From d71458d91963b56a02bc05d617344fd2871951dd Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 7 Sep 2020 16:09:48 +0200 Subject: BLI: add comparison operators for StringRef The semantic of those is the same as for std::string_view. --- source/blender/blenlib/BLI_string_ref.hh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh index be18848fbf4..8e3e3be99e2 100644 --- a/source/blender/blenlib/BLI_string_ref.hh +++ b/source/blender/blenlib/BLI_string_ref.hh @@ -404,6 +404,26 @@ inline bool operator!=(StringRef a, StringRef b) return !(a == b); } +inline bool operator<(StringRef a, StringRef b) +{ + return std::string_view(a) < std::string_view(b); +} + +inline bool operator>(StringRef a, StringRef b) +{ + return std::string_view(a) > std::string_view(b); +} + +inline bool operator<=(StringRef a, StringRef b) +{ + return std::string_view(a) <= std::string_view(b); +} + +inline bool operator>=(StringRef a, StringRef b) +{ + return std::string_view(a) >= std::string_view(b); +} + /** * Return true when the string starts with the given prefix. */ -- cgit v1.2.3 From 9681708c1cf12026095b3a8a52cd0b3fa046ba1f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 7 Sep 2020 16:14:58 +0200 Subject: Fix T80561: Crash when multi-mesh editing UVs with proportional editing Because of a `goto` we would free a variable before it was declared. Declare it before the `goto` and `NULL`-check the value before freeing. --- source/blender/editors/transform/transform_convert_mesh_uv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c index 632769c167e..92447c257da 100644 --- a/source/blender/editors/transform/transform_convert_mesh_uv.c +++ b/source/blender/editors/transform/transform_convert_mesh_uv.c @@ -322,6 +322,8 @@ void createTransUVs(bContext *C, TransInfo *t) } } + float *prop_dists = NULL; + /* Support other objects using PET to adjust these, unless connected is enabled. */ if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) { goto finally; @@ -349,8 +351,6 @@ void createTransUVs(bContext *C, TransInfo *t) td = tc->data; td2d = tc->data_2d; - float *prop_dists = NULL; - if (is_prop_connected) { prop_dists = MEM_callocN(em->bm->totloop * sizeof(float), "TransObPropDists(UV Editing)"); @@ -397,7 +397,7 @@ void createTransUVs(bContext *C, TransInfo *t) finally: if (is_prop_connected) { - MEM_freeN(prop_dists); + MEM_SAFE_FREE(prop_dists); } if (is_island_center) { BM_uv_element_map_free(elementmap); -- cgit v1.2.3 From 231d08cbb11277ebfe1c1700124ced9ef50229d8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Sep 2020 16:43:34 +0200 Subject: Multires: Fix memory leak when multires is at level 0 There is no SubdivCCG created in this case, meaning ownership of the Subdiv was not altered. --- source/blender/modifiers/intern/MOD_multires.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 7bdc1da33c2..03e7f0a235b 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -205,6 +205,13 @@ static Mesh *multires_as_ccg(MultiresModifierData *mmd, } BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd); result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh); + + /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share + * this pointer. Not sure if it's needed, but might have a second look + * on the ownership model here. */ + MultiresRuntimeData *runtime_data = mmd->modifier.runtime; + runtime_data->subdiv = NULL; + return result; } @@ -261,10 +268,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * sculpt_session->mpoly = NULL; sculpt_session->mloop = NULL; } - /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share - * this pointer. Not sure if it's needed, but might have a second look - * on the ownership model here. */ - runtime_data->subdiv = NULL; // BKE_subdiv_stats_print(&subdiv->stats); } else { -- cgit v1.2.3 From 179bd1ea7d4d1b31ce22ac1d5d0c0b32b843aa6f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Sep 2020 16:56:41 +0200 Subject: Fix T77763: Wrong highlight of active grab vertex The "Grab Active Vertex" in sculpt mode highlights the vertex and the neighbor vertices. This was working wrong in the case when mesh has multires modifier at sculpt level 0 and has shape keys. The issue was caused by the wrong crazy space calculation, which was ignoring subdivision level. This is an oversight from the initial implementation: the modifier has no effect if the subdivision level is 0. --- source/blender/modifiers/intern/MOD_multires.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 03e7f0a235b..9c7ab50cb61 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -296,7 +296,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } static void deformMatrices(ModifierData *md, - const ModifierEvalContext *UNUSED(ctx), + const ModifierEvalContext *ctx, Mesh *mesh, float (*vertex_cos)[3], float (*deform_matrices)[3][3], @@ -312,11 +312,19 @@ static void deformMatrices(ModifierData *md, (void)deform_matrices; MultiresModifierData *mmd = (MultiresModifierData *)md; + SubdivSettings subdiv_settings; BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); if (subdiv_settings.level == 0) { return; } + + SubdivToCCGSettings ccg_settings; + multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh); + if (ccg_settings.resolution < 3) { + return; + } + BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh); MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd); Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh); -- cgit v1.2.3 From 0c4b732ef2cd5d3b4d6d7dbaa27801d1bfff04ae Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Sun, 6 Sep 2020 18:56:40 +0200 Subject: Fix T78225: Vertex Colors not showing in edit mode This should be using the mesh_cd_ldata_get_from_mesh function in order to get ldata from BMesh in edit mode. Reviewed By: sergey Maniphest Tasks: T78225 Differential Revision: https://developer.blender.org/D8818 --- source/blender/draw/intern/draw_cache_impl_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index e8a712b6881..c7ba707d403 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -169,7 +169,7 @@ static void mesh_cd_calc_active_vcol_layer(const Mesh *me, DRW_MeshCDMask *cd_us static void mesh_cd_calc_active_mloopcol_layer(const Mesh *me, DRW_MeshCDMask *cd_used) { const Mesh *me_final = editmesh_final_or_this(me); - const CustomData *cd_ldata = &me_final->ldata; + const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL); if (layer != -1) { -- cgit v1.2.3 From bbbfd7130ae36b9ba1652b919ef6ae426107acd8 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Sun, 6 Sep 2020 19:38:37 +0200 Subject: Fix Boundary Brush not working with partially hidden meshes Now when a mesh is partially hidden using Face Sets, the open boundary the hidden geometry produces is also detected by the brush. Reviewed By: sergey Differential Revision: https://developer.blender.org/D8819 --- .../blender/editors/sculpt_paint/sculpt_boundary.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 5e01e034715..3051413a405 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -74,6 +74,10 @@ static bool boundary_initial_vertex_floodfill_cb( { BoundaryInitialVertexFloodFillData *data = userdata; + if (!SCULPT_vertex_visible_get(ss, to_v)) { + return false; + } + if (!is_duplicate) { data->floodfill_steps[to_v] = data->floodfill_steps[from_v] + 1; } @@ -174,13 +178,19 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss, const int initial_vertex) { + if (!SCULPT_vertex_visible_get(ss, initial_vertex)) { + return false; + } + int neighbor_count = 0; int boundary_vertex_count = 0; SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, initial_vertex, ni) { - neighbor_count++; - if (SCULPT_vertex_is_boundary(ss, ni.index)) { - boundary_vertex_count++; + if (SCULPT_vertex_visible_get(ss, ni.index)) { + neighbor_count++; + if (SCULPT_vertex_is_boundary(ss, ni.index)) { + boundary_vertex_count++; + } } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -349,7 +359,9 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptVertexNeighborIter ni; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { - if (boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) { + const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index); + if (is_visible && + 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; -- cgit v1.2.3 From 1dc11d15a60b1fdb21f72c9bd39ba27e3acdb80f Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Mon, 7 Sep 2020 17:24:52 +0200 Subject: Fix T79914: Grab active vertex using wrong coordinates This was introduced in the first commit of the cloth brush. In order to support the cloth brush deformations with subsurf modifiers, the sculpt API was changed to return the deformed coordinates from the PBVH instead of the mesh coordinates. When using grab active vertex and rendering the original mesh wireframe it should render the undeformed mesh coordinates when available. Reviewed By: sergey Maniphest Tasks: T79914 Differential Revision: https://developer.blender.org/D8630 --- source/blender/editors/sculpt_paint/paint_cursor.c | 12 ++++++++++-- source/blender/editors/sculpt_paint/sculpt.c | 13 +++++++++++-- source/blender/editors/sculpt_paint/sculpt_intern.h | 3 +++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 08733a26187..f4d7869e40a 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1154,7 +1154,8 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, if (ss->preview_vert_index_count > 0) { immBegin(GPU_PRIM_LINES, ss->preview_vert_index_count); for (int i = 0; i < ss->preview_vert_index_count; i++) { - immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss->preview_vert_index_list[i])); + immVertex3fv(gpuattr, + SCULPT_vertex_co_for_grab_active_get(ss, ss->preview_vert_index_list[i])); } immEnd(); } @@ -1572,7 +1573,14 @@ static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext * /* Cursor location symmetry points. */ - const float *active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss); + const float *active_vertex_co; + if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) { + active_vertex_co = SCULPT_vertex_co_for_grab_active_get( + pcontext->ss, SCULPT_active_vertex_get(pcontext->ss)); + } + else { + active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss); + } if (len_v3v3(active_vertex_co, pcontext->location) < pcontext->radius) { immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha); cursor_draw_point_with_symmetry(pcontext->pos, diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index f2eb1359af7..c8ee4a75b1d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -204,6 +204,14 @@ const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index) return SCULPT_vertex_co_get(ss, index); } +const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index) +{ + if (ss->mvert) { + return ss->mvert[index].co; + } + return SCULPT_vertex_co_get(ss, index); +} + void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]) { switch (BKE_pbvh_type(ss->pbvh)) { @@ -6694,7 +6702,8 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) { - copy_v3_v3(cache->orig_grab_location, SCULPT_active_vertex_co_get(ss)); + copy_v3_v3(cache->orig_grab_location, + SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss))); } else { copy_v3_v3(cache->orig_grab_location, cache->true_location); @@ -8366,7 +8375,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float totpoints++; if (!BLI_BITMAP_TEST(visited_vertices, to_v)) { BLI_BITMAP_ENABLE(visited_vertices, to_v); - const float *co = SCULPT_vertex_co_get(ss, to_v); + const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v); if (len_squared_v3v3(brush_co, co) < radius * radius) { BLI_gsqueue_push(not_visited_vertices, &to_v); } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index d7497a6cd4c..9f28bd59d87 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -100,6 +100,9 @@ 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]); +/* Coordinates used for manipulating the base mesh when Grab Active Vertex is enabled. */ +const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index); + /* 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]); -- cgit v1.2.3 From 675c9644420eba96751e1cadedd2656a8bc39191 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Sat, 5 Sep 2020 20:06:27 +0200 Subject: Sculpt: Sculpt Trimming gestures tools This implements Box Trim as a boolean based trimming too gesture in sculpt mode. This is the intended way to remove parts of the sculpt instead of using box mask and mask slice. It also creates new face sets for the new faces created after the boolean operation. Reviewed By: sergey Differential Revision: https://developer.blender.org/D8766 --- .../keyconfig/keymap_data/blender_default.py | 23 +- .../startup/bl_ui/space_toolsystem_toolbar.py | 24 ++ source/blender/editors/sculpt_paint/paint_mask.c | 477 +++++++++++++++++++++ source/blender/editors/sculpt_paint/sculpt.c | 2 + .../blender/editors/sculpt_paint/sculpt_intern.h | 3 + source/blender/windowmanager/intern/wm_operators.c | 1 + 6 files changed, 529 insertions(+), 1 deletion(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index acb2e731e12..53b45ed6c90 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -6332,7 +6332,6 @@ def km_3d_view_tool_sculpt_box_face_set(params): ]}, ) - def km_3d_view_tool_sculpt_lasso_face_set(params): return ( "3D View Tool: Sculpt, Lasso Face Set", @@ -6342,6 +6341,26 @@ def km_3d_view_tool_sculpt_lasso_face_set(params): None), ]}, ) + +def km_3d_view_tool_sculpt_box_trim(params): + return ( + "3D View Tool: Sculpt, Box Trim", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("sculpt.trim_box_gesture", {"type": params.tool_tweak, "value": 'ANY'}, + None), + ]}, + ) + +def km_3d_view_tool_sculpt_lasso_trim(params): + return ( + "3D View Tool: Sculpt, Lasso Trim", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("sculpt.trim_lasso_gesture", {"type": params.tool_tweak, "value": 'ANY'}, + None), + ]}, + ) def km_3d_view_tool_sculpt_mesh_filter(params): return ( @@ -6938,6 +6957,8 @@ def generate_keymaps(params=None): km_3d_view_tool_sculpt_lasso_mask(params), km_3d_view_tool_sculpt_box_face_set(params), km_3d_view_tool_sculpt_lasso_face_set(params), + km_3d_view_tool_sculpt_box_trim(params), + km_3d_view_tool_sculpt_lasso_trim(params), km_3d_view_tool_sculpt_mesh_filter(params), km_3d_view_tool_sculpt_cloth_filter(params), km_3d_view_tool_sculpt_color_filter(params), diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index c17b981a6b8..ab7ac007257 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1284,6 +1284,26 @@ class _defs_sculpt: draw_settings=draw_settings, ) + @ToolDef.from_fn + def trim_box(): + return dict( + idname="builtin.box_trim", + label="Box Trim", + icon="ops.sculpt.box_trim", + widget=None, + keymap=(), + ) + + @ToolDef.from_fn + def trim_lasso(): + return dict( + idname="builtin.lasso_trim", + label="Lasso Trim", + icon="ops.sculpt.lasso_trim", + widget=None, + keymap=(), + ) + @ToolDef.from_fn def mesh_filter(): @@ -2632,6 +2652,10 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_sculpt.face_set_lasso, ), _defs_sculpt.hide_border, + ( + _defs_sculpt.trim_box, + _defs_sculpt.trim_lasso, + ), None, _defs_sculpt.mesh_filter, _defs_sculpt.cloth_filter, diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index fd17793b6de..70f8ef89e9a 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -23,14 +23,18 @@ #include "MEM_guardedalloc.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_vec_types.h" +#include "BLI_alloca.h" #include "BLI_bitmap_draw_2d.h" #include "BLI_lasso_2d.h" #include "BLI_math_geom.h" #include "BLI_math_matrix.h" +#include "BLI_polyfill_2d.h" #include "BLI_rect.h" #include "BLI_task.h" #include "BLI_utildefines.h" @@ -56,6 +60,8 @@ #include "ED_view3d.h" #include "bmesh.h" +#include "bmesh_tools.h" +#include "tools/bmesh_boolean.h" #include "paint_intern.h" @@ -256,10 +262,18 @@ typedef struct SculptGestureContext { struct SculptGestureOperation *operation; + /* Gesture data. */ + /* Screen space points that represent the gesture shape. */ + float (*gesture_points)[2]; + int tot_gesture_points; + /* View parameters. */ float true_view_normal[3]; float view_normal[3]; + float true_view_origin[3]; + float view_origin[3]; + float true_clip_planes[4][4]; float clip_planes[4][4]; @@ -319,6 +333,9 @@ static void sculpt_gesture_context_init_common(bContext *C, copy_m3_m4(mat, ob->imat); mul_m3_v3(mat, view_dir); normalize_v3_v3(sgcontext->true_view_normal, view_dir); + + /* View Origin. */ + copy_v3_v3(sgcontext->true_view_origin, sgcontext->vc.rv3d->viewinv[3]); } static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) @@ -370,6 +387,14 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera sgcontext->vc.region, sgcontext->vc.obact, &sgcontext->lasso.boundbox); + + sgcontext->gesture_points = MEM_malloc_arrayN(mcoords_len, sizeof(float[2]), "trim points"); + sgcontext->tot_gesture_points = mcoords_len; + for (int i = 0; i < mcoords_len; i++) { + sgcontext->gesture_points[i][0] = mcoords[i][0]; + sgcontext->gesture_points[i][1] = mcoords[i][1]; + } + MEM_freeN((void *)mcoords); return sgcontext; @@ -390,12 +415,27 @@ static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperato ED_view3d_clipping_calc( &bb, sgcontext->true_clip_planes, sgcontext->vc.region, sgcontext->vc.obact, &rect); + sgcontext->gesture_points = MEM_calloc_arrayN(4, sizeof(float[2]), "trim points"); + sgcontext->tot_gesture_points = 4; + + sgcontext->gesture_points[0][0] = rect.xmax; + sgcontext->gesture_points[0][1] = rect.ymax; + + sgcontext->gesture_points[1][0] = rect.xmax; + sgcontext->gesture_points[1][1] = rect.ymin; + + sgcontext->gesture_points[2][0] = rect.xmin; + sgcontext->gesture_points[2][1] = rect.ymin; + + sgcontext->gesture_points[3][0] = rect.xmin; + sgcontext->gesture_points[3][1] = rect.ymax; return sgcontext; } static void sculpt_gesture_context_free(SculptGestureContext *sgcontext) { MEM_SAFE_FREE(sgcontext->lasso.mask_px); + MEM_SAFE_FREE(sgcontext->gesture_points); MEM_SAFE_FREE(sgcontext->operation); MEM_SAFE_FREE(sgcontext->nodes); MEM_SAFE_FREE(sgcontext); @@ -434,6 +474,7 @@ static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontex } negate_m4(sgcontext->clip_planes); flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass); + flip_v3_v3(sgcontext->view_origin, sgcontext->true_view_origin, symmpass); } static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext) @@ -699,6 +740,361 @@ static void paint_mask_gesture_operator_properties(wmOperatorType *ot) 1.0f); } +/* Trim Gesture Operation. */ + +typedef enum eSculptTrimOperationType { + SCULPT_GESTURE_TRIM_INTERSECT, + SCULPT_GESTURE_TRIM_DIFFERENCE, +} eSculptTrimOperationType; + +static EnumPropertyItem prop_trim_operation_types[] = { + {SCULPT_GESTURE_TRIM_INTERSECT, "INTERSECT", 0, "Intersect", ""}, + {SCULPT_GESTURE_TRIM_DIFFERENCE, "DIFFERENCE", 0, "Difference", ""}, + {0, NULL, 0, NULL, NULL}, +}; + +typedef struct SculptGestureTrimOperation { + SculptGestureOperation op; + + Mesh *mesh; + float (*true_mesh_co)[3]; + + float depth_front; + float depth_back; + + eSculptTrimOperationType mode; +} SculptGestureTrimOperation; + +static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) +{ + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + Mesh *trim_mesh = trim_operation->mesh; + BKE_mesh_calc_normals(trim_mesh); + + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(trim_mesh); + BMesh *bm; + bm = BM_mesh_create(&allocsize, + &((struct BMeshCreateParams){ + .use_toolflags = true, + })); + + BM_mesh_bm_from_me(bm, + trim_mesh, + (&(struct BMeshFromMeshParams){ + .calc_face_normal = true, + })); + BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, false); + BMO_op_callf(bm, + (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), + "recalc_face_normals faces=%hf", + BM_ELEM_TAG); + BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false); + Mesh *result = BKE_mesh_from_bmesh_nomain(bm, + (&(struct BMeshToMeshParams){ + .calc_object_remap = false, + }), + trim_mesh); + BM_mesh_free(bm); + BKE_mesh_free(trim_mesh); + trim_operation->mesh = result; +} + +static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext) +{ + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + + SculptSession *ss = sgcontext->ss; + const int totvert = SCULPT_vertex_count_get(ss); + + float view_plane[4]; + plane_from_point_normal_v3(view_plane, sgcontext->true_view_origin, sgcontext->true_view_normal); + + trim_operation->depth_front = FLT_MAX; + trim_operation->depth_back = -FLT_MAX; + + for (int i = 0; i < totvert; i++) { + const float *vco = SCULPT_vertex_co_get(ss, i); + const float dist = dist_signed_to_plane_v3(vco, view_plane); + trim_operation->depth_front = min_ff(dist, trim_operation->depth_front); + trim_operation->depth_back = max_ff(dist, trim_operation->depth_back); + } +} + +static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontext) +{ + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + ViewContext *vc = &sgcontext->vc; + ARegion *region = vc->region; + + const int tot_screen_points = sgcontext->tot_gesture_points; + float(*screen_points)[2] = sgcontext->gesture_points; + + const int trim_totverts = tot_screen_points * 2; + const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points); + trim_operation->mesh = BKE_mesh_new_nomain( + trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys); + trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, 3 * sizeof(float), "mesh orco"); + + const float depth_front = trim_operation->depth_front - 0.1f; + const float depth_back = trim_operation->depth_back + 0.1f; + + float *view_origin = sgcontext->true_view_origin; + float *view_normal = sgcontext->true_view_normal; + + /* Write vertices coordinates for the front face. */ + + float depth_point[3]; + madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_front); + for (int i = 0; i < tot_screen_points; i++) { + float new_point[3]; + ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + copy_v3_v3(trim_operation->mesh->mvert[i].co, new_point); + copy_v3_v3(trim_operation->true_mesh_co[i], new_point); + } + + /* Write vertices coordinates for the back face. */ + madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_back); + for (int i = 0; i < tot_screen_points; i++) { + float new_point[3]; + ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + copy_v3_v3(trim_operation->mesh->mvert[i + tot_screen_points].co, new_point); + copy_v3_v3(trim_operation->true_mesh_co[i + tot_screen_points], new_point); + } + + /* Get the triangulation for the front/back poly. */ + const int tot_tris_face = tot_screen_points - 2; + uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, 3 * sizeof(uint), "tris"); + BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris); + + /* Write the front face triangle indices. */ + MPoly *mp = trim_operation->mesh->mpoly; + MLoop *ml = trim_operation->mesh->mloop; + for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) { + mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->totloop = 3; + ml[0].v = r_tris[i][0]; + ml[1].v = r_tris[i][1]; + ml[2].v = r_tris[i][2]; + } + + /* Write the back face triangle indices. */ + for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) { + mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->totloop = 3; + ml[0].v = r_tris[i][0] + tot_screen_points; + ml[1].v = r_tris[i][1] + tot_screen_points; + ml[2].v = r_tris[i][2] + tot_screen_points; + } + + MEM_freeN(r_tris); + + /* Write the indices for the lateral triangles. */ + for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) { + mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->totloop = 3; + int current_index = i; + int next_index = current_index + 1; + if (next_index >= tot_screen_points) { + next_index = 0; + } + ml[0].v = next_index + tot_screen_points; + ml[1].v = next_index; + ml[2].v = current_index; + } + + for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) { + mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->totloop = 3; + int current_index = i; + int next_index = current_index + 1; + if (next_index >= tot_screen_points) { + next_index = 0; + } + ml[0].v = current_index; + ml[1].v = current_index + tot_screen_points; + ml[2].v = next_index + tot_screen_points; + } + + BKE_mesh_calc_edges(trim_operation->mesh, false, false); + sculpt_gesture_trim_normals_update(sgcontext); +} + +static void sculpt_gesture_trim_geometry_free(SculptGestureContext *sgcontext) +{ + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + BKE_mesh_free(trim_operation->mesh); + MEM_freeN(trim_operation->true_mesh_co); +} + +static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data)) +{ + return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 1 : 0; +} + +static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) +{ + + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + Object *object = sgcontext->vc.obact; + Mesh *sculpt_mesh = BKE_mesh_from_object(sgcontext->vc.obact); + Mesh *trim_mesh = trim_operation->mesh; + + BMesh *bm; + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, trim_mesh); + bm = BM_mesh_create(&allocsize, + &((struct BMeshCreateParams){ + .use_toolflags = false, + })); + + BM_mesh_bm_from_me(bm, + trim_mesh, + &((struct BMeshFromMeshParams){ + .calc_face_normal = true, + })); + + BM_mesh_bm_from_me(bm, + sculpt_mesh, + &((struct BMeshFromMeshParams){ + .calc_face_normal = true, + })); + + const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); + int tottri; + BMLoop *(*looptris)[3]; + looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__); + BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri); + + BMIter iter; + int i; + const int i_verts_end = trim_mesh->totvert; + const int i_faces_end = trim_mesh->totpoly; + + float imat[4][4]; + float omat[4][4]; + + invert_m4_m4(imat, object->obmat); + mul_m4_m4m4(omat, imat, object->obmat); + + BMVert *eve; + i = 0; + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + mul_m4_v3(omat, eve->co); + if (++i == i_verts_end) { + break; + } + } + + /* We need face normals because of 'BM_face_split_edgenet' + * we could calculate on the fly too (before calling split). */ + float nmat[3][3]; + copy_m3_m4(nmat, omat); + invert_m3(nmat); + + const short ob_src_totcol = trim_mesh->totcol; + short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1); + + BMFace *efa; + i = 0; + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + mul_transposed_m3_v3(nmat, efa->no); + normalize_v3(efa->no); + + /* Temp tag to test which side split faces are from. */ + BM_elem_flag_enable(efa, BM_ELEM_DRAW); + + /* Remap material. */ + if (efa->mat_nr < ob_src_totcol) { + efa->mat_nr = material_remap[efa->mat_nr]; + } + + if (++i == i_faces_end) { + break; + } + } + + int boolean_mode; + switch (trim_operation->mode) { + case SCULPT_GESTURE_TRIM_INTERSECT: + boolean_mode = eBooleanModifierOp_Intersect; + break; + case SCULPT_GESTURE_TRIM_DIFFERENCE: + boolean_mode = eBooleanModifierOp_Difference; + break; + } + + BM_mesh_boolean(bm, looptris, tottri, bm_face_isect_pair, NULL, false, boolean_mode); + + Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, sculpt_mesh); + BM_mesh_free(bm); + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + + BKE_mesh_nomain_to_mesh(result, sculpt_mesh, sgcontext->vc.obact, &CD_MASK_MESH, true); + BKE_mesh_free(result); +} + +static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext) +{ + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + sculpt_gesture_trim_calculate_depth(sgcontext); + sculpt_gesture_trim_geometry_generate(sgcontext); + BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false); + SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_GEOMETRY); +} + +static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), + SculptGestureContext *sgcontext) +{ + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + Mesh *trim_mesh = trim_operation->mesh; + for (int i = 0; i < trim_mesh->totvert; i++) { + flip_v3_v3(trim_mesh->mvert[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass); + } + sculpt_gesture_trim_normals_update(sgcontext); + sculpt_gesture_apply_trim(sgcontext); +} + +static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *sgcontext) +{ + Object *object = sgcontext->vc.obact; + SculptSession *ss = object->sculpt; + ss->face_sets = CustomData_get_layer(&((Mesh *)object->data)->pdata, CD_SCULPT_FACE_SETS); + if (ss->face_sets) { + /* Assign a new Face Set ID to the new faces created by the trim operation. */ + const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data); + ED_sculpt_face_sets_initialize_none_to_id(object->data, next_face_set_id); + } + + sculpt_gesture_trim_geometry_free(sgcontext); + + SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_GEOMETRY); + BKE_mesh_batch_cache_dirty_tag(sgcontext->vc.obact->data, BKE_MESH_BATCH_DIRTY_ALL); + DEG_id_tag_update(&sgcontext->vc.obact->id, ID_RECALC_GEOMETRY); +} + +static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, wmOperator *op) +{ + sgcontext->operation = MEM_callocN(sizeof(SculptGestureTrimOperation), "Trim Operation"); + + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + + trim_operation->op.sculpt_gesture_begin = sculpt_gesture_trim_begin; + trim_operation->op.sculpt_gesture_apply_for_symmetry_pass = + sculpt_gesture_trim_apply_for_symmetry_pass; + trim_operation->op.sculpt_gesture_end = sculpt_gesture_trim_end; + + trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode"); +} + +static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) +{ + RNA_def_enum(ot->srna, + "trim_mode", + prop_trim_operation_types, + SCULPT_GESTURE_TRIM_DIFFERENCE, + "Trim Mode", + NULL); +} + static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op) { SculptGestureContext *sgcontext = sculpt_gesture_init_from_box(C, op); @@ -747,6 +1143,45 @@ static int face_set_gesture_lasso_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int sculpt_trim_gesture_box_exec(bContext *C, wmOperator *op) +{ + Object *object = CTX_data_active_object(C); + SculptSession *ss = object->sculpt; + if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) { + /* Not supported in Multires and Dyntopo. */ + return OPERATOR_CANCELLED; + } + + SculptGestureContext *sgcontext = sculpt_gesture_init_from_box(C, op); + if (!sgcontext) { + return OPERATOR_CANCELLED; + } + + sculpt_gesture_init_trim_properties(sgcontext, op); + sculpt_gesture_apply(C, sgcontext); + sculpt_gesture_context_free(sgcontext); + return OPERATOR_FINISHED; +} + +static int sculpt_trim_gesture_lasso_exec(bContext *C, wmOperator *op) +{ + Object *object = CTX_data_active_object(C); + SculptSession *ss = object->sculpt; + if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) { + /* Not supported in Multires and Dyntopo. */ + return OPERATOR_CANCELLED; + } + + SculptGestureContext *sgcontext = sculpt_gesture_init_from_lasso(C, op); + if (!sgcontext) { + return OPERATOR_CANCELLED; + } + sculpt_gesture_init_trim_properties(sgcontext, op); + sculpt_gesture_apply(C, sgcontext); + sculpt_gesture_context_free(sgcontext); + return OPERATOR_FINISHED; +} + void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) { ot->name = "Mask Lasso Gesture"; @@ -826,3 +1261,45 @@ void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot) WM_operator_properties_border(ot); sculpt_gesture_operator_properties(ot); } + +void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot) +{ + ot->name = "Trim Lasso Gesture"; + ot->idname = "SCULPT_OT_trim_lasso_gesture"; + ot->description = "Trims the mesh within the lasso as you move the brush"; + + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = sculpt_trim_gesture_lasso_exec; + + ot->poll = SCULPT_mode_poll; + + ot->flag = OPTYPE_REGISTER; + + /* Properties. */ + WM_operator_properties_gesture_lasso(ot); + sculpt_gesture_operator_properties(ot); + + sculpt_trim_gesture_operator_properties(ot); +} + +void SCULPT_OT_trim_box_gesture(wmOperatorType *ot) +{ + ot->name = "Trim Box Gesture"; + ot->idname = "SCULPT_OT_trim_box_gesture"; + ot->description = "Trims the mesh within the box as you move the brush"; + + ot->invoke = WM_gesture_box_invoke; + ot->modal = WM_gesture_box_modal; + ot->exec = sculpt_trim_gesture_box_exec; + + ot->poll = SCULPT_mode_poll; + + ot->flag = OPTYPE_REGISTER; + + /* Properties. */ + WM_operator_properties_border(ot); + sculpt_gesture_operator_properties(ot); + + sculpt_trim_gesture_operator_properties(ot); +} diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c8ee4a75b1d..5070709cb6d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -9164,6 +9164,8 @@ void ED_operatortypes_sculpt(void) WM_operatortype_append(SCULPT_OT_face_sets_edit); WM_operatortype_append(SCULPT_OT_face_set_lasso_gesture); WM_operatortype_append(SCULPT_OT_face_set_box_gesture); + WM_operatortype_append(SCULPT_OT_trim_box_gesture); + WM_operatortype_append(SCULPT_OT_trim_lasso_gesture); WM_operatortype_append(SCULPT_OT_sample_color); WM_operatortype_append(SCULPT_OT_loop_to_vertex_colors); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 9f28bd59d87..620033422b2 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1057,6 +1057,9 @@ bool SCULPT_get_redraw_rect(struct ARegion *region, void SCULPT_OT_face_set_lasso_gesture(struct wmOperatorType *ot); void SCULPT_OT_face_set_box_gesture(struct wmOperatorType *ot); +void SCULPT_OT_trim_lasso_gesture(struct wmOperatorType *ot); +void SCULPT_OT_trim_box_gesture(struct wmOperatorType *ot); + /* Face Sets. */ void SCULPT_OT_face_sets_randomize_colors(struct wmOperatorType *ot); void SCULPT_OT_face_sets_change_visibility(struct wmOperatorType *ot); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 98beae69672..ffe2ffac3a2 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3903,6 +3903,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "MASK_OT_select_box"); WM_modalkeymap_assign(keymap, "PAINT_OT_mask_box_gesture"); WM_modalkeymap_assign(keymap, "SCULPT_OT_face_set_box_gesture"); + WM_modalkeymap_assign(keymap, "SCULPT_OT_trim_box_gesture"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); -- cgit v1.2.3 From 1291c7add619d5e5f3cf4a6ad2c14827ce74afb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 7 Sep 2020 16:30:34 +0200 Subject: Cleanup: Refactor object.parent_set operator Refactor the operator exec function into a few smaller functions. The exec function was mixing up vertex-parent and non-vertex-parent code, including incorrect comments. No functional changes. --- source/blender/editors/object/object_relations.c | 120 ++++++++++++++++------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index d9196425098..fd4a7ae1d4a 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -954,58 +954,104 @@ static void parent_set_vert_find(KDTree_3d *tree, Object *child, int vert_par[3] } } -static int parent_set_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - Object *par = ED_object_active_context(C); - int partype = RNA_enum_get(op->ptr, "type"); - const bool xmirror = RNA_boolean_get(op->ptr, "xmirror"); - const bool keep_transform = RNA_boolean_get(op->ptr, "keep_transform"); - bool ok = true; - - /* vertex parent (kdtree) */ - const bool is_vert_par = ELEM(partype, PAR_VERTEX, PAR_VERTEX_TRI); - const bool is_tri = partype == PAR_VERTEX_TRI; - int tree_tot; - struct KDTree_3d *tree = NULL; - int vert_par[3] = {0, 0, 0}; - const int *vert_par_p = is_vert_par ? vert_par : NULL; - - if (is_vert_par) { - tree = BKE_object_as_kdtree(par, &tree_tot); - BLI_assert(tree != NULL); +struct ParentingContext { + ReportList *reports; + Scene *scene; + Object *par; + int partype; + bool is_vertex_tri; + bool xmirror; + bool keep_transform; +}; - if (tree_tot < (is_tri ? 3 : 1)) { - BKE_report(op->reports, RPT_ERROR, "Not enough vertices for vertex-parent"); - ok = false; +static bool parent_set_nonvertex_parent(bContext *C, struct ParentingContext *parenting_context) +{ + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + if (!ED_object_parent_set(parenting_context->reports, + C, + parenting_context->scene, + ob, + parenting_context->par, + parenting_context->partype, + parenting_context->xmirror, + parenting_context->keep_transform, + NULL)) { + return false; } } + CTX_DATA_END; - if (ok) { - /* Non vertex-parent */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (is_vert_par) { - parent_set_vert_find(tree, ob, vert_par, is_tri); - } + return true; +} - if (!ED_object_parent_set( - op->reports, C, scene, ob, par, partype, xmirror, keep_transform, vert_par_p)) { - ok = false; - break; - } +static bool parent_set_vertex_parent_with_kdtree(bContext *C, + struct ParentingContext *parenting_context, + struct KDTree_3d *tree) +{ + int vert_par[3] = {0, 0, 0}; + + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + parent_set_vert_find(tree, ob, vert_par, parenting_context->is_vertex_tri); + if (!ED_object_parent_set(parenting_context->reports, + C, + parenting_context->scene, + ob, + parenting_context->par, + parenting_context->partype, + parenting_context->xmirror, + parenting_context->keep_transform, + vert_par)) { + return false; } - CTX_DATA_END; } + CTX_DATA_END; + return true; +} + +static bool parent_set_vertex_parent(bContext *C, struct ParentingContext *parenting_context) +{ + struct KDTree_3d *tree = NULL; + int tree_tot; + + tree = BKE_object_as_kdtree(parenting_context->par, &tree_tot); + BLI_assert(tree != NULL); - if (is_vert_par) { + if (tree_tot < (parenting_context->is_vertex_tri ? 3 : 1)) { + BKE_report(parenting_context->reports, RPT_ERROR, "Not enough vertices for vertex-parent"); BLI_kdtree_3d_free(tree); + return false; } + const bool ok = parent_set_vertex_parent_with_kdtree(C, parenting_context, tree); + BLI_kdtree_3d_free(tree); + return ok; +} + +static int parent_set_exec(bContext *C, wmOperator *op) +{ + const int partype = RNA_enum_get(op->ptr, "type"); + struct ParentingContext parenting_context = { + .reports = op->reports, + .scene = CTX_data_scene(C), + .par = ED_object_active_context(C), + .partype = partype, + .is_vertex_tri = partype == PAR_VERTEX_TRI, + .xmirror = RNA_boolean_get(op->ptr, "xmirror"), + .keep_transform = RNA_boolean_get(op->ptr, "keep_transform"), + }; + + bool ok; + if (ELEM(parenting_context.partype, PAR_VERTEX, PAR_VERTEX_TRI)) { + ok = parent_set_vertex_parent(C, &parenting_context); + } + else { + ok = parent_set_nonvertex_parent(C, &parenting_context); + } if (!ok) { return OPERATOR_CANCELLED; } + Main *bmain = CTX_data_main(C); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); -- cgit v1.2.3 From 53ca638f2b738af644661bd4fabcf7e3fdf6e73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 7 Sep 2020 18:09:09 +0200 Subject: Cleanup: Clang Tidy, readability-inconsistent-declaration-parameter-name No functional changes. --- source/blender/python/intern/bpy_rna.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index cc981c7c2e1..0980d9df762 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -219,10 +219,10 @@ static void value_id_set(void *id) } static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash); -static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref) +static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref) { /* Important to search backwards. */ - GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL); + GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_pair, NULL); if (BLI_ghash_len(weakinfo_hash) > 1) { BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL); -- cgit v1.2.3 From 9cac181fbead28c0bf963bf2b9f82fddf3c2b7df Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Mon, 7 Sep 2020 18:11:56 +0200 Subject: Audaspace: port changes from upstream. Adds possibility to report progress during audio mixdown. --- extern/audaspace/bindings/C/AUD_Special.cpp | 8 ++++---- extern/audaspace/bindings/C/AUD_Special.h | 10 ++++++++-- extern/audaspace/include/file/FileWriter.h | 4 ++-- extern/audaspace/src/file/FileWriter.cpp | 20 ++++++++++++++++++-- source/blender/editors/sound/sound_ops.c | 8 ++++++-- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/extern/audaspace/bindings/C/AUD_Special.cpp b/extern/audaspace/bindings/C/AUD_Special.cpp index c7155276a30..a83465620ab 100644 --- a/extern/audaspace/bindings/C/AUD_Special.cpp +++ b/extern/audaspace/bindings/C/AUD_Special.cpp @@ -270,7 +270,7 @@ AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int sampl return length; } -AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) +AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate, void(*callback)(float, void*), void* data) { try { @@ -280,7 +280,7 @@ AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned i std::shared_ptr reader = f->createQualityReader(); reader->seek(start); std::shared_ptr writer = FileWriter::createWriter(filename, convCToDSpec(specs), static_cast(format), static_cast(codec), bitrate); - FileWriter::writeReader(reader, writer, length, buffersize); + FileWriter::writeReader(reader, writer, length, buffersize, callback, data); return nullptr; } @@ -290,7 +290,7 @@ AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned i } } -AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) +AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate, void(*callback)(float, void*), void* data) { try { @@ -326,7 +326,7 @@ AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start std::shared_ptr reader = f->createQualityReader(); reader->seek(start); - FileWriter::writeReader(reader, writers, length, buffersize); + FileWriter::writeReader(reader, writers, length, buffersize, callback, data); return nullptr; } diff --git a/extern/audaspace/bindings/C/AUD_Special.h b/extern/audaspace/bindings/C/AUD_Special.h index 9faf9e4ee74..ce51fa2e04e 100644 --- a/extern/audaspace/bindings/C/AUD_Special.h +++ b/extern/audaspace/bindings/C/AUD_Special.h @@ -68,12 +68,15 @@ extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, in * \param format The file's container format. * \param codec The codec used for encoding the audio data. * \param bitrate The bitrate for encoding. + * \param callback A callback function that is called periodically during mixdown, reporting progress if length > 0. Can be NULL. + * \param data Pass through parameter that is passed to the callback. * \return An error message or NULL in case of success. */ extern AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, - AUD_Codec codec, unsigned int bitrate); + AUD_Codec codec, unsigned int bitrate, + void(*callback)(float, void*), void* data); /** * Mixes a sound down into multiple files. @@ -86,12 +89,15 @@ extern AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, uns * \param format The file's container format. * \param codec The codec used for encoding the audio data. * \param bitrate The bitrate for encoding. + * \param callback A callback function that is called periodically during mixdown, reporting progress if length > 0. Can be NULL. + * \param data Pass through parameter that is passed to the callback. * \return An error message or NULL in case of success. */ extern AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, - AUD_Codec codec, unsigned int bitrate); + AUD_Codec codec, unsigned int bitrate, + void(*callback)(float, void*), void* data); /** * Opens a read device and prepares it for mixdown of the sound scene. diff --git a/extern/audaspace/include/file/FileWriter.h b/extern/audaspace/include/file/FileWriter.h index dac842f2a8f..13619d4de71 100644 --- a/extern/audaspace/include/file/FileWriter.h +++ b/extern/audaspace/include/file/FileWriter.h @@ -63,7 +63,7 @@ public: * \param length How many samples should be transferred. * \param buffersize How many samples should be transferred at once. */ - static void writeReader(std::shared_ptr reader, std::shared_ptr writer, unsigned int length, unsigned int buffersize); + static void writeReader(std::shared_ptr reader, std::shared_ptr writer, unsigned int length, unsigned int buffersize, void(*callback)(float, void*) = nullptr, void* data = nullptr); /** * Writes a reader to several writers. @@ -72,7 +72,7 @@ public: * \param length How many samples should be transferred. * \param buffersize How many samples should be transferred at once. */ - static void writeReader(std::shared_ptr reader, std::vector >& writers, unsigned int length, unsigned int buffersize); + static void writeReader(std::shared_ptr reader, std::vector >& writers, unsigned int length, unsigned int buffersize, void(*callback)(float, void*) = nullptr, void* data = nullptr); }; AUD_NAMESPACE_END diff --git a/extern/audaspace/src/file/FileWriter.cpp b/extern/audaspace/src/file/FileWriter.cpp index a6bb0f0049a..b28bbc5329d 100644 --- a/extern/audaspace/src/file/FileWriter.cpp +++ b/extern/audaspace/src/file/FileWriter.cpp @@ -27,7 +27,7 @@ std::shared_ptr FileWriter::createWriter(std::string filename,DeviceSpe return FileManager::createWriter(filename, specs, format, codec, bitrate); } -void FileWriter::writeReader(std::shared_ptr reader, std::shared_ptr writer, unsigned int length, unsigned int buffersize) +void FileWriter::writeReader(std::shared_ptr reader, std::shared_ptr writer, unsigned int length, unsigned int buffersize, void(*callback)(float, void*), void* data) { Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs())); sample_t* buf = buffer.getBuffer(); @@ -53,10 +53,18 @@ void FileWriter::writeReader(std::shared_ptr reader, std::shared_ptrwrite(len, buf); + + if(callback) + { + float progress = -1; + if(length > 0) + progress = pos / float(length); + callback(progress, data); + } } } -void FileWriter::writeReader(std::shared_ptr reader, std::vector >& writers, unsigned int length, unsigned int buffersize) +void FileWriter::writeReader(std::shared_ptr reader, std::vector >& writers, unsigned int length, unsigned int buffersize, void(*callback)(float, void*), void* data) { Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs())); Buffer buffer2(buffersize * sizeof(sample_t)); @@ -89,6 +97,14 @@ void FileWriter::writeReader(std::shared_ptr reader, std::vectorwrite(len, buf2); } + + if(callback) + { + float progress = -1; + if(length > 0) + progress = pos / float(length); + callback(progress, data); + } } } diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 87b84c475fd..9d9918a6daf 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -386,7 +386,9 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op) specs, container, codec, - bitrate); + bitrate, + NULL, + NULL); } else { result = AUD_mixdown(scene_eval->sound_scene, @@ -397,7 +399,9 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op) specs, container, codec, - bitrate); + bitrate, + NULL, + NULL); } BKE_sound_reset_scene_specs(scene_eval); -- cgit v1.2.3 From 360489c75167d47653bc34ad9ba9a65076bf384c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 15:39:47 +0200 Subject: GPUPlatform: GL backend isolation Part of the vulkan implementation T68990. Pretty straight forward. Just move the GL code inside the GLBackend and make the GPUPlatformGlobal a class object. --- source/blender/gpu/CMakeLists.txt | 2 + source/blender/gpu/intern/gpu_init_exit.c | 2 - source/blender/gpu/intern/gpu_platform.cc | 217 +++++----------------- source/blender/gpu/intern/gpu_platform_private.hh | 53 ++++++ source/blender/gpu/intern/gpu_private.h | 4 - source/blender/gpu/opengl/gl_backend.cc | 135 ++++++++++++++ source/blender/gpu/opengl/gl_backend.hh | 9 + 7 files changed, 250 insertions(+), 172 deletions(-) create mode 100644 source/blender/gpu/intern/gpu_platform_private.hh create mode 100644 source/blender/gpu/opengl/gl_backend.cc diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 5cce4f84aea..47ce113230b 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -87,6 +87,7 @@ set(SRC intern/gpu_vertex_format.cc intern/gpu_viewport.c + opengl/gl_backend.cc opengl/gl_batch.cc opengl/gl_context.cc opengl/gl_drawlist.cc @@ -143,6 +144,7 @@ set(SRC intern/gpu_matrix_private.h intern/gpu_node_graph.h intern/gpu_private.h + intern/gpu_platform_private.hh intern/gpu_select_private.h intern/gpu_shader_private.hh intern/gpu_shader_interface.hh diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 4cb43db9bce..f265d841922 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -48,7 +48,6 @@ void GPU_init(void) } initialized = true; - gpu_platform_init(); gpu_extensions_init(); /* must come first */ gpu_codegen_init(); @@ -81,7 +80,6 @@ void GPU_exit(void) gpu_codegen_exit(); gpu_extensions_exit(); - gpu_platform_exit(); /* must come last */ initialized = false; } diff --git a/source/blender/gpu/intern/gpu_platform.cc b/source/blender/gpu/intern/gpu_platform.cc index 5cabde61bc3..e4db8c93f1d 100644 --- a/source/blender/gpu/intern/gpu_platform.cc +++ b/source/blender/gpu/intern/gpu_platform.cc @@ -23,75 +23,31 @@ * Wrap OpenGL features such as textures, shaders and GLSL * with checks for drivers and GPU support. */ -#include "GPU_platform.h" -#include "GPU_glew.h" -#include "gpu_private.h" -#include +#include "MEM_guardedalloc.h" #include "BLI_dynstr.h" #include "BLI_string.h" -#include "MEM_guardedalloc.h" +#include "GPU_platform.h" -static struct GPUPlatformGlobal { - bool initialized; - eGPUDeviceType device; - eGPUOSType os; - eGPUDriverType driver; - eGPUSupportLevel support_level; - char *support_key; - char *gpu_name; -} GPG = {false}; - -/* Remove this? */ -#if 0 -typedef struct GPUPlatformSupportTest { - eGPUSupportLevel support_level; - eGPUDeviceType device; - eGPUOSType os; - eGPUDriverType driver; - const char *vendor; - const char *renderer; - const char *version; -} GPUPlatformSupportTest; -#endif +#include "gpu_platform_private.hh" -eGPUSupportLevel GPU_platform_support_level(void) -{ - return GPG.support_level; -} +/* -------------------------------------------------------------------- */ +/** \name GPUPlatformGlobal + * \{ */ -const char *GPU_platform_support_level_key(void) -{ - return GPG.support_key; -} +namespace blender::gpu { -const char *GPU_platform_gpu_name(void) -{ - return GPG.gpu_name; -} +GPUPlatformGlobal GPG; -/* GPU Types */ -bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver) -{ - return (GPG.device & device) && (GPG.os & os) && (GPG.driver & driver); -} - -static char *gpu_platform_create_key(eGPUSupportLevel support_level, - const char *vendor, - const char *renderer, - const char *version) +void GPUPlatformGlobal::create_key(eGPUSupportLevel support_level, + const char *vendor, + const char *renderer, + const char *version) { DynStr *ds = BLI_dynstr_new(); - BLI_dynstr_append(ds, "{"); - BLI_dynstr_append(ds, vendor); - BLI_dynstr_append(ds, "/"); - BLI_dynstr_append(ds, renderer); - BLI_dynstr_append(ds, "/"); - BLI_dynstr_append(ds, version); - BLI_dynstr_append(ds, "}"); - BLI_dynstr_append(ds, "="); + BLI_dynstr_appendf(ds, "{%s/%s/%s}=", vendor, renderer, version); if (support_level == GPU_SUPPORT_LEVEL_SUPPORTED) { BLI_dynstr_append(ds, "SUPPORTED"); } @@ -102,132 +58,61 @@ static char *gpu_platform_create_key(eGPUSupportLevel support_level, BLI_dynstr_append(ds, "UNSUPPORTED"); } - char *support_key = BLI_dynstr_get_cstring(ds); + support_key = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); BLI_str_replace_char(support_key, '\n', ' '); BLI_str_replace_char(support_key, '\r', ' '); - return support_key; } -static char *gpu_platform_create_gpu_name(const char *vendor, - const char *renderer, - const char *version) +void GPUPlatformGlobal::create_gpu_name(const char *vendor, + const char *renderer, + const char *version) { DynStr *ds = BLI_dynstr_new(); - BLI_dynstr_append(ds, vendor); - BLI_dynstr_append(ds, " "); - BLI_dynstr_append(ds, renderer); - BLI_dynstr_append(ds, " "); - BLI_dynstr_append(ds, version); + BLI_dynstr_appendf(ds, "%s %s %s", vendor, renderer, version); - char *gpu_name = BLI_dynstr_get_cstring(ds); + gpu_name = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); BLI_str_replace_char(gpu_name, '\n', ' '); BLI_str_replace_char(gpu_name, '\r', ' '); - return gpu_name; } -void gpu_platform_init(void) +void GPUPlatformGlobal::clear(void) { - if (GPG.initialized) { - return; - } + MEM_SAFE_FREE(GPG.support_key); + MEM_SAFE_FREE(GPG.gpu_name); + initialized = false; +} -#ifdef _WIN32 - GPG.os = GPU_OS_WIN; -#elif defined(__APPLE__) - GPG.os = GPU_OS_MAC; -#else - GPG.os = GPU_OS_UNIX; -#endif - - const char *vendor = (const char *)glGetString(GL_VENDOR); - const char *renderer = (const char *)glGetString(GL_RENDERER); - const char *version = (const char *)glGetString(GL_VERSION); - - if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) { - GPG.device = GPU_DEVICE_ATI; - GPG.driver = GPU_DRIVER_OFFICIAL; - } - else if (strstr(vendor, "NVIDIA")) { - GPG.device = GPU_DEVICE_NVIDIA; - GPG.driver = GPU_DRIVER_OFFICIAL; - } - else if (strstr(vendor, "Intel") || - /* src/mesa/drivers/dri/intel/intel_context.c */ - strstr(renderer, "Mesa DRI Intel") || strstr(renderer, "Mesa DRI Mobile Intel")) { - GPG.device = GPU_DEVICE_INTEL; - GPG.driver = GPU_DRIVER_OFFICIAL; - - if (strstr(renderer, "UHD Graphics") || - /* Not UHD but affected by the same bugs. */ - strstr(renderer, "HD Graphics 530") || strstr(renderer, "Kaby Lake GT2") || - strstr(renderer, "Whiskey Lake")) { - GPG.device |= GPU_DEVICE_INTEL_UHD; - } - } - else if ((strstr(renderer, "Mesa DRI R")) || - (strstr(renderer, "Radeon") && strstr(vendor, "X.Org")) || - (strstr(renderer, "AMD") && strstr(vendor, "X.Org")) || - (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) || - (strstr(renderer, "Gallium ") && strstr(renderer, " on AMD "))) { - GPG.device = GPU_DEVICE_ATI; - GPG.driver = GPU_DRIVER_OPENSOURCE; - } - else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) { - GPG.device = GPU_DEVICE_NVIDIA; - GPG.driver = GPU_DRIVER_OPENSOURCE; - } - else if (strstr(vendor, "Mesa")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; - } - else if (strstr(vendor, "Microsoft")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; - } - else if (strstr(renderer, "Apple Software Renderer")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; - } - else if (strstr(renderer, "llvmpipe") || strstr(renderer, "softpipe")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; - } - else { - printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n"); - printf("Detected OpenGL configuration:\n"); - printf("Vendor: %s\n", vendor); - printf("Renderer: %s\n", renderer); - GPG.device = GPU_DEVICE_ANY; - GPG.driver = GPU_DRIVER_ANY; - } +} // namespace blender::gpu - /* Detect support level */ - if (!GLEW_VERSION_3_3) { - GPG.support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED; - } - else { - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) { - /* Old Intel drivers with known bugs that cause material properties to crash. - * Version Build 10.18.14.5067 is the latest available and appears to be working - * ok with our workarounds, so excluded from this list. */ - if (strstr(version, "Build 7.14") || strstr(version, "Build 7.15") || - strstr(version, "Build 8.15") || strstr(version, "Build 9.17") || - strstr(version, "Build 9.18") || strstr(version, "Build 10.18.10.3") || - strstr(version, "Build 10.18.10.4") || strstr(version, "Build 10.18.10.5") || - strstr(version, "Build 10.18.14.4")) { - GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED; - } - } - } - GPG.support_key = gpu_platform_create_key(GPG.support_level, vendor, renderer, version); - GPG.gpu_name = gpu_platform_create_gpu_name(vendor, renderer, version); - GPG.initialized = true; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name C-API + * \{ */ + +using namespace blender::gpu; + +eGPUSupportLevel GPU_platform_support_level(void) +{ + return GPG.support_level; } -void gpu_platform_exit(void) +const char *GPU_platform_support_level_key(void) { - MEM_SAFE_FREE(GPG.support_key); - MEM_SAFE_FREE(GPG.gpu_name); + return GPG.support_key; +} + +const char *GPU_platform_gpu_name(void) +{ + return GPG.gpu_name; } + +/* GPU Types */ +bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver) +{ + return (GPG.device & device) && (GPG.os & os) && (GPG.driver & driver); +} + +/** \} */ \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_platform_private.hh b/source/blender/gpu/intern/gpu_platform_private.hh new file mode 100644 index 00000000000..e882672fdda --- /dev/null +++ b/source/blender/gpu/intern/gpu_platform_private.hh @@ -0,0 +1,53 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "GPU_platform.h" + +namespace blender::gpu { + +class GPUPlatformGlobal { + public: + bool initialized = false; + eGPUDeviceType device; + eGPUOSType os; + eGPUDriverType driver; + eGPUSupportLevel support_level; + char *support_key = nullptr; + char *gpu_name = nullptr; + + public: + void create_key(eGPUSupportLevel support_level, + const char *vendor, + const char *renderer, + const char *version); + + void create_gpu_name(const char *vendor, const char *renderer, const char *version); + + void clear(void); +}; + +extern GPUPlatformGlobal GPG; + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h index 505ac3b0278..059d19f1002 100644 --- a/source/blender/gpu/intern/gpu_private.h +++ b/source/blender/gpu/intern/gpu_private.h @@ -24,10 +24,6 @@ extern "C" { #endif -/* call this before running any of the functions below */ -void gpu_platform_init(void); -void gpu_platform_exit(void); - /* call this before running any of the functions below */ void gpu_extensions_init(void); void gpu_extensions_exit(void); diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc new file mode 100644 index 00000000000..d44bb9ba481 --- /dev/null +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -0,0 +1,135 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "gpu_platform_private.hh" + +#include "glew-mx.h" + +#include "gl_backend.hh" + +namespace blender::gpu { + +void GLBackend::platform_init(void) +{ + BLI_assert(!GPG.initialized); + GPG.initialized = true; + +#ifdef _WIN32 + GPG.os = GPU_OS_WIN; +#elif defined(__APPLE__) + GPG.os = GPU_OS_MAC; +#else + GPG.os = GPU_OS_UNIX; +#endif + + const char *vendor = (const char *)glGetString(GL_VENDOR); + const char *renderer = (const char *)glGetString(GL_RENDERER); + const char *version = (const char *)glGetString(GL_VERSION); + + if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) { + GPG.device = GPU_DEVICE_ATI; + GPG.driver = GPU_DRIVER_OFFICIAL; + } + else if (strstr(vendor, "NVIDIA")) { + GPG.device = GPU_DEVICE_NVIDIA; + GPG.driver = GPU_DRIVER_OFFICIAL; + } + else if (strstr(vendor, "Intel") || + /* src/mesa/drivers/dri/intel/intel_context.c */ + strstr(renderer, "Mesa DRI Intel") || strstr(renderer, "Mesa DRI Mobile Intel")) { + GPG.device = GPU_DEVICE_INTEL; + GPG.driver = GPU_DRIVER_OFFICIAL; + + if (strstr(renderer, "UHD Graphics") || + /* Not UHD but affected by the same bugs. */ + strstr(renderer, "HD Graphics 530") || strstr(renderer, "Kaby Lake GT2") || + strstr(renderer, "Whiskey Lake")) { + GPG.device |= GPU_DEVICE_INTEL_UHD; + } + } + else if ((strstr(renderer, "Mesa DRI R")) || + (strstr(renderer, "Radeon") && strstr(vendor, "X.Org")) || + (strstr(renderer, "AMD") && strstr(vendor, "X.Org")) || + (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) || + (strstr(renderer, "Gallium ") && strstr(renderer, " on AMD "))) { + GPG.device = GPU_DEVICE_ATI; + GPG.driver = GPU_DRIVER_OPENSOURCE; + } + else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) { + GPG.device = GPU_DEVICE_NVIDIA; + GPG.driver = GPU_DRIVER_OPENSOURCE; + } + else if (strstr(vendor, "Mesa")) { + GPG.device = GPU_DEVICE_SOFTWARE; + GPG.driver = GPU_DRIVER_SOFTWARE; + } + else if (strstr(vendor, "Microsoft")) { + GPG.device = GPU_DEVICE_SOFTWARE; + GPG.driver = GPU_DRIVER_SOFTWARE; + } + else if (strstr(renderer, "Apple Software Renderer")) { + GPG.device = GPU_DEVICE_SOFTWARE; + GPG.driver = GPU_DRIVER_SOFTWARE; + } + else if (strstr(renderer, "llvmpipe") || strstr(renderer, "softpipe")) { + GPG.device = GPU_DEVICE_SOFTWARE; + GPG.driver = GPU_DRIVER_SOFTWARE; + } + else { + printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n"); + printf("Detected OpenGL configuration:\n"); + printf("Vendor: %s\n", vendor); + printf("Renderer: %s\n", renderer); + GPG.device = GPU_DEVICE_ANY; + GPG.driver = GPU_DRIVER_ANY; + } + + /* Detect support level */ + if (!GLEW_VERSION_3_3) { + GPG.support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED; + } + else { + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) { + /* Old Intel drivers with known bugs that cause material properties to crash. + * Version Build 10.18.14.5067 is the latest available and appears to be working + * ok with our workarounds, so excluded from this list. */ + if (strstr(version, "Build 7.14") || strstr(version, "Build 7.15") || + strstr(version, "Build 8.15") || strstr(version, "Build 9.17") || + strstr(version, "Build 9.18") || strstr(version, "Build 10.18.10.3") || + strstr(version, "Build 10.18.10.4") || strstr(version, "Build 10.18.10.5") || + strstr(version, "Build 10.18.14.4")) { + GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED; + } + } + } + GPG.create_key(GPG.support_level, vendor, renderer, version); + GPG.create_gpu_name(vendor, renderer, version); +} + +void GLBackend::platform_exit(void) +{ + BLI_assert(GPG.initialized); + GPG.clear(); +} + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index c178aa537a0..9548aa9dd92 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -47,11 +47,16 @@ class GLBackend : public GPUBackend { public: GLBackend() { + /* platform_init needs to go first. */ + GLBackend::platform_init(); + GLTexture::samplers_init(); } ~GLBackend() { GLTexture::samplers_free(); + + GLBackend::platform_exit(); } static GLBackend *get(void) @@ -118,6 +123,10 @@ class GLBackend : public GPUBackend { orphan_list.append(id); list_mutex.unlock(); } + + private: + static void platform_init(void); + static void platform_exit(void); }; } // namespace gpu -- cgit v1.2.3 From 171b36683a774d70a8f25529858b9c002a2a317e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 18:52:30 +0200 Subject: GPUExtensions: GL backend isolation This is part of the Vulkan task T68990. This commits changes a few things: - Rename extensions to capabilities (but left the file name untouched). - Cubemap mip render workaround detection is rewritten using gl commands to avoid using the GPU API before initialization. - Put all the capabilities that are only relevant for the GL backend inside GLContext as static variables. - Cleanup the names of the limit variables. - Separate all GL related workaround search inside the GL module. --- source/blender/draw/intern/DRW_render.h | 1 - source/blender/draw/intern/draw_manager.c | 5 - source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/GPU_extensions.h | 4 - source/blender/gpu/intern/gpu_extensions.cc | 352 ++------------------- .../blender/gpu/intern/gpu_extensions_private.hh | 54 ++++ source/blender/gpu/intern/gpu_init_exit.c | 3 - source/blender/gpu/intern/gpu_private.h | 4 - source/blender/gpu/intern/gpu_uniform_buffer.cc | 1 - source/blender/gpu/opengl/gl_backend.cc | 220 +++++++++++++ source/blender/gpu/opengl/gl_backend.hh | 3 + source/blender/gpu/opengl/gl_batch.cc | 7 +- source/blender/gpu/opengl/gl_context.hh | 13 + source/blender/gpu/opengl/gl_drawlist.cc | 2 +- source/blender/gpu/opengl/gl_framebuffer.cc | 2 +- source/blender/gpu/opengl/gl_shader.cc | 7 +- source/blender/gpu/opengl/gl_texture.cc | 6 +- source/blender/gpu/opengl/gl_uniform_buffer.cc | 5 +- 18 files changed, 340 insertions(+), 350 deletions(-) create mode 100644 source/blender/gpu/intern/gpu_extensions_private.hh diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 680636f9e87..e154a52b32f 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -721,7 +721,6 @@ void DRW_state_lock(DRWState state); void DRW_select_load_id(uint id); /* Draw State */ -void DRW_state_dfdy_factors_get(float dfdyfac[2]); bool DRW_state_is_fbo(void); bool DRW_state_is_select(void); bool DRW_state_is_depth(void); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 09ce16efcc2..49780f59db3 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2496,11 +2496,6 @@ void DRW_draw_depth_object( /** \name Draw Manager State (DRW_state) * \{ */ -void DRW_state_dfdy_factors_get(float dfdyfac[2]) -{ - GPU_get_dfdy_factors(dfdyfac); -} - /** * When false, drawing doesn't output to a pixel buffer * eg: Occlusion queries, or when we have setup a context to draw in already. diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 47ce113230b..358bd045c2f 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -137,6 +137,7 @@ set(SRC intern/gpu_codegen.h intern/gpu_context_private.hh intern/gpu_drawlist_private.hh + intern/gpu_extensions_private.hh intern/gpu_framebuffer_private.hh intern/gpu_immediate_private.hh intern/gpu_index_buffer_private.hh diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 35967ac304f..dd0a2ec9f39 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -41,14 +41,10 @@ int GPU_max_color_texture_samples(void); int GPU_max_cube_map_size(void); int GPU_max_ubo_binds(void); int GPU_max_ubo_size(void); -void GPU_get_dfdy_factors(float fac[2]); -bool GPU_arb_base_instance_is_supported(void); bool GPU_arb_texture_cube_map_array_is_supported(void); bool GPU_mip_render_workaround(void); bool GPU_depth_blitting_workaround(void); -bool GPU_unused_fb_slot_workaround(void); bool GPU_use_main_context_workaround(void); -bool GPU_texture_copy_workaround(void); bool GPU_crappy_amd_driver(void); int GPU_texture_size_with_limit(int res); diff --git a/source/blender/gpu/intern/gpu_extensions.cc b/source/blender/gpu/intern/gpu_extensions.cc index ac7748e6430..168d2fb3fbb 100644 --- a/source/blender/gpu/intern/gpu_extensions.cc +++ b/source/blender/gpu/intern/gpu_extensions.cc @@ -24,381 +24,95 @@ * with checks for drivers and GPU support. */ -#include "BLI_math_base.h" -#include "BLI_math_vector.h" -#include "BLI_utildefines.h" - -#include "BKE_global.h" -#include "MEM_guardedalloc.h" - #include "DNA_userdef_types.h" #include "GPU_extensions.h" -#include "GPU_framebuffer.h" -#include "GPU_glew.h" -#include "GPU_platform.h" -#include "GPU_texture.h" - -#include "intern/gpu_private.h" - -#include -#include -#include - -#ifdef WIN32 -# include "BLI_winstuff.h" -#endif - -/* Extensions support */ - -/* -- extension: version of GL that absorbs it - * EXT_gpu_shader4: 3.0 - * ARB_framebuffer object: 3.0 - * EXT_framebuffer_multisample_blit_scaled: ??? - * ARB_draw_instanced: 3.1 - * ARB_texture_multisample: 3.2 - * ARB_texture_query_lod: 4.0 - */ - -static struct GPUGlobal { - GLint maxtexsize; - GLint maxtex3dsize; - GLint maxtexlayers; - GLint maxcubemapsize; - GLint maxtextures; - GLint maxtexturesfrag; - GLint maxtexturesgeom; - GLint maxtexturesvert; - GLint maxubosize; - GLint maxubobinds; - int samples_color_texture_max; - /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers - * calculate dfdy in shader differently when drawing to an off-screen buffer. First - * number is factor on screen and second is off-screen */ - float dfdyfactors[2]; - /* Some Intel drivers have limited support for `GLEW_ARB_base_instance` so in - * these cases it is best to indicate that it is not supported. See T67951 */ - bool glew_arb_base_instance_is_supported; - /* Cubemap Array support. */ - bool glew_arb_texture_cube_map_array_is_supported; - /* Some Intel drivers have issues with using mips as framebuffer targets if - * GL_TEXTURE_MAX_LEVEL is higher than the target mip. - * We need a workaround in this cases. */ - bool mip_render_workaround; - /* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics. - * Blitting depth with#GL_DEPTH24_STENCIL8 is buggy so the workaround is to use - * #GPU_DEPTH32F_STENCIL8. Then Blitting depth will work but blitting stencil will - * still be broken. */ - bool depth_blitting_workaround; - /* Crappy driver don't know how to map framebuffer slot to output vars... - * We need to have no "holes" in the output buffer slots. */ - bool unused_fb_slot_workaround; - bool broken_amd_driver; - /* Some crappy Intel drivers don't work well with shaders created in different - * rendering contexts. */ - bool use_main_context_workaround; - /* Intel drivers exhibit artifacts when using #glCopyImageSubData & workbench anti-aliasing. - * (see T76273) */ - bool texture_copy_workaround; -} GG = {1, 0}; - -static void gpu_detect_mip_render_workaround(void) -{ - int cube_size = 2; - float *source_pix = (float *)MEM_callocN(sizeof(float[4][6]) * cube_size * cube_size, __func__); - float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f}; - GPUTexture *tex = GPU_texture_create_cube(__func__, cube_size, 2, GPU_RGBA16F, source_pix); - MEM_freeN(source_pix); +#include "gpu_extensions_private.hh" - GPU_texture_bind(tex, 0); - GPU_texture_generate_mipmap(tex); - glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, 0); - GPU_texture_unbind(tex); +#include "gl_backend.hh" /* TODO remove */ - GPUFrameBuffer *fb = GPU_framebuffer_create(__func__); - GPU_framebuffer_texture_attach(fb, tex, 0, 1); - GPU_framebuffer_bind(fb); - GPU_framebuffer_clear_color(fb, clear_color); - GPU_framebuffer_restore(); - GPU_framebuffer_free(fb); +namespace blender::gpu { - float *data = (float *)GPU_texture_read(tex, GPU_DATA_FLOAT, 1); - GG.mip_render_workaround = !equals_v4v4(clear_color, data); +GPUCapabilities GCaps; - MEM_freeN(data); - GPU_texture_free(tex); } -/* GPU Extensions */ +using namespace blender::gpu; + +/* -------------------------------------------------------------------- */ +/** \name Capabilities + * \{ */ int GPU_max_texture_size(void) { - return GG.maxtexsize; + return GCaps.max_texture_size; } -int GPU_max_texture_3d_size(void) +int GPU_texture_size_with_limit(int res) { - return GG.maxtex3dsize; + int size = GPU_max_texture_size(); + int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size; + return min_ii(reslimit, res); } int GPU_max_texture_layers(void) { - return GG.maxtexlayers; -} - -int GPU_max_textures(void) -{ - return GG.maxtextures; -} - -int GPU_max_textures_frag(void) -{ - return GG.maxtexturesfrag; -} - -int GPU_max_textures_geom(void) -{ - return GG.maxtexturesgeom; + return GCaps.max_texture_layers; } int GPU_max_textures_vert(void) { - return GG.maxtexturesvert; -} - -int GPU_max_color_texture_samples(void) -{ - return GG.samples_color_texture_max; -} - -int GPU_max_cube_map_size(void) -{ - return GG.maxcubemapsize; -} - -int GPU_max_ubo_binds(void) -{ - return GG.maxubobinds; + return GCaps.max_textures_vert; } -int GPU_max_ubo_size(void) +int GPU_max_textures_geom(void) { - return GG.maxubosize; + return GCaps.max_textures_geom; } -void GPU_get_dfdy_factors(float fac[2]) +int GPU_max_textures_frag(void) { - copy_v2_v2(fac, GG.dfdyfactors); + return GCaps.max_textures_frag; } -bool GPU_arb_base_instance_is_supported(void) +int GPU_max_textures(void) { - return GG.glew_arb_base_instance_is_supported; + return GCaps.max_textures; } bool GPU_arb_texture_cube_map_array_is_supported(void) { - return GG.glew_arb_texture_cube_map_array_is_supported; + /* FIXME bad level call. */ + return GLContext::texture_cube_map_array_support; } bool GPU_mip_render_workaround(void) { - return GG.mip_render_workaround; + return GCaps.mip_render_workaround; } bool GPU_depth_blitting_workaround(void) { - return GG.depth_blitting_workaround; -} - -bool GPU_unused_fb_slot_workaround(void) -{ - return GG.unused_fb_slot_workaround; + return GCaps.depth_blitting_workaround; } bool GPU_use_main_context_workaround(void) { - return GG.use_main_context_workaround; -} - -bool GPU_texture_copy_workaround(void) -{ - return GG.texture_copy_workaround; + return GCaps.use_main_context_workaround; } bool GPU_crappy_amd_driver(void) { /* Currently are the same drivers with the `unused_fb_slot` problem. */ - return GG.broken_amd_driver; -} - -int GPU_texture_size_with_limit(int res) -{ - int size = GPU_max_texture_size(); - int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size; - return min_ii(reslimit, res); + return GCaps.broken_amd_driver; } -void gpu_extensions_init(void) -{ - /* during 2.8 development each platform has its own OpenGL minimum requirements - * final 2.8 release will be unified on OpenGL 3.3 core profile, no required extensions - * see developer.blender.org/T49012 for details - */ - BLI_assert(GLEW_VERSION_3_3); - - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GG.maxtexturesfrag); - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &GG.maxtexturesvert); - glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GG.maxtexturesgeom); - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GG.maxtextures); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize); - glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GG.maxtex3dsize); - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GG.maxtexlayers); - glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GG.maxcubemapsize); +/** \} */ - glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GG.maxubobinds); - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GG.maxubosize); - - glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &GG.samples_color_texture_max); - - const char *vendor = (const char *)glGetString(GL_VENDOR); - const char *renderer = (const char *)glGetString(GL_RENDERER); - const char *version = (const char *)glGetString(GL_VERSION); - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) { - if (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") || - strstr(version, "4.5.13422")) { - /* The renderers include: - * Mobility Radeon HD 5000; - * Radeon HD 7500M; - * Radeon HD 7570M; - * Radeon HD 7600M; - * And many others... */ - - GG.unused_fb_slot_workaround = true; - GG.broken_amd_driver = true; - } - } - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && - strstr(renderer, "AMD VERDE")) { - /* We have issues with this specific renderer. (see T74024) */ - GG.unused_fb_slot_workaround = true; - GG.broken_amd_driver = true; - } - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && - strstr(version, "Mesa 19.3.4")) { - /* Fix slowdown on this particular driver. (see T77641) */ - GG.broken_amd_driver = true; - } - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { - if (strstr(renderer, "AMD Radeon Pro") || strstr(renderer, "AMD Radeon R9") || - strstr(renderer, "AMD Radeon RX")) { - GG.depth_blitting_workaround = true; - } - } - - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) { - /* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are - * covered since they only support GL 4.4 on windows. - * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */ - if (!GLEW_VERSION_4_5) { - GG.texture_copy_workaround = true; - } - } - - /* Limit support for GLEW_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800 - * (TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support - * GLEW_ARB_draw_indirect as it has an OpenGL3 context what also matches the minimum needed - * requirements. - * - * We use it as a target for glMapBuffer(Range) what is part of the OpenGL 4 API. So better - * disable it when we don't have an OpenGL4 context (See T77657) */ - GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance && GLEW_VERSION_4_0; - GG.glew_arb_texture_cube_map_array_is_supported = GLEW_ARB_texture_cube_map_array; - gpu_detect_mip_render_workaround(); - - if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) { - printf("\n"); - printf("GPU: Bypassing workaround detection.\n"); - printf("GPU: OpenGL identification strings\n"); - printf("GPU: vendor: %s\n", vendor); - printf("GPU: renderer: %s\n", renderer); - printf("GPU: version: %s\n\n", version); - GG.mip_render_workaround = true; - GG.depth_blitting_workaround = true; - GG.unused_fb_slot_workaround = true; - GG.texture_copy_workaround = true; - } - - /* Special fix for theses specific GPUs. - * Without this workaround, blender crashes on startup. (see T72098) */ - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && - (strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) { - GG.mip_render_workaround = true; - } - - /* Intel Ivy Bridge GPU's seems to have buggy cube-map array support. (see T75943) */ - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && - (strstr(renderer, "HD Graphics 4000") || strstr(renderer, "HD Graphics 4400") || - strstr(renderer, "HD Graphics 2500"))) { - GG.glew_arb_texture_cube_map_array_is_supported = false; - } - - /* df/dy calculation factors, those are dependent on driver */ - GG.dfdyfactors[0] = 1.0; - GG.dfdyfactors[1] = 1.0; - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) && - strstr(version, "3.3.10750")) { - GG.dfdyfactors[0] = 1.0; - GG.dfdyfactors[1] = -1.0; - } - else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) { - if (strstr(version, "4.0.0 - Build 10.18.10.3308") || - strstr(version, "4.0.0 - Build 9.18.10.3186") || - strstr(version, "4.0.0 - Build 9.18.10.3165") || - strstr(version, "3.1.0 - Build 9.17.10.3347") || - strstr(version, "3.1.0 - Build 9.17.10.4101") || - strstr(version, "3.3.0 - Build 8.15.10.2618")) { - GG.dfdyfactors[0] = -1.0; - GG.dfdyfactors[1] = 1.0; - } - - if (strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") || - strstr(version, "Build 10.18.10.5") || strstr(version, "Build 10.18.14.4") || - strstr(version, "Build 10.18.14.5")) { - /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`. - * But it's hard to test each case. */ - GG.glew_arb_base_instance_is_supported = false; - GG.use_main_context_workaround = true; - } - - if (strstr(version, "Build 20.19.15.4285")) { - /* Somehow fixes armature display issues (see T69743). */ - GG.use_main_context_workaround = true; - } - } - else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && - (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") || - strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2"))) { - /* See T70187: merging vertices fail. This has been tested from 18.2.2 till 19.3.0~dev of the - * Mesa driver */ - GG.unused_fb_slot_workaround = true; - } - - GPU_invalid_tex_init(); -} - -void gpu_extensions_exit(void) -{ - GPU_invalid_tex_free(); -} +/* -------------------------------------------------------------------- */ +/** \name Memory statistics + * \{ */ bool GPU_mem_stats_supported(void) { @@ -439,3 +153,5 @@ bool GPU_stereo_quadbuffer_support(void) glGetBooleanv(GL_STEREO, &stereo); return stereo == GL_TRUE; } + +/** \} */ diff --git a/source/blender/gpu/intern/gpu_extensions_private.hh b/source/blender/gpu/intern/gpu_extensions_private.hh new file mode 100644 index 00000000000..ec387555bfe --- /dev/null +++ b/source/blender/gpu/intern/gpu_extensions_private.hh @@ -0,0 +1,54 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "GPU_platform.h" + +namespace blender::gpu { + +/** + * This includes both hardware capabilities & workarounds. + * Try to limit these to the implementation codebase (i.e.: gpu/opengl/). + * Only add workarounds here if they are common to all implementation or + * if you need access to it outside of the GPU module. + * Same goes for capabilities (i.e.: texture size) + **/ +struct GPUCapabilities { + int max_texture_size = 0; + int max_texture_layers = 0; + int max_textures = 0; + int max_textures_vert = 0; + int max_textures_geom = 0; + int max_textures_frag = 0; + + /* OpenGL related workarounds. */ + bool mip_render_workaround = false; + bool depth_blitting_workaround = false; + bool use_main_context_workaround = false; + bool broken_amd_driver = false; +}; + +extern GPUCapabilities GCaps; + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index f265d841922..129a66994b1 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -48,7 +48,6 @@ void GPU_init(void) } initialized = true; - gpu_extensions_init(); /* must come first */ gpu_codegen_init(); gpu_material_library_init(); @@ -79,8 +78,6 @@ void GPU_exit(void) gpu_material_library_exit(); gpu_codegen_exit(); - gpu_extensions_exit(); - initialized = false; } diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h index 059d19f1002..310a432c102 100644 --- a/source/blender/gpu/intern/gpu_private.h +++ b/source/blender/gpu/intern/gpu_private.h @@ -24,10 +24,6 @@ extern "C" { #endif -/* call this before running any of the functions below */ -void gpu_extensions_init(void); -void gpu_extensions_exit(void); - /* gpu_pbvh.c */ void gpu_pbvh_init(void); void gpu_pbvh_exit(void); diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc index 94aa6bd76ab..24e5b452e03 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer.cc +++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc @@ -47,7 +47,6 @@ UniformBuf::UniformBuf(size_t size, const char *name) { /* Make sure that UBO is padded to size of vec4 */ BLI_assert((size % 16) == 0); - BLI_assert(size <= GPU_max_ubo_size()); size_in_bytes_ = size; diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index d44bb9ba481..317416ca355 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -21,6 +21,9 @@ * \ingroup gpu */ +#include "BKE_global.h" + +#include "gpu_extensions_private.hh" #include "gpu_platform_private.hh" #include "glew-mx.h" @@ -29,6 +32,10 @@ namespace blender::gpu { +/* -------------------------------------------------------------------- */ +/** \name Platform + * \{ */ + void GLBackend::platform_init(void) { BLI_assert(!GPG.initialized); @@ -132,4 +139,217 @@ void GLBackend::platform_exit(void) GPG.clear(); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Capabilities + * \{ */ + +static bool detect_mip_render_workaround(void) +{ + int cube_size = 2; + float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f}; + float *source_pix = (float *)MEM_callocN(sizeof(float[4]) * cube_size * cube_size * 6, __func__); + + /* Not using GPU API since it is not yet fully initialized. */ + GLuint tex, fb; + /* Create cubemap with 2 mip level. */ + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + for (int mip = 0; mip < 2; mip++) { + for (int i = 0; i < 6; i++) { + GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; + glTexImage2D(target, mip, GL_RGBA16F, 2, 2, 0, GL_RGBA, GL_FLOAT, source_pix); + } + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); + /* Attach and clear mip 1. */ + glGenFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, fb); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glClearColor(UNPACK4(clear_color)); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDrawBuffer(GL_BACK); + /* Read mip 1. If color is not the same as the clear_color, the rendering failed. */ + glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA, GL_FLOAT, source_pix); + bool enable_workaround = !equals_v4v4(clear_color, source_pix); + MEM_freeN(source_pix); + + glDeleteFramebuffers(1, &fb); + glDeleteTextures(1, &tex); + + return enable_workaround; +} + +static void detect_workarounds(void) +{ + const char *vendor = (const char *)glGetString(GL_VENDOR); + const char *renderer = (const char *)glGetString(GL_RENDERER); + const char *version = (const char *)glGetString(GL_VERSION); + + if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) { + printf("\n"); + printf("GL: Forcing workaround usage and disabling extensions.\n"); + printf(" OpenGL identification strings\n"); + printf(" vendor: %s\n", vendor); + printf(" renderer: %s\n", renderer); + printf(" version: %s\n\n", version); + GCaps.depth_blitting_workaround = true; + GCaps.mip_render_workaround = true; + GLContext::unused_fb_slot_workaround = true; + GLContext::texture_copy_workaround = true; + /* Turn off extensions. */ + GLContext::base_instance_support = false; + GLContext::texture_cube_map_array_support = false; + return; + } + + /* Some Intel drivers have issues with using mips as framebuffer targets if + * GL_TEXTURE_MAX_LEVEL is higher than the target mip. + * Only check at the end after all other workarounds because this uses the drawing code. */ + GCaps.mip_render_workaround = detect_mip_render_workaround(); + /* Limit support for GLEW_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800 + * (TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support + * GLEW_ARB_draw_indirect as it has an OpenGL3 context what also matches the minimum needed + * requirements. + * + * We use it as a target for glMapBuffer(Range) what is part of the OpenGL 4 API. So better + * disable it when we don't have an OpenGL4 context (See T77657) */ + if (!GLEW_VERSION_4_0) { + GLContext::base_instance_support = false; + } + /* The renderers include: + * Mobility Radeon HD 5000; + * Radeon HD 7500M; + * Radeon HD 7570M; + * Radeon HD 7600M; + * And many others... */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && + (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") || + strstr(version, "4.5.13422"))) { + GLContext::unused_fb_slot_workaround = true; + GCaps.broken_amd_driver = true; + } + /* We have issues with this specific renderer. (see T74024) */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && + strstr(renderer, "AMD VERDE")) { + GLContext::unused_fb_slot_workaround = true; + GCaps.broken_amd_driver = true; + } + /* Fix slowdown on this particular driver. (see T77641) */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && + strstr(version, "Mesa 19.3.4")) { + GCaps.broken_amd_driver = true; + } + /* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics. + * Blitting depth with#GL_DEPTH24_STENCIL8 is buggy so the workaround is to use + * #GPU_DEPTH32F_STENCIL8. Then Blitting depth will work but blitting stencil will + * still be broken. */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { + if (strstr(renderer, "AMD Radeon Pro") || strstr(renderer, "AMD Radeon R9") || + strstr(renderer, "AMD Radeon RX")) { + GCaps.depth_blitting_workaround = true; + } + } + /* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are + * covered since they only support GL 4.4 on windows. + * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */ + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && !GLEW_VERSION_4_5) { + GLContext::texture_copy_workaround = true; + } + /* Special fix for theses specific GPUs. + * Without this workaround, blender crashes on startup. (see T72098) */ + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && + (strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) { + GCaps.mip_render_workaround = true; + } + /* Intel Ivy Bridge GPU's seems to have buggy cube-map array support. (see T75943) */ + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && + (strstr(renderer, "HD Graphics 4000") || strstr(renderer, "HD Graphics 4400") || + strstr(renderer, "HD Graphics 2500"))) { + GLContext::texture_cube_map_array_support = false; + } + /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`. + * But it's hard to test each case. + * We get crashes from some crappy Intel drivers don't work well with shaders created in + * different rendering contexts. */ + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY) && + (strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") || + strstr(version, "Build 10.18.10.5") || strstr(version, "Build 10.18.14.4") || + strstr(version, "Build 10.18.14.5"))) { + GLContext::base_instance_support = false; + GCaps.use_main_context_workaround = true; + } + /* Somehow fixes armature display issues (see T69743). */ + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY) && + (strstr(version, "Build 20.19.15.4285"))) { + GCaps.use_main_context_workaround = true; + } + /* See T70187: merging vertices fail. This has been tested from 18.2.2 till 19.3.0~dev of the + * Mesa driver */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && + (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") || + strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2"))) { + GLContext::unused_fb_slot_workaround = true; + } + + /* dFdx/dFdy calculation factors, those are dependent on driver. */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) && + strstr(version, "3.3.10750")) { + GLContext::derivative_signs[0] = 1.0; + GLContext::derivative_signs[1] = -1.0; + } + else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) { + if (strstr(version, "4.0.0 - Build 10.18.10.3308") || + strstr(version, "4.0.0 - Build 9.18.10.3186") || + strstr(version, "4.0.0 - Build 9.18.10.3165") || + strstr(version, "3.1.0 - Build 9.17.10.3347") || + strstr(version, "3.1.0 - Build 9.17.10.4101") || + strstr(version, "3.3.0 - Build 8.15.10.2618")) { + GLContext::derivative_signs[0] = -1.0; + GLContext::derivative_signs[1] = 1.0; + } + } +} + +/** Internal capabilities. */ +GLint GLContext::max_texture_3d_size; +GLint GLContext::max_cubemap_size; +GLint GLContext::max_ubo_size; +GLint GLContext::max_ubo_binds; +/** Extensions. */ +bool GLContext::base_instance_support = false; +bool GLContext::texture_cube_map_array_support = false; +/** Workarounds. */ +bool GLContext::texture_copy_workaround = false; +bool GLContext::unused_fb_slot_workaround = false; +float GLContext::derivative_signs[2] = {1.0f, 1.0f}; + +void GLBackend::capabilities_init(void) +{ + BLI_assert(GLEW_VERSION_3_3); + /* Common Capabilities. */ + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GCaps.max_texture_size); + glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GCaps.max_texture_layers); + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_frag); + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_vert); + glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_geom); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GCaps.max_textures); + /* GL specific capabilities. */ + glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GLContext::max_texture_3d_size); + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size); + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GLContext::max_ubo_binds); + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GLContext::max_ubo_size); + GLContext::base_instance_support = GLEW_ARB_base_instance; + GLContext::texture_cube_map_array_support = GLEW_ARB_texture_cube_map_array; + + detect_workarounds(); +} + +/** \} */ + } // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index 9548aa9dd92..25f3ff38d8b 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -50,6 +50,7 @@ class GLBackend : public GPUBackend { /* platform_init needs to go first. */ GLBackend::platform_init(); + GLBackend::capabilities_init(); GLTexture::samplers_init(); } ~GLBackend() @@ -127,6 +128,8 @@ class GLBackend : public GPUBackend { private: static void platform_init(void); static void platform_exit(void); + + static void capabilities_init(void); }; } // namespace gpu diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index db30a57953d..f4ad7194ce1 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -34,6 +34,7 @@ #include "gpu_batch_private.hh" #include "gpu_shader_private.hh" +#include "gl_backend.hh" #include "gl_context.hh" #include "gl_debug.hh" #include "gl_index_buffer.hh" @@ -314,7 +315,7 @@ void GLBatch::bind(int i_first) #endif /* Can be removed if GL 4.2 is required. */ - if (!GPU_arb_base_instance_is_supported() && (i_first > 0)) { + if (!GLContext::base_instance_support && (i_first > 0)) { glBindVertexArray(vao_cache_.base_instance_vao_get(this, i_first)); } else { @@ -339,7 +340,7 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count) GLint base_index = el->index_base_; void *v_first_ofs = el->offset_ptr(v_first); - if (GPU_arb_base_instance_is_supported()) { + if (GLContext::base_instance_support) { glDrawElementsInstancedBaseVertexBaseInstance( gl_type, v_count, index_type, v_first_ofs, i_count, base_index, i_first); } @@ -353,7 +354,7 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count) #ifdef __APPLE__ glDisable(GL_PRIMITIVE_RESTART); #endif - if (GPU_arb_base_instance_is_supported()) { + if (GLContext::base_instance_support) { glDrawArraysInstancedBaseInstance(gl_type, v_first, v_count, i_count, i_first); } else { diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index 9e6359fabad..e2ae8bf24b2 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -55,6 +55,19 @@ class GLSharedOrphanLists { class GLContext : public GPUContext { public: + /** Capabilities. */ + static GLint max_texture_3d_size; + static GLint max_cubemap_size; + static GLint max_ubo_size; + static GLint max_ubo_binds; + /** Extensions. */ + static bool base_instance_support; + static bool texture_cube_map_array_support; + /** Workarounds. */ + static bool texture_copy_workaround; + static bool unused_fb_slot_workaround; + static float derivative_signs[2]; + /** Used for debugging purpose. Bitflags of all bound slots. */ uint16_t bound_ubo_slots; diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index d8c17084457..0768f7502ce 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -76,7 +76,7 @@ GLDrawList::GLDrawList(int length) data_ = NULL; if (USE_MULTI_DRAW_INDIRECT && GLEW_ARB_multi_draw_indirect && - GPU_arb_base_instance_is_supported()) { + GLContext::base_instance_support) { /* Alloc the biggest possible command list, which is indexed. */ buffer_size_ = sizeof(GLDrawCommandIndexed) * length; } diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index 4be471b236a..506a945d9d4 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -208,7 +208,7 @@ void GLFrameBuffer::update_attachments(void) } } - if (GPU_unused_fb_slot_workaround()) { + if (GLContext::unused_fb_slot_workaround) { /* Fill normally un-occupied slots to avoid rendering artifacts on some hardware. */ GLuint gl_tex = 0; /* NOTE: Inverse iteration to get the first color texture. */ diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 9136a1d9714..f125afeb535 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -28,6 +28,7 @@ #include "GPU_extensions.h" #include "GPU_platform.h" +#include "gl_backend.hh" #include "gl_vertex_buffer.hh" #include "gl_shader.hh" @@ -118,10 +119,8 @@ char *GLShader::glsl_patch_get(void) } /* 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]); + STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", GLContext::derivative_signs[0]); + STR_CONCATF(patch, slen, "#define DFDY_SIGN %1.1f\n", GLContext::derivative_signs[1]); BLI_assert(slen < sizeof(patch)); return patch; diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 6cff97215e8..ba2e5844cc7 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -369,7 +369,7 @@ void GLTexture::copy_to(Texture *dst_) /* TODO support array / 3D textures. */ BLI_assert(dst->d_ == 0); - if (GLEW_ARB_copy_image && !GPU_texture_copy_workaround()) { + if (GLEW_ARB_copy_image && !GLContext::texture_copy_workaround) { /* Opengl 4.3 */ int mip = 0; /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */ @@ -560,8 +560,8 @@ bool GLTexture::proxy_check(int mip) { /* Manual validation first, since some implementation have issues with proxy creation. */ int max_size = GPU_max_texture_size(); - int max_3d_size = GPU_max_texture_3d_size(); - int max_cube_size = GPU_max_cube_map_size(); + int max_3d_size = GLContext::max_texture_3d_size; + int max_cube_size = GLContext::max_cubemap_size; int size[3] = {1, 1, 1}; this->mip_size_get(mip, size); diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc index 0e0c64e5c60..82b7341d145 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.cc +++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc @@ -42,6 +42,7 @@ namespace blender::gpu { GLUniformBuf::GLUniformBuf(size_t size, const char *name) : UniformBuf(size, name) { /* Do not create ubo GL buffer here to allow allocation from any thread. */ + BLI_assert(size <= GLContext::max_ubo_size); } GLUniformBuf::~GLUniformBuf() @@ -90,12 +91,12 @@ void GLUniformBuf::update(const void *data) void GLUniformBuf::bind(int slot) { - if (slot >= GPU_max_ubo_binds()) { + if (slot >= GLContext::max_ubo_binds) { fprintf(stderr, "Error: Trying to bind \"%s\" ubo to slot %d which is above the reported limit of %d.", name_, slot, - GPU_max_ubo_binds()); + GLContext::max_ubo_binds); return; } -- cgit v1.2.3 From a784e90be02548aa38ba7c6d48087a819ea8693d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 19:17:04 +0200 Subject: EEVEE: Try to allocate the lightcache and use fallback if failure This is to remove an explicit opengl dependence to GPU_extension. --- .../blender/draw/engines/eevee/eevee_lightcache.c | 38 ++++++++++------------ source/blender/gpu/GPU_extensions.h | 1 - source/blender/gpu/intern/gpu_extensions.cc | 6 ---- source/blender/gpu/opengl/gl_shader.cc | 2 +- source/blender/gpu/opengl/gl_texture.cc | 5 +-- 5 files changed, 22 insertions(+), 30 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 49d68481045..5de161a646b 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -348,17 +348,14 @@ LightCache *EEVEE_lightcache_create(const int grid_len, int mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL; - if (GPU_arb_texture_cube_map_array_is_supported()) { - light_cache->cube_tx.tex = DRW_texture_create_cube_array( - cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); - } - else { - light_cache->cube_tx.tex = DRW_texture_create_2d_array(cube_size, - cube_size, - cube_len * 6, - GPU_R11F_G11F_B10F, - DRW_TEX_FILTER | DRW_TEX_MIPMAP, - NULL); + /* Try to create a cubemap array. */ + DRWTextureFlag cube_texflag = DRW_TEX_FILTER | DRW_TEX_MIPMAP; + light_cache->cube_tx.tex = DRW_texture_create_cube_array( + cube_size, cube_len, GPU_R11F_G11F_B10F, cube_texflag, NULL); + if (light_cache->cube_tx.tex == NULL) { + /* Try fallback to 2D array. */ + light_cache->cube_tx.tex = DRW_texture_create_2d_array( + cube_size, cube_size, cube_len * 6, GPU_R11F_G11F_B10F, cube_texflag, NULL); } light_cache->cube_tx.tex_size[0] = cube_size; @@ -414,15 +411,16 @@ static bool eevee_lightcache_static_load(LightCache *lcache) } if (lcache->cube_tx.tex == NULL) { - if (GPU_arb_texture_cube_map_array_is_supported()) { - lcache->cube_tx.tex = GPU_texture_create_cube_array("lightcache_cubemaps", - lcache->cube_tx.tex_size[0], - lcache->cube_tx.tex_size[2] / 6, - lcache->mips_len + 1, - GPU_R11F_G11F_B10F, - NULL); - } - else { + /* Try to create a cubemap array. */ + lcache->cube_tx.tex = GPU_texture_create_cube_array("lightcache_cubemaps", + lcache->cube_tx.tex_size[0], + lcache->cube_tx.tex_size[2] / 6, + lcache->mips_len + 1, + GPU_R11F_G11F_B10F, + NULL); + + if (lcache->cube_tx.tex == NULL) { + /* Try fallback to 2D array. */ lcache->cube_tx.tex = GPU_texture_create_2d_array("lightcache_cubemaps_fallback", UNPACK3(lcache->cube_tx.tex_size), lcache->mips_len + 1, diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index dd0a2ec9f39..357e867775a 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -41,7 +41,6 @@ int GPU_max_color_texture_samples(void); int GPU_max_cube_map_size(void); int GPU_max_ubo_binds(void); int GPU_max_ubo_size(void); -bool GPU_arb_texture_cube_map_array_is_supported(void); bool GPU_mip_render_workaround(void); bool GPU_depth_blitting_workaround(void); bool GPU_use_main_context_workaround(void); diff --git a/source/blender/gpu/intern/gpu_extensions.cc b/source/blender/gpu/intern/gpu_extensions.cc index 168d2fb3fbb..e06828bf994 100644 --- a/source/blender/gpu/intern/gpu_extensions.cc +++ b/source/blender/gpu/intern/gpu_extensions.cc @@ -81,12 +81,6 @@ int GPU_max_textures(void) return GCaps.max_textures; } -bool GPU_arb_texture_cube_map_array_is_supported(void) -{ - /* FIXME bad level call. */ - return GLContext::texture_cube_map_array_support; -} - bool GPU_mip_render_workaround(void) { return GCaps.mip_render_workaround; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index f125afeb535..76e20de1e51 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -113,7 +113,7 @@ char *GLShader::glsl_patch_get(void) 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()) { + if (GLContext::texture_cube_map_array_support) { 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"); } diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index ba2e5844cc7..4c3d34a759f 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -71,8 +71,9 @@ bool GLTexture::init_internal(void) format_ = GPU_DEPTH32F_STENCIL8; } - if ((type_ == GPU_TEXTURE_CUBE_ARRAY) && !GPU_arb_texture_cube_map_array_is_supported()) { - debug::raise_gl_error("Attempt to create a cubemap array without hardware support!"); + if ((type_ == GPU_TEXTURE_CUBE_ARRAY) && (GLContext::texture_cube_map_array_support == false)) { + /* Silently fail and let the caller handle the error. */ + // debug::raise_gl_error("Attempt to create a cubemap array without hardware support!"); return false; } -- cgit v1.2.3 From 5de4525e3939514b339c9775541ff7d1bc8af908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 19:19:06 +0200 Subject: GPUTexture: Bump GPU_TEX_MAX_FBO_ATTACHED This was causing an assert when using `--debug-gpu-force-workarounds` --- source/blender/gpu/intern/gpu_texture_private.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 8f01d28e65e..d237540f654 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -66,7 +66,7 @@ ENUM_OPERATORS(eGPUTextureType) #endif /* Maximum number of FBOs a texture can be attached to. */ -#define GPU_TEX_MAX_FBO_ATTACHED 13 +#define GPU_TEX_MAX_FBO_ATTACHED 14 class Texture { public: -- cgit v1.2.3 From 6b436b80a45c947d49ab5fbda515fb02877eefd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 19:35:56 +0200 Subject: GPU: Rename gpu_extensions to gpu_capabilities This makes more sense as this module has more to it than just GL extensions. --- source/blender/blenfont/intern/blf_glyph.c | 2 +- source/blender/blenkernel/intern/image_gpu.c | 2 +- source/blender/draw/engines/eevee/eevee_effects.c | 2 +- .../blender/draw/engines/eevee/eevee_lightcache.c | 2 +- .../blender/draw/engines/eevee/eevee_lightprobes.c | 2 +- .../blender/draw/engines/eevee/eevee_occlusion.c | 2 +- source/blender/draw/engines/eevee/eevee_render.c | 2 +- source/blender/draw/engines/eevee/eevee_shaders.c | 2 +- .../blender/draw/engines/eevee/eevee_subsurface.c | 2 +- source/blender/draw/engines/eevee/eevee_volumes.c | 2 +- .../draw/engines/workbench/workbench_opaque.c | 2 - .../draw/engines/workbench/workbench_transparent.c | 2 - .../blender/draw/intern/draw_cache_extract_mesh.c | 2 +- .../blender/draw/intern/draw_cache_impl_displist.c | 2 +- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/draw/intern/draw_manager_exec.c | 1 - source/blender/draw/intern/draw_manager_shader.c | 2 +- source/blender/editors/screen/screen_ops.c | 2 +- .../editors/sculpt_paint/paint_image_proj.c | 2 +- source/blender/editors/space_info/info_stats.c | 2 +- source/blender/gpu/CMakeLists.txt | 6 +- source/blender/gpu/GPU_capabilities.h | 55 ++++++++ source/blender/gpu/GPU_extensions.h | 60 -------- source/blender/gpu/intern/gpu_batch.cc | 1 - source/blender/gpu/intern/gpu_capabilities.cc | 151 +++++++++++++++++++++ .../blender/gpu/intern/gpu_capabilities_private.hh | 54 ++++++++ source/blender/gpu/intern/gpu_codegen.c | 2 +- source/blender/gpu/intern/gpu_extensions.cc | 151 --------------------- .../blender/gpu/intern/gpu_extensions_private.hh | 54 -------- source/blender/gpu/intern/gpu_framebuffer.cc | 2 +- source/blender/gpu/intern/gpu_shader.cc | 2 +- source/blender/gpu/intern/gpu_shader_builtin.c | 1 - source/blender/gpu/intern/gpu_state.cc | 1 - source/blender/gpu/intern/gpu_uniform_buffer.cc | 2 - source/blender/gpu/opengl/gl_backend.cc | 2 +- source/blender/gpu/opengl/gl_batch.cc | 2 - source/blender/gpu/opengl/gl_drawlist.cc | 2 +- source/blender/gpu/opengl/gl_framebuffer.cc | 2 +- source/blender/gpu/opengl/gl_shader.cc | 1 - source/blender/gpu/opengl/gl_state.cc | 2 +- source/blender/gpu/opengl/gl_texture.cc | 2 +- source/blender/gpu/opengl/gl_uniform_buffer.cc | 2 - source/blender/imbuf/intern/util_gpu.c | 2 +- source/blender/makesrna/intern/rna_render.c | 2 +- source/blender/makesrna/intern/rna_userdef.c | 2 +- source/blender/windowmanager/intern/wm_stereo.c | 2 +- 46 files changed, 292 insertions(+), 312 deletions(-) create mode 100644 source/blender/gpu/GPU_capabilities.h delete mode 100644 source/blender/gpu/GPU_extensions.h create mode 100644 source/blender/gpu/intern/gpu_capabilities.cc create mode 100644 source/blender/gpu/intern/gpu_capabilities_private.hh delete mode 100644 source/blender/gpu/intern/gpu_extensions.cc delete mode 100644 source/blender/gpu/intern/gpu_extensions_private.hh diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 773d3409905..8e74d5bba7c 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -46,7 +46,7 @@ #include "BLF_api.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_immediate.h" #include "blf_internal.h" diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c index 083d6c1d973..8b6bd47a0db 100644 --- a/source/blender/blenkernel/intern/image_gpu.c +++ b/source/blender/blenkernel/intern/image_gpu.c @@ -39,7 +39,7 @@ #include "BKE_image.h" #include "BKE_main.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_state.h" #include "GPU_texture.h" diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 2bd1a875371..3b2a3cc7c01 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -26,7 +26,7 @@ #include "BKE_global.h" /* for G.debug_value */ -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_platform.h" #include "GPU_state.h" #include "GPU_texture.h" diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 5de161a646b..5a676bf4004 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -41,8 +41,8 @@ #include "eevee_lightcache.h" #include "eevee_private.h" +#include "GPU_capabilities.h" #include "GPU_context.h" -#include "GPU_extensions.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 9f86958cef8..89e61ab939a 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -36,7 +36,7 @@ #include "BKE_object.h" #include "MEM_guardedalloc.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_material.h" #include "GPU_texture.h" #include "GPU_uniform_buffer.h" diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index b7b765d9c00..3c684c467a4 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -32,7 +32,7 @@ #include "eevee_private.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_platform.h" #include "GPU_state.h" diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 2351b06db98..504e4e1d336 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -38,7 +38,7 @@ #include "DEG_depsgraph_query.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_framebuffer.h" #include "GPU_state.h" diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index bbc5801b0f7..d4b1d421603 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -32,7 +32,7 @@ #include "MEM_guardedalloc.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_material.h" #include "GPU_shader.h" diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index 58b545be2f5..f9195e5861d 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -28,7 +28,7 @@ #include "DEG_depsgraph_query.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_material.h" #include "GPU_texture.h" diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 85c7c89934c..69b916244b5 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -44,7 +44,7 @@ #include "DEG_depsgraph_query.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_material.h" #include "GPU_texture.h" #include "eevee_private.h" diff --git a/source/blender/draw/engines/workbench/workbench_opaque.c b/source/blender/draw/engines/workbench/workbench_opaque.c index 738f4a67471..9fdefed019f 100644 --- a/source/blender/draw/engines/workbench/workbench_opaque.c +++ b/source/blender/draw/engines/workbench/workbench_opaque.c @@ -31,8 +31,6 @@ #include "DRW_render.h" -#include "GPU_extensions.h" - #include "workbench_engine.h" #include "workbench_private.h" diff --git a/source/blender/draw/engines/workbench/workbench_transparent.c b/source/blender/draw/engines/workbench/workbench_transparent.c index 5eff056846c..1c8575ddc12 100644 --- a/source/blender/draw/engines/workbench/workbench_transparent.c +++ b/source/blender/draw/engines/workbench/workbench_transparent.c @@ -35,8 +35,6 @@ #include "ED_view3d.h" -#include "GPU_extensions.h" - #include "workbench_engine.h" #include "workbench_private.h" diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index 9f4ae8fbfbf..cb716b3130a 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -59,7 +59,7 @@ #include "bmesh.h" #include "GPU_batch.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "DRW_render.h" diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index 2f7ce54aef4..42e410ad189 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -37,7 +37,7 @@ #include "BKE_displist_tangent.h" #include "GPU_batch.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "draw_cache_inline.h" diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 49780f59db3..8d69ed05fc6 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -64,7 +64,7 @@ #include "ED_space_api.h" #include "ED_view3d.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_framebuffer.h" #include "GPU_immediate.h" #include "GPU_matrix.h" diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 58464c0a15a..79d74e1f67d 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -29,7 +29,6 @@ #include "BKE_global.h" -#include "GPU_extensions.h" #include "GPU_platform.h" #include "GPU_shader.h" #include "GPU_state.h" diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 7602bbb39ac..7eeb5a2fb67 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -34,7 +34,7 @@ #include "DEG_depsgraph_query.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_material.h" #include "GPU_shader.h" diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6c3b47db155..b79447273d6 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -89,7 +89,7 @@ #include "UI_resources.h" #include "UI_view2d.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "screen_intern.h" /* own module include */ diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 456c1f61cb1..3886b78286b 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -90,7 +90,7 @@ #include "ED_view3d.h" #include "ED_view3d_offscreen.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_init_exit.h" #include "WM_api.h" diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 301e88b0904..3650fbdc9f8 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -64,7 +64,7 @@ #include "UI_resources.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #define MAX_INFO_NUM_LEN 16 diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 358bd045c2f..6fdd510ad28 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -59,11 +59,11 @@ set(SRC intern/gpu_batch_presets.c intern/gpu_batch_utils.c intern/gpu_buffers.c + intern/gpu_capabilities.cc intern/gpu_codegen.c intern/gpu_context.cc intern/gpu_debug.cc intern/gpu_drawlist.cc - intern/gpu_extensions.cc intern/gpu_framebuffer.cc intern/gpu_immediate.cc intern/gpu_immediate_util.c @@ -107,11 +107,11 @@ set(SRC GPU_batch_presets.h GPU_batch_utils.h GPU_buffers.h + GPU_capabilities.h GPU_common.h GPU_context.h GPU_debug.h GPU_drawlist.h - GPU_extensions.h GPU_framebuffer.h GPU_glew.h GPU_immediate.h @@ -134,10 +134,10 @@ set(SRC intern/gpu_backend.hh intern/gpu_batch_private.hh + intern/gpu_capabilities_private.hh intern/gpu_codegen.h intern/gpu_context_private.hh intern/gpu_drawlist_private.hh - intern/gpu_extensions_private.hh intern/gpu_framebuffer_private.hh intern/gpu_immediate_private.hh intern/gpu_index_buffer_private.hh diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h new file mode 100644 index 00000000000..b8a48735548 --- /dev/null +++ b/source/blender/gpu/GPU_capabilities.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * GPU Capabilities & workarounds + * This module expose the reported implementation limits & enabled + * workaround for drivers that needs specific codepaths. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int GPU_max_texture_size(void); +int GPU_max_texture_layers(void); +int GPU_max_textures(void); +int GPU_max_textures_vert(void); +int GPU_max_textures_geom(void); +int GPU_max_textures_frag(void); + +int GPU_texture_size_with_limit(int res); + +bool GPU_mip_render_workaround(void); +bool GPU_depth_blitting_workaround(void); +bool GPU_use_main_context_workaround(void); +bool GPU_crappy_amd_driver(void); + +bool GPU_mem_stats_supported(void); +void GPU_mem_stats_get(int *totalmem, int *freemem); + +bool GPU_stereo_quadbuffer_support(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h deleted file mode 100644 index 357e867775a..00000000000 --- a/source/blender/gpu/GPU_extensions.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/* GPU extensions support */ - -int GPU_max_texture_size(void); -int GPU_max_texture_3d_size(void); -int GPU_max_texture_layers(void); -int GPU_max_textures(void); -int GPU_max_textures_vert(void); -int GPU_max_textures_geom(void); -int GPU_max_textures_frag(void); -float GPU_max_texture_anisotropy(void); -int GPU_max_color_texture_samples(void); -int GPU_max_cube_map_size(void); -int GPU_max_ubo_binds(void); -int GPU_max_ubo_size(void); -bool GPU_mip_render_workaround(void); -bool GPU_depth_blitting_workaround(void); -bool GPU_use_main_context_workaround(void); -bool GPU_crappy_amd_driver(void); - -int GPU_texture_size_with_limit(int res); - -bool GPU_mem_stats_supported(void); -void GPU_mem_stats_get(int *totalmem, int *freemem); - -void GPU_code_generate_glsl_lib(void); - -bool GPU_stereo_quadbuffer_support(void); - -#ifdef __cplusplus -} -#endif diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index 34655c48ca4..d6f4f223a83 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -30,7 +30,6 @@ #include "GPU_batch.h" #include "GPU_batch_presets.h" -#include "GPU_extensions.h" #include "GPU_matrix.h" #include "GPU_platform.h" #include "GPU_shader.h" diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc new file mode 100644 index 00000000000..83b9597abbb --- /dev/null +++ b/source/blender/gpu/intern/gpu_capabilities.cc @@ -0,0 +1,151 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * Wrap OpenGL features such as textures, shaders and GLSL + * with checks for drivers and GPU support. + */ + +#include "DNA_userdef_types.h" + +#include "GPU_capabilities.h" + +#include "gpu_capabilities_private.hh" + +#include "gl_backend.hh" /* TODO remove */ + +namespace blender::gpu { + +GPUCapabilities GCaps; + +} + +using namespace blender::gpu; + +/* -------------------------------------------------------------------- */ +/** \name Capabilities + * \{ */ + +int GPU_max_texture_size(void) +{ + return GCaps.max_texture_size; +} + +int GPU_texture_size_with_limit(int res) +{ + int size = GPU_max_texture_size(); + int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size; + return min_ii(reslimit, res); +} + +int GPU_max_texture_layers(void) +{ + return GCaps.max_texture_layers; +} + +int GPU_max_textures_vert(void) +{ + return GCaps.max_textures_vert; +} + +int GPU_max_textures_geom(void) +{ + return GCaps.max_textures_geom; +} + +int GPU_max_textures_frag(void) +{ + return GCaps.max_textures_frag; +} + +int GPU_max_textures(void) +{ + return GCaps.max_textures; +} + +bool GPU_mip_render_workaround(void) +{ + return GCaps.mip_render_workaround; +} + +bool GPU_depth_blitting_workaround(void) +{ + return GCaps.depth_blitting_workaround; +} + +bool GPU_use_main_context_workaround(void) +{ + return GCaps.use_main_context_workaround; +} + +bool GPU_crappy_amd_driver(void) +{ + /* Currently are the same drivers with the `unused_fb_slot` problem. */ + return GCaps.broken_amd_driver; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Memory statistics + * \{ */ + +bool GPU_mem_stats_supported(void) +{ +#ifndef GPU_STANDALONE + return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo); +#else + return false; +#endif +} + +void GPU_mem_stats_get(int *totalmem, int *freemem) +{ + /* TODO(merwin): use Apple's platform API to get this info */ + + if (GLEW_NVX_gpu_memory_info) { + /* returned value in Kb */ + glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem); + + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, freemem); + } + else if (GLEW_ATI_meminfo) { + int stats[4]; + + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats); + *freemem = stats[0]; + *totalmem = 0; + } + else { + *totalmem = 0; + *freemem = 0; + } +} + +/* Return support for the active context + window. */ +bool GPU_stereo_quadbuffer_support(void) +{ + GLboolean stereo = GL_FALSE; + glGetBooleanv(GL_STEREO, &stereo); + return stereo == GL_TRUE; +} + +/** \} */ diff --git a/source/blender/gpu/intern/gpu_capabilities_private.hh b/source/blender/gpu/intern/gpu_capabilities_private.hh new file mode 100644 index 00000000000..ec387555bfe --- /dev/null +++ b/source/blender/gpu/intern/gpu_capabilities_private.hh @@ -0,0 +1,54 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "GPU_platform.h" + +namespace blender::gpu { + +/** + * This includes both hardware capabilities & workarounds. + * Try to limit these to the implementation codebase (i.e.: gpu/opengl/). + * Only add workarounds here if they are common to all implementation or + * if you need access to it outside of the GPU module. + * Same goes for capabilities (i.e.: texture size) + **/ +struct GPUCapabilities { + int max_texture_size = 0; + int max_texture_layers = 0; + int max_textures = 0; + int max_textures_vert = 0; + int max_textures_geom = 0; + int max_textures_frag = 0; + + /* OpenGL related workarounds. */ + bool mip_render_workaround = false; + bool depth_blitting_workaround = false; + bool use_main_context_workaround = false; + bool broken_amd_driver = false; +}; + +extern GPUCapabilities GCaps; + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index d67ce0be310..f10fd8cd137 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -40,7 +40,7 @@ #include "BKE_material.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_uniform_buffer.h" diff --git a/source/blender/gpu/intern/gpu_extensions.cc b/source/blender/gpu/intern/gpu_extensions.cc deleted file mode 100644 index e06828bf994..00000000000 --- a/source/blender/gpu/intern/gpu_extensions.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - * - * Wrap OpenGL features such as textures, shaders and GLSL - * with checks for drivers and GPU support. - */ - -#include "DNA_userdef_types.h" - -#include "GPU_extensions.h" - -#include "gpu_extensions_private.hh" - -#include "gl_backend.hh" /* TODO remove */ - -namespace blender::gpu { - -GPUCapabilities GCaps; - -} - -using namespace blender::gpu; - -/* -------------------------------------------------------------------- */ -/** \name Capabilities - * \{ */ - -int GPU_max_texture_size(void) -{ - return GCaps.max_texture_size; -} - -int GPU_texture_size_with_limit(int res) -{ - int size = GPU_max_texture_size(); - int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size; - return min_ii(reslimit, res); -} - -int GPU_max_texture_layers(void) -{ - return GCaps.max_texture_layers; -} - -int GPU_max_textures_vert(void) -{ - return GCaps.max_textures_vert; -} - -int GPU_max_textures_geom(void) -{ - return GCaps.max_textures_geom; -} - -int GPU_max_textures_frag(void) -{ - return GCaps.max_textures_frag; -} - -int GPU_max_textures(void) -{ - return GCaps.max_textures; -} - -bool GPU_mip_render_workaround(void) -{ - return GCaps.mip_render_workaround; -} - -bool GPU_depth_blitting_workaround(void) -{ - return GCaps.depth_blitting_workaround; -} - -bool GPU_use_main_context_workaround(void) -{ - return GCaps.use_main_context_workaround; -} - -bool GPU_crappy_amd_driver(void) -{ - /* Currently are the same drivers with the `unused_fb_slot` problem. */ - return GCaps.broken_amd_driver; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Memory statistics - * \{ */ - -bool GPU_mem_stats_supported(void) -{ -#ifndef GPU_STANDALONE - return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo); -#else - return false; -#endif -} - -void GPU_mem_stats_get(int *totalmem, int *freemem) -{ - /* TODO(merwin): use Apple's platform API to get this info */ - - if (GLEW_NVX_gpu_memory_info) { - /* returned value in Kb */ - glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem); - - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, freemem); - } - else if (GLEW_ATI_meminfo) { - int stats[4]; - - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats); - *freemem = stats[0]; - *totalmem = 0; - } - else { - *totalmem = 0; - *freemem = 0; - } -} - -/* Return support for the active context + window. */ -bool GPU_stereo_quadbuffer_support(void) -{ - GLboolean stereo = GL_FALSE; - glGetBooleanv(GL_STEREO, &stereo); - return stereo == GL_TRUE; -} - -/** \} */ diff --git a/source/blender/gpu/intern/gpu_extensions_private.hh b/source/blender/gpu/intern/gpu_extensions_private.hh deleted file mode 100644 index ec387555bfe..00000000000 --- a/source/blender/gpu/intern/gpu_extensions_private.hh +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright 2020, Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - */ - -#pragma once - -#include "GPU_platform.h" - -namespace blender::gpu { - -/** - * This includes both hardware capabilities & workarounds. - * Try to limit these to the implementation codebase (i.e.: gpu/opengl/). - * Only add workarounds here if they are common to all implementation or - * if you need access to it outside of the GPU module. - * Same goes for capabilities (i.e.: texture size) - **/ -struct GPUCapabilities { - int max_texture_size = 0; - int max_texture_layers = 0; - int max_textures = 0; - int max_textures_vert = 0; - int max_textures_geom = 0; - int max_textures_frag = 0; - - /* OpenGL related workarounds. */ - bool mip_render_workaround = false; - bool depth_blitting_workaround = false; - bool use_main_context_workaround = false; - bool broken_amd_driver = false; -}; - -extern GPUCapabilities GCaps; - -} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index 44994c2cabf..a0b05df583a 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -28,7 +28,7 @@ #include "BLI_utildefines.h" #include "GPU_batch.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index fd01160cff6..38acc773c49 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -36,7 +36,7 @@ #include "DNA_space_types.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_matrix.h" #include "GPU_platform.h" #include "GPU_shader.h" diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c index ed95a236da5..f528e67a80a 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.c +++ b/source/blender/gpu/intern/gpu_shader_builtin.c @@ -35,7 +35,6 @@ #include "DNA_space_types.h" -#include "GPU_extensions.h" #include "GPU_matrix.h" #include "GPU_platform.h" #include "GPU_shader.h" diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index 478fd639cdd..90c6efad2e8 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -30,7 +30,6 @@ #include "BKE_global.h" -#include "GPU_extensions.h" #include "GPU_glew.h" #include "GPU_state.h" diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc index 24e5b452e03..4926a5fa2dc 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer.cc +++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc @@ -32,8 +32,6 @@ #include "GPU_material.h" -#include "GPU_extensions.h" - #include "GPU_uniform_buffer.h" #include "gpu_uniform_buffer_private.hh" diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 317416ca355..fedc03f5787 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -23,7 +23,7 @@ #include "BKE_global.h" -#include "gpu_extensions_private.hh" +#include "gpu_capabilities_private.hh" #include "gpu_platform_private.hh" #include "glew-mx.h" diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index f4ad7194ce1..c28d3e33e65 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -29,8 +29,6 @@ #include "glew-mx.h" -#include "GPU_extensions.h" - #include "gpu_batch_private.hh" #include "gpu_shader_private.hh" diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index 0768f7502ce..7cec6da7541 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -27,7 +27,7 @@ #include "BLI_assert.h" #include "GPU_batch.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "glew-mx.h" diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index 506a945d9d4..d0644b356ac 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -23,7 +23,7 @@ #include "BKE_global.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "gl_backend.hh" #include "gl_framebuffer.hh" diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 76e20de1e51..a303229fc3c 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -25,7 +25,6 @@ #include "BLI_string.h" -#include "GPU_extensions.h" #include "GPU_platform.h" #include "gl_backend.hh" diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index dc6d475d39f..b43b01aed4f 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -25,7 +25,7 @@ #include "BLI_math_base.h" #include "BLI_math_bits.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "glew-mx.h" diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 4c3d34a759f..2934865f4d1 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -25,7 +25,7 @@ #include "DNA_userdef_types.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_framebuffer.h" #include "GPU_platform.h" diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc index 82b7341d145..8c8fac44fdc 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.cc +++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc @@ -25,8 +25,6 @@ #include "BLI_string.h" -#include "GPU_extensions.h" - #include "gpu_backend.hh" #include "gpu_context_private.hh" diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 73532a1825e..2826bd63cc1 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -30,7 +30,7 @@ #include "BKE_global.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_texture.h" #include "IMB_colormanagement.h" diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 5b77632be79..35563ad143e 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -100,7 +100,7 @@ const EnumPropertyItem rna_enum_bake_pass_type_items[] = { # include "BKE_context.h" # include "BKE_report.h" -# include "GPU_extensions.h" +# include "GPU_capabilities.h" # include "GPU_shader.h" # include "IMB_colormanagement.h" diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 6682cd743eb..7b777aa642a 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -188,7 +188,7 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = { # include "DEG_depsgraph.h" -# include "GPU_extensions.h" +# include "GPU_capabilities.h" # include "GPU_select.h" # include "GPU_texture.h" diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index 9667ed5b631..ab6da2cc947 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -40,7 +40,7 @@ #include "ED_screen.h" -#include "GPU_extensions.h" +#include "GPU_capabilities.h" #include "GPU_immediate.h" #include "GPU_texture.h" #include "GPU_viewport.h" -- cgit v1.2.3 From d2911124f42fd58d42b1b734c852980d5dbde401 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 7 Sep 2020 19:36:24 +0200 Subject: BLI: improve exception safety of VectorSet For more information see rB2aff45146f1464ba8899368ad004522cb6a1a98c. --- source/blender/blenlib/BLI_array.hh | 4 + source/blender/blenlib/BLI_vector_set.hh | 114 +++++++++++++-------- source/blender/blenlib/BLI_vector_set_slots.hh | 12 --- .../blender/blenlib/tests/BLI_vector_set_test.cc | 71 +++++++++++++ 4 files changed, 144 insertions(+), 57 deletions(-) diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh index dddf4f64ff5..8a7dcb7ffaa 100644 --- a/source/blender/blenlib/BLI_array.hh +++ b/source/blender/blenlib/BLI_array.hh @@ -353,6 +353,10 @@ class Array { { return allocator_; } + const Allocator &allocator() const + { + return allocator_; + } /** * Get the value of the InlineBufferCapacity template argument. This is the number of elements diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh index 9d7c61f9e3b..c9773dc599d 100644 --- a/source/blender/blenlib/BLI_vector_set.hh +++ b/source/blender/blenlib/BLI_vector_set.hh @@ -143,7 +143,7 @@ class VectorSet { * no keys are removed. The first set->size() elements in this array are initialized. The * capacity of the array is usable_slots_. */ - Key *keys_; + Key *keys_ = nullptr; /** Iterate over a slot index sequence for a given hash. */ #define VECTOR_SET_SLOT_PROBING_BEGIN(HASH, R_SLOT) \ @@ -157,22 +157,31 @@ class VectorSet { * necessary to avoid a high cost when no elements are added at all. An optimized grow operation * is performed on the first insertion. */ - VectorSet() + VectorSet(Allocator allocator = {}) noexcept : removed_slots_(0), occupied_and_removed_slots_(0), usable_slots_(0), slot_mask_(0), - slots_(1), + slots_(1, allocator), keys_(nullptr) { } + VectorSet(NoExceptConstructor, Allocator allocator = {}) : VectorSet(allocator) + { + } + + VectorSet(Span keys, Allocator allocator = {}) : VectorSet(NoExceptConstructor(), allocator) + { + this->add_multiple(keys); + } + /** * Construct a vector set that contains the given keys. Duplicates will be removed automatically. */ - VectorSet(const std::initializer_list &keys) : VectorSet() + VectorSet(const std::initializer_list &keys, Allocator allocator = {}) + : VectorSet(Span(keys), allocator) { - this->add_multiple(keys); } ~VectorSet() @@ -183,15 +192,23 @@ class VectorSet { } } - VectorSet(const VectorSet &other) - : removed_slots_(other.removed_slots_), - occupied_and_removed_slots_(other.occupied_and_removed_slots_), - usable_slots_(other.usable_slots_), - slot_mask_(other.slot_mask_), - slots_(other.slots_) + VectorSet(const VectorSet &other) : slots_(other.slots_) { - keys_ = this->allocate_keys_array(usable_slots_); - uninitialized_copy_n(other.keys_, other.size(), keys_); + keys_ = this->allocate_keys_array(other.usable_slots_); + try { + uninitialized_copy_n(other.keys_, other.size(), keys_); + } + catch (...) { + this->deallocate_keys_array(keys_); + throw; + } + + removed_slots_ = other.removed_slots_; + occupied_and_removed_slots_ = other.occupied_and_removed_slots_; + usable_slots_ = other.usable_slots_; + slot_mask_ = other.slot_mask_; + hash_ = other.hash_; + is_equal_ = other.is_equal_; } VectorSet(VectorSet &&other) noexcept @@ -212,26 +229,12 @@ class VectorSet { VectorSet &operator=(const VectorSet &other) { - if (this == &other) { - return *this; - } - - this->~VectorSet(); - new (this) VectorSet(other); - - return *this; + return copy_assign_container(*this, other); } VectorSet &operator=(VectorSet &&other) { - if (this == &other) { - return *this; - } - - this->~VectorSet(); - new (this) VectorSet(std::move(other)); - - return *this; + return move_assign_container(*this, std::move(other)); } /** @@ -490,32 +493,48 @@ class VectorSet { /* Optimize the case when the set was empty beforehand. We can avoid some copies here. */ if (this->size() == 0) { - slots_.~Array(); - new (&slots_) SlotArray(total_slots); + try { + slots_.reinitialize(total_slots); + keys_ = this->allocate_keys_array(usable_slots); + } + catch (...) { + this->noexcept_reset(); + throw; + } removed_slots_ = 0; occupied_and_removed_slots_ = 0; usable_slots_ = usable_slots; slot_mask_ = new_slot_mask; - keys_ = this->allocate_keys_array(usable_slots); return; } SlotArray new_slots(total_slots); - for (Slot &slot : slots_) { - if (slot.is_occupied()) { - this->add_after_grow_and_destruct_old(slot, new_slots, new_slot_mask); + try { + for (Slot &slot : slots_) { + if (slot.is_occupied()) { + this->add_after_grow(slot, new_slots, new_slot_mask); + slot.remove(); + } } + slots_ = std::move(new_slots); + } + catch (...) { + this->noexcept_reset(); + throw; } Key *new_keys = this->allocate_keys_array(usable_slots); - uninitialized_relocate_n(keys_, this->size(), new_keys); + try { + uninitialized_relocate_n(keys_, this->size(), new_keys); + } + catch (...) { + this->deallocate_keys_array(new_keys); + this->noexcept_reset(); + throw; + } this->deallocate_keys_array(keys_); - /* All occupied slots have been destructed already and empty/removed slots are assumed to be - * trivially destructible. */ - slots_.clear_without_destruct(); - slots_ = std::move(new_slots); keys_ = new_keys; occupied_and_removed_slots_ -= removed_slots_; usable_slots_ = usable_slots; @@ -523,9 +542,7 @@ class VectorSet { slot_mask_ = new_slot_mask; } - void add_after_grow_and_destruct_old(Slot &old_slot, - SlotArray &new_slots, - const uint64_t new_slot_mask) + void add_after_grow(Slot &old_slot, SlotArray &new_slots, const uint64_t new_slot_mask) { const Key &key = keys_[old_slot.index()]; const uint64_t hash = old_slot.get_hash(key, Hash()); @@ -533,13 +550,20 @@ class VectorSet { SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) { Slot &slot = new_slots[slot_index]; if (slot.is_empty()) { - slot.relocate_occupied_here(old_slot, hash); + slot.occupy(old_slot.index(), hash); return; } } SLOT_PROBING_END(); } + void noexcept_reset() noexcept + { + Allocator allocator = slots_.allocator(); + this->~VectorSet(); + new (this) VectorSet(NoExceptConstructor(), allocator); + } + template bool contains__impl(const ForwardKey &key, const uint64_t hash) const { @@ -580,8 +604,8 @@ class VectorSet { if (slot.is_empty()) { int64_t index = this->size(); new (keys_ + index) Key(std::forward(key)); - occupied_and_removed_slots_++; slot.occupy(index, hash); + occupied_and_removed_slots_++; return true; } if (slot.contains(key, is_equal_, hash, keys_)) { diff --git a/source/blender/blenlib/BLI_vector_set_slots.hh b/source/blender/blenlib/BLI_vector_set_slots.hh index 0e75c4690a4..b79341ed744 100644 --- a/source/blender/blenlib/BLI_vector_set_slots.hh +++ b/source/blender/blenlib/BLI_vector_set_slots.hh @@ -96,18 +96,6 @@ template class SimpleVectorSetSlot { return false; } - /** - * Move the other slot into this slot and destruct it. We do destruction here, because this way - * we can avoid a comparison with the state, since we know the slot is occupied. For this - * specific slot implementation, this does not make a difference. - */ - void relocate_occupied_here(SimpleVectorSetSlot &other, uint64_t UNUSED(hash)) - { - BLI_assert(!this->is_occupied()); - BLI_assert(other.is_occupied()); - state_ = other.state_; - } - /** * Change the state of this slot from empty/removed to occupied. The hash can be used by other * slot implementations. diff --git a/source/blender/blenlib/tests/BLI_vector_set_test.cc b/source/blender/blenlib/tests/BLI_vector_set_test.cc index 8f3db8d8403..320cb15f450 100644 --- a/source/blender/blenlib/tests/BLI_vector_set_test.cc +++ b/source/blender/blenlib/tests/BLI_vector_set_test.cc @@ -1,5 +1,6 @@ /* Apache License, Version 2.0 */ +#include "BLI_exception_safety_test_utils.hh" #include "BLI_strict_flags.h" #include "BLI_vector_set.hh" #include "testing/testing.h" @@ -161,4 +162,74 @@ TEST(vector_set, Remove) EXPECT_FALSE(set.contains(5)); } +TEST(vector_set, SpanConstructorExceptions) +{ + std::array array = {1, 2, 3, 4, 5}; + array[3].throw_during_copy = true; + Span span = array; + + EXPECT_ANY_THROW({ VectorSet set(span); }); +} + +TEST(vector_set, CopyConstructorExceptions) +{ + VectorSet set = {1, 2, 3, 4, 5}; + set[3].throw_during_copy = true; + + EXPECT_ANY_THROW({ VectorSet set_copy(set); }); +} + +TEST(vector_set, MoveConstructorExceptions) +{ + VectorSet set = {1, 2, 3, 4, 5}; + set[3].throw_during_copy = true; + set[3].throw_during_move = true; + /* Currently never throws on move, because values are separately allocated. */ + VectorSet set_moved(std::move(set)); + EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */ + set.add_multiple({4, 5, 6, 7, 8}); + EXPECT_EQ(set.size(), 5); +} + +TEST(vector_set, AddNewExceptions) +{ + VectorSet set; + ExceptionThrower value; + value.throw_during_copy = true; + EXPECT_ANY_THROW({ set.add_new(value); }); + EXPECT_EQ(set.size(), 0); + EXPECT_ANY_THROW({ set.add_new(value); }); + EXPECT_EQ(set.size(), 0); +} + +TEST(vector_set, AddExceptions) +{ + VectorSet set; + ExceptionThrower value; + value.throw_during_copy = true; + EXPECT_ANY_THROW({ set.add(value); }); + EXPECT_EQ(set.size(), 0); + EXPECT_ANY_THROW({ set.add(value); }); + EXPECT_EQ(set.size(), 0); +} + +TEST(vector_set, ReserveExceptions) +{ + VectorSet set; + set.add_multiple({1, 2, 3, 4, 5}); + set[2].throw_during_move = true; + EXPECT_ANY_THROW({ set.reserve(100); }); +} + +TEST(vector_set, PopExceptions) +{ + VectorSet set = {1, 2, 3}; + set.as_span().last().throw_during_move = true; + EXPECT_EQ(set.size(), 3); + EXPECT_ANY_THROW({ set.pop(); }); /* NOLINT: bugprone-throw-keyword-missing */ + EXPECT_EQ(set.size(), 3); + set.add(10); + EXPECT_EQ(set.size(), 4); +} + } // namespace blender::tests -- cgit v1.2.3 From c5c6b5ddb31c8a79667d6dcd689808efd3dadd8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 19:52:22 +0200 Subject: GPUCapabilities: Isolate GL_STEREO to GLContext This is part of the Vulkan task T68990 This is a simple cleanup. --- source/blender/gpu/intern/gpu_capabilities.cc | 4 +--- source/blender/gpu/opengl/gl_context.cc | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc index 83b9597abbb..71bf479b4a8 100644 --- a/source/blender/gpu/intern/gpu_capabilities.cc +++ b/source/blender/gpu/intern/gpu_capabilities.cc @@ -143,9 +143,7 @@ void GPU_mem_stats_get(int *totalmem, int *freemem) /* Return support for the active context + window. */ bool GPU_stereo_quadbuffer_support(void) { - GLboolean stereo = GL_FALSE; - glGetBooleanv(GL_STEREO, &stereo); - return stereo == GL_TRUE; + return GPU_context_active_get()->front_right != nullptr; } /** \} */ diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index 1495e665aa8..ec6cc9e6159 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -80,8 +80,8 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list front_left = new GLFrameBuffer("front_left", this, GL_FRONT_LEFT, 0, w, h); back_left = new GLFrameBuffer("back_left", this, GL_BACK_LEFT, 0, w, h); } - /* TODO(fclem) enable is supported. */ - const bool supports_stereo_quad_buffer = false; + GLboolean supports_stereo_quad_buffer = GL_FALSE; + glGetBooleanv(GL_STEREO, &supports_stereo_quad_buffer); if (supports_stereo_quad_buffer) { front_right = new GLFrameBuffer("front_right", this, GL_FRONT_RIGHT, 0, w, h); back_right = new GLFrameBuffer("back_right", this, GL_BACK_RIGHT, 0, w, h); -- cgit v1.2.3 From 58353834f441b8b4ca91dcd4ec94ac49bbbf5ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 19:53:48 +0200 Subject: GPUCapabilities: Isolate GL memory statistics This is part of the Vulkan task T68990 This is a simple cleanup. --- source/blender/gpu/intern/gpu_capabilities.cc | 30 +++------------------- .../blender/gpu/intern/gpu_capabilities_private.hh | 3 ++- source/blender/gpu/intern/gpu_context_private.hh | 1 + source/blender/gpu/opengl/gl_backend.cc | 1 + source/blender/gpu/opengl/gl_context.cc | 27 +++++++++++++++++++ source/blender/gpu/opengl/gl_context.hh | 1 + 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc index 71bf479b4a8..0ee25ea2569 100644 --- a/source/blender/gpu/intern/gpu_capabilities.cc +++ b/source/blender/gpu/intern/gpu_capabilities.cc @@ -28,9 +28,9 @@ #include "GPU_capabilities.h" -#include "gpu_capabilities_private.hh" +#include "gpu_context_private.hh" -#include "gl_backend.hh" /* TODO remove */ +#include "gpu_capabilities_private.hh" namespace blender::gpu { @@ -110,34 +110,12 @@ bool GPU_crappy_amd_driver(void) bool GPU_mem_stats_supported(void) { -#ifndef GPU_STANDALONE - return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo); -#else - return false; -#endif + return GCaps.mem_stats_support; } void GPU_mem_stats_get(int *totalmem, int *freemem) { - /* TODO(merwin): use Apple's platform API to get this info */ - - if (GLEW_NVX_gpu_memory_info) { - /* returned value in Kb */ - glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem); - - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, freemem); - } - else if (GLEW_ATI_meminfo) { - int stats[4]; - - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats); - *freemem = stats[0]; - *totalmem = 0; - } - else { - *totalmem = 0; - *freemem = 0; - } + GPU_context_active_get()->memory_statistics_get(totalmem, freemem); } /* Return support for the active context + window. */ diff --git a/source/blender/gpu/intern/gpu_capabilities_private.hh b/source/blender/gpu/intern/gpu_capabilities_private.hh index ec387555bfe..a51525fa932 100644 --- a/source/blender/gpu/intern/gpu_capabilities_private.hh +++ b/source/blender/gpu/intern/gpu_capabilities_private.hh @@ -41,12 +41,13 @@ struct GPUCapabilities { int max_textures_vert = 0; int max_textures_geom = 0; int max_textures_frag = 0; - + bool mem_stats_support = false; /* OpenGL related workarounds. */ bool mip_render_workaround = false; bool depth_blitting_workaround = false; bool use_main_context_workaround = false; bool broken_amd_driver = false; + /* Vulkan related workarounds. */ }; extern GPUCapabilities GCaps; diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 20e57c405ba..5643eec1aa6 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -76,6 +76,7 @@ struct GPUContext { virtual void activate(void) = 0; virtual void deactivate(void) = 0; + virtual void memory_statistics_get(int *total_mem, int *free_mem) = 0; bool is_active_on_thread(void); diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index fedc03f5787..3dfe0e1e412 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -339,6 +339,7 @@ void GLBackend::capabilities_init(void) glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_vert); glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_geom); glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GCaps.max_textures); + GCaps.mem_stats_support = GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo; /* GL specific capabilities. */ glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GLContext::max_texture_3d_size); glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size); diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index ec6cc9e6159..ecf74a1993d 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -277,3 +277,30 @@ void GLContext::vao_cache_unregister(GLVaoCache *cache) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Memory statistics + * \{ */ + +void GLContext::memory_statistics_get(int *r_total_mem, int *r_free_mem) +{ + /* TODO(merwin): use Apple's platform API to get this info. */ + if (GLEW_NVX_gpu_memory_info) { + /* Teturned value in Kb. */ + glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, r_total_mem); + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, r_free_mem); + } + else if (GLEW_ATI_meminfo) { + int stats[4]; + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats); + + *r_total_mem = 0; + *r_free_mem = stats[0]; /* Total memory free in the pool. */ + } + else { + *r_total_mem = 0; + *r_free_mem = 0; + } +} + +/** \} */ diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index e2ae8bf24b2..06e59724f4a 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -97,6 +97,7 @@ class GLContext : public GPUContext { void activate(void) override; void deactivate(void) override; + void memory_statistics_get(int *total_mem, int *free_mem) override; static inline GLStateManager *state_manager_active_get() { -- cgit v1.2.3 From 19f56cfe6c59e3a54aaf7499fd9072a8790171b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 20:08:25 +0200 Subject: Cleanup: GLBackend: Move buf_free and tex_free to GLContext This makes it easier to follow. Also removes the GL related functions inside gpu_context.cc. --- source/blender/gpu/intern/gpu_context.cc | 52 ------------------------ source/blender/gpu/intern/gpu_context_private.hh | 13 ------ source/blender/gpu/opengl/gl_backend.hh | 11 ++--- source/blender/gpu/opengl/gl_context.cc | 10 +++-- source/blender/gpu/opengl/gl_context.hh | 12 ++++-- source/blender/gpu/opengl/gl_drawlist.cc | 5 +-- source/blender/gpu/opengl/gl_index_buffer.cc | 4 +- source/blender/gpu/opengl/gl_texture.cc | 2 +- source/blender/gpu/opengl/gl_uniform_buffer.cc | 2 +- source/blender/gpu/opengl/gl_vertex_buffer.cc | 4 +- 10 files changed, 24 insertions(+), 91 deletions(-) diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 85e7dffe3e7..8ebd49a658e 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -126,58 +126,6 @@ GPUContext *GPU_context_active_get(void) return active_ctx; } -GLuint GPU_vao_alloc(void) -{ - GLuint new_vao_id = 0; - glGenVertexArrays(1, &new_vao_id); - return new_vao_id; -} - -GLuint GPU_fbo_alloc(void) -{ - GLuint new_fbo_id = 0; - glGenFramebuffers(1, &new_fbo_id); - return new_fbo_id; -} - -GLuint GPU_buf_alloc(void) -{ - GLuint new_buffer_id = 0; - glGenBuffers(1, &new_buffer_id); - return new_buffer_id; -} - -GLuint GPU_tex_alloc(void) -{ - GLuint new_texture_id = 0; - glGenTextures(1, &new_texture_id); - return new_texture_id; -} - -void GPU_vao_free(GLuint vao_id, GPUContext *ctx) -{ - static_cast(ctx)->vao_free(vao_id); -} - -void GPU_fbo_free(GLuint fbo_id, GPUContext *ctx) -{ - static_cast(ctx)->fbo_free(fbo_id); -} - -void GPU_buf_free(GLuint buf_id) -{ - /* TODO avoid using backend */ - GPUBackend *backend = GPUBackend::get(); - static_cast(backend)->buf_free(buf_id); -} - -void GPU_tex_free(GLuint tex_id) -{ - /* TODO avoid using backend */ - GPUBackend *backend = GPUBackend::get(); - static_cast(backend)->tex_free(tex_id); -} - struct GPUMatrixState *gpu_context_active_matrix_state_get() { BLI_assert(active_ctx); diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 5643eec1aa6..3d92b4eb587 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -83,19 +83,6 @@ struct GPUContext { MEM_CXX_CLASS_ALLOC_FUNCS("GPUContext") }; -/* These require a OpenGL ctx bound. */ -GLuint GPU_buf_alloc(void); -GLuint GPU_tex_alloc(void); -GLuint GPU_vao_alloc(void); -GLuint GPU_fbo_alloc(void); - -/* These can be called any threads even without OpenGL ctx. */ -void GPU_buf_free(GLuint buf_id); -void GPU_tex_free(GLuint tex_id); -/* These two need the ctx the id was created with. */ -void GPU_vao_free(GLuint vao_id, GPUContext *ctx); -void GPU_fbo_free(GLuint fbo_id, GPUContext *ctx); - void gpu_context_active_framebuffer_set(GPUContext *ctx, struct GPUFrameBuffer *fb); struct GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx); diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index 25f3ff38d8b..0c759d2cd62 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -115,15 +115,10 @@ class GLBackend : public GPUBackend { return new GLVertBuf(); }; - /* TODO remove */ - void buf_free(GLuint buf_id); - void tex_free(GLuint tex_id); - void orphans_add(Vector &orphan_list, std::mutex &list_mutex, unsigned int id) + GLSharedOrphanLists &shared_orphan_list_get(void) { - list_mutex.lock(); - orphan_list.append(id); - list_mutex.unlock(); - } + return shared_orphan_list_; + }; private: static void platform_init(void); diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index ecf74a1993d..5633d28023a 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -230,25 +230,27 @@ void GLContext::fbo_free(GLuint fbo_id) } } -void GLBackend::buf_free(GLuint buf_id) +void GLContext::buf_free(GLuint buf_id) { /* Any context can free. */ if (GPU_context_active_get()) { glDeleteBuffers(1, &buf_id); } else { - orphans_add(shared_orphan_list_.buffers, shared_orphan_list_.lists_mutex, buf_id); + GLSharedOrphanLists &orphan_list = GLBackend::get()->shared_orphan_list_get(); + orphans_add(orphan_list.buffers, orphan_list.lists_mutex, buf_id); } } -void GLBackend::tex_free(GLuint tex_id) +void GLContext::tex_free(GLuint tex_id) { /* Any context can free. */ if (GPU_context_active_get()) { glDeleteTextures(1, &tex_id); } else { - orphans_add(shared_orphan_list_.textures, shared_orphan_list_.lists_mutex, tex_id); + GLSharedOrphanLists &orphan_list = GLBackend::get()->shared_orphan_list_get(); + orphans_add(orphan_list.textures, orphan_list.lists_mutex, tex_id); } } diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index 06e59724f4a..f05029c7075 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -105,13 +105,17 @@ class GLContext : public GPUContext { return static_cast(ctx->state_manager); }; + /* These need to be called with the context the id was created with. */ + void vao_free(GLuint vao_id); + void fbo_free(GLuint fbo_id); + /* These can be called by any threads even without OpenGL ctx. Deletion will be delayed. */ + static void buf_free(GLuint buf_id); + static void tex_free(GLuint tex_id); + /* TODO(fclem) these needs to become private. */ public: - void orphans_add(Vector &orphan_list, std::mutex &list_mutex, GLuint id); + static void orphans_add(Vector &orphan_list, std::mutex &list_mutex, GLuint id); void orphans_clear(void); - - void vao_free(GLuint vao_id); - void fbo_free(GLuint fbo_id); void vao_cache_register(GLVaoCache *cache); void vao_cache_unregister(GLVaoCache *cache); }; diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index 7cec6da7541..039ef18ad72 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -88,10 +88,7 @@ GLDrawList::GLDrawList(int length) GLDrawList::~GLDrawList() { - /* TODO This ... */ - static_cast(GPUBackend::get())->buf_free(buffer_id_); - /* ... should be this. */ - // context_->buf_free(buffer_id_) + GLContext::buf_free(buffer_id_); } void GLDrawList::init(void) diff --git a/source/blender/gpu/opengl/gl_index_buffer.cc b/source/blender/gpu/opengl/gl_index_buffer.cc index 03a9607a00b..d68953e6daa 100644 --- a/source/blender/gpu/opengl/gl_index_buffer.cc +++ b/source/blender/gpu/opengl/gl_index_buffer.cc @@ -21,7 +21,7 @@ * \ingroup gpu */ -#include "gl_backend.hh" +#include "gl_context.hh" #include "gl_debug.hh" #include "gl_index_buffer.hh" @@ -30,7 +30,7 @@ namespace blender::gpu { GLIndexBuf::~GLIndexBuf() { - GLBackend::get()->buf_free(ibo_id_); + GLContext::buf_free(ibo_id_); } void GLIndexBuf::bind(void) diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 2934865f4d1..b4a8e43c931 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -59,7 +59,7 @@ GLTexture::~GLTexture() /* This avoid errors when the texture is still inside the bound texture array. */ ctx->state_manager->texture_unbind(this); } - GLBackend::get()->tex_free(tex_id_); + GLContext::tex_free(tex_id_); } /* Return true on success. */ diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc index 8c8fac44fdc..a06fadf4785 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.cc +++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc @@ -45,7 +45,7 @@ GLUniformBuf::GLUniformBuf(size_t size, const char *name) : UniformBuf(size, nam GLUniformBuf::~GLUniformBuf() { - GLBackend::get()->buf_free(ubo_id_); + GLContext::buf_free(ubo_id_); } /** \} */ diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc index 66ff1f36cef..d56f5d1aa52 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.cc +++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc @@ -21,7 +21,7 @@ * \ingroup gpu */ -#include "gl_backend.hh" +#include "gl_context.hh" #include "gl_vertex_buffer.hh" @@ -42,7 +42,7 @@ void GLVertBuf::resize_data(void) void GLVertBuf::release_data(void) { if (vbo_id_ != 0) { - GLBackend::get()->buf_free(vbo_id_); + GLContext::buf_free(vbo_id_); vbo_id_ = 0; memory_usage -= vbo_size_; } -- cgit v1.2.3 From de21ab418d69ca82a07ec7c836b1deca09bbd57f Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Mon, 7 Sep 2020 14:26:00 -0400 Subject: Add a Self option to the Exact boolean modifier. Fixes T52425. With this option, self-intersections in either or both operands will be handled properly (if both sides are piecewise winding number constant, and maybe some other cases too). In the Boolean tool, this flag was there already but the code forced a unary operation in that case; this commit corrects it to make a binary operation. This flag makes the code slower, which is why it is an option and not an always-on thing. --- source/blender/blenloader/intern/versioning_290.c | 1 + source/blender/bmesh/tools/bmesh_boolean.cc | 4 ++-- source/blender/makesdna/DNA_modifier_types.h | 6 +++++- source/blender/makesrna/intern/rna_modifier.c | 5 +++++ source/blender/modifiers/intern/MOD_boolean.c | 11 +++++++++-- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index b970f18933f..7dc1aab833e 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -513,6 +513,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (md->type == eModifierType_Boolean) { BooleanModifierData *bmd = (BooleanModifierData *)md; bmd->solver = eBooleanModifierSolver_Fast; + bmd->flag = 0; } } } diff --git a/source/blender/bmesh/tools/bmesh_boolean.cc b/source/blender/bmesh/tools/bmesh_boolean.cc index 5d410d60496..d2f73dd63ec 100644 --- a/source/blender/bmesh/tools/bmesh_boolean.cc +++ b/source/blender/bmesh/tools/bmesh_boolean.cc @@ -340,8 +340,8 @@ static bool bmesh_boolean(BMesh *bm, IMesh m_in = mesh_from_bm(bm, looptris, looptris_tot, &m_triangulated, &arena); std::function shape_fn; int nshapes; - if (use_self) { - /* Unary boolean operation. Want every face where test_fn doesn't return -1. */ + if (use_self && boolean_mode == BoolOpType::None) { + /* Unary knife operation. Want every face where test_fn doesn't return -1. */ nshapes = 1; shape_fn = [bm, test_fn, user_data](int f) { BMFace *bmf = BM_face_at_index(bm, f); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 2839d826df9..a9f1d5bcfc4 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -863,7 +863,7 @@ typedef struct BooleanModifierData { struct Object *object; char operation; char solver; - char _pad[1]; + char flag; char bm_flag; float double_threshold; } BooleanModifierData; @@ -879,6 +879,10 @@ typedef enum { eBooleanModifierSolver_Exact = 1, } BooleanModifierSolver; +enum { + eBooleanModifierFlag_Self = (1 << 0), +}; + /* bm_flag only used when G_DEBUG. */ enum { eBooleanModifierBMeshFlag_BMesh_Separate = (1 << 0), diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index d9e151e5f73..1bf14f86189 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2863,6 +2863,11 @@ static void rna_def_modifier_boolean(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Solver", "Method for calculating booleans"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_self", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", eBooleanModifierFlag_Self); + RNA_def_property_ui_text(prop, "Self", "Allow self-intersection in operands"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + /* BMesh debugging options, only used when G_DEBUG is set */ /* BMesh intersection options */ diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 87489c90de3..bef7d5d8e4f 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -77,6 +77,7 @@ static void initData(ModifierData *md) bmd->double_threshold = 1e-6f; bmd->operation = eBooleanModifierOp_Difference; bmd->solver = eBooleanModifierSolver_Exact; + bmd->flag = 0; } static bool isDisabled(const struct Scene *UNUSED(scene), @@ -319,15 +320,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #ifdef WITH_GMP const bool use_exact = bmd->solver == eBooleanModifierSolver_Exact; + const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0; #else if (bmd->solver == eBooleanModifierSolver_Exact) { BKE_modifier_set_error(md, "Compiled without GMP, using fast solver"); } const bool use_exact = false; + const bool use_self = false; #endif if (use_exact) { - BM_mesh_boolean(bm, looptris, tottri, bm_face_isect_pair, NULL, false, bmd->operation); + BM_mesh_boolean( + bm, looptris, tottri, bm_face_isect_pair, NULL, use_self, bmd->operation); } else { BM_mesh_intersect(bm, @@ -393,7 +397,10 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "solver", UI_ITEM_R_EXPAND, NULL, ICON_NONE); - if (!use_exact) { + if (use_exact) { + uiItemR(layout, ptr, "use_self", 0, NULL, ICON_NONE); + } + else { uiItemR(layout, ptr, "double_threshold", 0, NULL, ICON_NONE); } -- cgit v1.2.3 From 40dcf686f04f7db8110f9c85621eb8a0bd764080 Mon Sep 17 00:00:00 2001 From: Ankit Date: Tue, 8 Sep 2020 00:17:17 +0530 Subject: Support ASan library on macOS for all generators. This change allows macOS developers to use `WITH_COMPILER_ASAN` with every generator. `CMAKE_C_IMPLICIT_LINK_DIRECTORIES` on macOS points to `Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib` which is not where the Sanitizer libraries are. To link the library, rpath could be used but that seems complex, so linker flags are passed as the documentation says. [1] If users have `ASAN_OPTIONS=detect_leaks=1` in their environment variables, it should be removed to avoid a feature-unsupported error while compiling. [1]: http://clang.llvm.org/docs/AddressSanitizer.html#usage Reviewed By: brecht Differential Revision: https://developer.blender.org/D8817 --- CMakeLists.txt | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76d2d578dc3..f72ccd857b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -510,9 +510,21 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") -fno-sanitize=alignment \ ") - if(NOT MSVC) # not all sanitizers are supported with clang-cl, these two however are very vocal about it - set(_asan_defaults "${_asan_defaults} -fsanitize=leak -fsanitize=object-size" ) + if(MSVC) + # clang-cl doesn't support all sanitizers, but leak and object-size give errors/warnings. + set(_asan_defaults "${_asan_defaults}") + elseif(APPLE) + # AppleClang doesn't support all sanitizers, but leak gives error. + if(CMAKE_BUILD_TYPE MATCHES "Debug") + # Silence the warning that object-size is not effective in -O0. + set(_asan_defaults "${_asan_defaults}") + else() + set(_asan_defaults "${_asan_defaults} -fsanitize=object-size") + endif() + else() + set(_asan_defaults "${_asan_defaults} -fsanitize=leak -fsanitize=object-size") endif() + set(COMPILER_ASAN_CFLAGS "${_asan_defaults}" CACHE STRING "C flags for address sanitizer") mark_as_advanced(COMPILER_ASAN_CFLAGS) set(COMPILER_ASAN_CXXFLAGS "${_asan_defaults}" CACHE STRING "C++ flags for address sanitizer") @@ -520,16 +532,31 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") unset(_asan_defaults) - if(NOT MSVC) - find_library(COMPILER_ASAN_LIBRARY asan ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}) - else() - find_library( - COMPILER_ASAN_LIBRARY NAMES clang_rt.asan-x86_64 + if(MSVC) + find_library( + COMPILER_ASAN_LIBRARY NAMES clang_rt.asan-x86_64 PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/7.0.0/lib/windows [HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/6.0.0/lib/windows ) + elseif(APPLE) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} + -print-file-name=lib + OUTPUT_VARIABLE CLANG_LIB_DIR + ) + string(STRIP "${CLANG_LIB_DIR}" CLANG_LIB_DIR) + find_library( + COMPILER_ASAN_LIBRARY NAMES libclang_rt.asan_osx_dynamic.dylib + PATHS + "${CLANG_LIB_DIR}/darwin/" + ) + unset(CLANG_LIB_DIR) + else() + find_library( + COMPILER_ASAN_LIBRARY asan ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES} + ) endif() + mark_as_advanced(COMPILER_ASAN_LIBRARY) endif() endif() @@ -823,6 +850,9 @@ if(NOT CMAKE_BUILD_TYPE MATCHES "Release") if(MSVC) set(COMPILER_ASAN_LINKER_FLAGS "/FUNCTIONPADMIN:6") endif() + if(APPLE) + set(COMPILER_ASAN_LINKER_FLAGS "-fno-omit-frame-pointer -fsanitize=address") + endif(APPLE) if(COMPILER_ASAN_LIBRARY) set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS};${COMPILER_ASAN_LIBRARY}") set(PLATFORM_LINKFLAGS "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}") -- cgit v1.2.3 From 6aaa6c96a1c5b1cfb093433f96999086534ef18b Mon Sep 17 00:00:00 2001 From: Ankit Date: Tue, 8 Sep 2020 00:22:39 +0530 Subject: Tests: set build directory using build type Similar to {rB0a5f7061369d53b4eac55362ad2} but also for Xcode and Ninja multi-config. This silences 44 pairs of warnings like: /bin/rm -f build_full/bin/tests/BLI_ghash_performance_test "build_full/CMakeScripts/XCODE_DEPEND_HELPER.make:42: warning: ignoring old commands for target `build_full/bin/tests/BLI_ghash_performance_test'" /bin/rm -f build_full/bin/tests/BLI_ghash_performance_test "build_full/CMakeScripts/XCODE_DEPEND_HELPER.make:3523: warning: overriding commands for target `build_full/bin/tests/BLI_ghash_performance_test'" Reviewed By: brecht Differential Revision: https://developer.blender.org/D8815 --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f72ccd857b3..cfc49505a0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,7 +128,9 @@ enable_testing() set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE INTERNAL "" FORCE) set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib CACHE INTERNAL "" FORCE) -if(MSVC) + +get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(GENERATOR_IS_MULTI_CONFIG) set(TESTS_OUTPUT_DIR ${EXECUTABLE_OUTPUT_PATH}/tests/$/ CACHE INTERNAL "" FORCE) else() set(TESTS_OUTPUT_DIR ${EXECUTABLE_OUTPUT_PATH}/tests/ CACHE INTERNAL "" FORCE) -- cgit v1.2.3 From 5eb5978043c8e7036e15572ea43b083965140e77 Mon Sep 17 00:00:00 2001 From: Ankit Date: Tue, 8 Sep 2020 00:24:59 +0530 Subject: Generate Xcode scheme files during configuration. Every time CMake is re-run, Xcode shows a popup asking if user wants to manage schemes automatically or manually. Building Blender wiki page recommends managing schemes automatically. This change sets the default behavior to "automatically" and generates the .xcscheme files while CMake is running, instead of hogging Xcode later on. With tests enabled, the number of schemes is 203. Reviewed By: brecht Differential Revision: https://developer.blender.org/D8820 --- build_files/cmake/platform/platform_apple_xcode.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build_files/cmake/platform/platform_apple_xcode.cmake b/build_files/cmake/platform/platform_apple_xcode.cmake index 3a43ca317dd..7e6bd14ecc3 100644 --- a/build_files/cmake/platform/platform_apple_xcode.cmake +++ b/build_files/cmake/platform/platform_apple_xcode.cmake @@ -154,3 +154,11 @@ if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() + +if(${CMAKE_GENERATOR} MATCHES "Xcode") + # Generate schemes in Blender.xcodeproj/xcshareddata/xcschemes/ early, at + # configuration time, not when Xcode is opened. + # This gets rid of "Manage schemes automatically" confirmation dialog that + # appears whenever CMake is run. + set(CMAKE_XCODE_GENERATE_SCHEME ON) +endif() -- cgit v1.2.3 From d4cca7b7b0d858a45c684fd0725344881e0c1c63 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 7 Sep 2020 14:22:29 -0500 Subject: UI: Changes to timeline playback popover The current playback popover has some issues: - Using labels instead of headers is inconsistent with the rest of the interface - Incomplete context and description for some properties - Ugly large spacing This commit fixes these problems by using headers. Differential Revision: https://developer.blender.org/D8434 --- release/scripts/startup/bl_ui/space_time.py | 43 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 1a9244a3051..68b5f8acd38 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -230,34 +230,37 @@ class TimelinePanelButtons: class TIME_PT_playback(TimelinePanelButtons, Panel): bl_label = "Playback" bl_region_type = 'HEADER' + bl_ui_units_x = 11 def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False screen = context.screen scene = context.scene - layout.prop(scene, "sync_mode", text="") - layout.prop(scene, "use_audio_scrub") - layout.prop(scene, "use_audio", text="Mute Audio") - - layout.prop(scene, "show_subframe", text="Subframes") - - layout.prop(scene, "lock_frame_selection_to_range", text="Limit Playback to Frame Range") - layout.prop(screen, "use_follow", text="Follow Current Frame") - - layout.separator() - col = layout.column() - col.label(text="Play Animation In:") - layout.prop(screen, "use_play_top_left_3d_editor", text="Active Editor Only") - layout.prop(screen, "use_play_3d_editors") - layout.prop(screen, "use_play_animation_editors") - layout.prop(screen, "use_play_properties_editors") - layout.prop(screen, "use_play_image_editors") - layout.prop(screen, "use_play_sequence_editors") - layout.prop(screen, "use_play_node_editors") - layout.prop(screen, "use_play_clip_editors") + col.prop(scene, "sync_mode", text="Audio") + col.prop(scene, "use_audio_scrub", text="Scrubbing") + col.prop(scene, "use_audio", text="Mute") + + col = layout.column(heading="Playback") + col.prop(scene, "lock_frame_selection_to_range", text="Limit to Frame Range") + col.prop(screen, "use_follow", text="Follow Current Frame") + + col = layout.column(heading="Play In") + col.prop(screen, "use_play_top_left_3d_editor", text="Active Editor") + col.prop(screen, "use_play_3d_editors", text="3D Viewport") + col.prop(screen, "use_play_animation_editors", text="Animation Editors") + col.prop(screen, "use_play_image_editors", text="Image Editor") + col.prop(screen, "use_play_properties_editors", text="Properties Editor") + col.prop(screen, "use_play_clip_editors", text="Movie Clip Editor") + col.prop(screen, "use_play_node_editors", text="Node Editors") + col.prop(screen, "use_play_sequence_editors", text="Video Sequencer") + + col = layout.column(heading="Show") + col.prop(scene, "show_subframe", text="Subframes") layout.separator() -- cgit v1.2.3 From 36aeb0ec1e2ec8cd6a3690ac11cd3c50f3851802 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 7 Sep 2020 14:59:07 -0500 Subject: UI: Add temperature units Based on the original patch by Vaishnav S (@padthai), this adds support for temperature units. Initially supported units are Celsius, Kelvin, and Fahrenheit. The units aren't used anywhere with this commit. Those changes should happen in separate patches by adding PROP_TEMPERATURE to RNA property definitions. But it should be ensured that the various solvers and simulations actually properly use real units. The complexity of some of the changes comes from the fact that these units have offsets from each other as well as coefficients. This also makes the implementation in the current unit system troublesome. For example, entering 0C evaluates correctly to 273K, but 0C + 0C doubles that result, because each unit value is evaluated separately. This is quite hard to solve in the general case with Blender's current unit system, though, so it is not handled in this commit. Differential Revision: https://developer.blender.org/D4401 --- release/scripts/startup/bl_ui/properties_scene.py | 1 + source/blender/blenkernel/BKE_unit.h | 7 +- source/blender/blenkernel/intern/scene.c | 2 + source/blender/blenkernel/intern/unit.c | 104 ++++++++++++++++++++-- source/blender/editors/util/numinput.c | 2 +- source/blender/makesdna/DNA_scene_types.h | 3 +- source/blender/makesrna/RNA_types.h | 4 + source/blender/makesrna/intern/makesrna.c | 4 + source/blender/makesrna/intern/rna_rna.c | 1 + source/blender/makesrna/intern/rna_scene.c | 16 ++++ source/blender/python/intern/bpy_props.c | 1 + 11 files changed, 131 insertions(+), 14 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index df4793cab19..8618c201312 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -92,6 +92,7 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): subcol.prop(unit, "length_unit", text="Length") subcol.prop(unit, "mass_unit", text="Mass") subcol.prop(unit, "time_unit", text="Time") + subcol.prop(unit, "temperature_unit", text="Temperature") class SceneKeyingSetsPanel: diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h index a797c5555ff..d47cebb5dc8 100644 --- a/source/blender/blenkernel/BKE_unit.h +++ b/source/blender/blenkernel/BKE_unit.h @@ -46,8 +46,8 @@ bool bUnit_ReplaceString( /* return true if the string contains any valid unit for the given type */ bool bUnit_ContainsUnit(const char *str, int type); -/* if user does not specify a unit, multiply with this value */ -double bUnit_PreferredInputUnitScalar(const struct UnitSettings *settings, int type); +/* If user does not specify a unit, this converts it to the unit from the settings. */ +double bUnit_ApplyPreferredUnit(const struct UnitSettings *settings, int type, double value); /* make string keyboard-friendly: 10µm --> 10um */ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type); @@ -86,7 +86,8 @@ enum { B_UNIT_ACCELERATION = 8, B_UNIT_CAMERA = 9, B_UNIT_POWER = 10, - B_UNIT_TYPE_TOT = 11, + B_UNIT_TEMPERATURE = 11, + B_UNIT_TYPE_TOT = 12, }; #ifdef __cplusplus diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 00218b1be51..a1f74dddbad 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -157,6 +157,8 @@ static void scene_init_data(ID *id) scene->unit.length_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_LENGTH); scene->unit.mass_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_MASS); scene->unit.time_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_TIME); + scene->unit.temperature_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, + B_UNIT_TEMPERATURE); /* Anti-Aliasing threshold. */ scene->grease_pencil_settings.smaa_threshold = 1.0f; diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 5af24152972..c5782d846bb 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -80,6 +80,8 @@ #define UN_SC_LB 0.45359237f #define UN_SC_OZ 0.028349523125f +#define UN_SC_FAH 0.555555555555f + /* clang-format on */ /* Define a single unit. */ @@ -101,7 +103,7 @@ typedef struct bUnitDef { const char *identifier; double scalar; - /** Not used yet, needed for converting temperature. */ + /** Needed for converting temperatures. */ double bias; int flag; } bUnitDef; @@ -329,6 +331,22 @@ static struct bUnitDef buPowerDef[] = { }; static struct bUnitCollection buPowerCollection = {buPowerDef, 3, 0, UNIT_COLLECTION_LENGTH(buPowerDef)}; +/* Temperature */ +static struct bUnitDef buMetricTempDef[] = { + {"kelvin", "kelvin", "K", NULL, "Kelvin", "KELVIN", 1.0f, 0.0, B_UNIT_DEF_NONE}, /* Base unit. */ + {"celsius", "celsius", "°C", "C", "Celsius", "CELCIUS", 1.0f, 273.15, B_UNIT_DEF_NONE}, + NULL_UNIT, +}; +static struct bUnitCollection buMetricTempCollection = {buMetricTempDef, 0, 0, UNIT_COLLECTION_LENGTH(buMetricTempDef)}; + +static struct bUnitDef buImperialTempDef[] = { + {"kelvin", "kelvin", "K", NULL, "Kelvin", "KELVIN", 1.0f, 0.0, B_UNIT_DEF_NONE}, /* Base unit. */ + {"fahrenheit", "fahrenheit", "°F", "F", "Fahrenheit", "FAHRENHEIT", UN_SC_FAH, 459.67, B_UNIT_DEF_NONE}, + NULL_UNIT, +}; +static struct bUnitCollection buImperialTempCollection = { + buImperialTempDef, 1, 0, UNIT_COLLECTION_LENGTH(buImperialTempDef)}; + /* clang-format on */ #define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / B_UNIT_TYPE_TOT) / sizeof(void *)) - 1) @@ -344,6 +362,7 @@ static const struct bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = { NULL, NULL, NULL, + NULL, NULL}, /* Metric. */ {NULL, @@ -356,7 +375,8 @@ static const struct bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = { &buMetricVelCollection, &buMetricAclCollection, &buCameraLenCollection, - &buPowerCollection}, + &buPowerCollection, + &buMetricTempCollection}, /* Imperial. */ {NULL, &buImperialLenCollection, @@ -368,7 +388,8 @@ static const struct bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = { &buImperialVelCollection, &buImperialAclCollection, &buCameraLenCollection, - &buPowerCollection}, + &buPowerCollection, + &buImperialTempCollection}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, }; @@ -449,7 +470,7 @@ static size_t unit_as_string(char *str, } } - double value_conv = value / unit->scalar; + double value_conv = (value / unit->scalar) - unit->bias; /* Adjust precision to expected number of significant digits. * Note that here, we shall not have to worry about very big/small numbers, units are expected @@ -512,6 +533,7 @@ typedef struct { int length; int mass; int time; + int temperature; } PreferredUnits; static PreferredUnits preferred_units_from_UnitSettings(const UnitSettings *settings) @@ -522,6 +544,7 @@ static PreferredUnits preferred_units_from_UnitSettings(const UnitSettings *sett units.length = settings->length_unit; units.mass = settings->mass_unit; units.time = settings->time_unit; + units.temperature = settings->temperature_unit; return units; } @@ -597,6 +620,11 @@ static const bUnitDef *get_preferred_display_unit_if_used(int type, PreferredUni return usys->units + 3; } break; + case B_UNIT_TEMPERATURE: + if (units.temperature == USER_UNIT_ADAPTIVE) { + return NULL; + } + return usys->units + MIN2(units.temperature, max_offset); default: break; } @@ -643,6 +671,7 @@ size_t bUnit_AsString( units.length = USER_UNIT_ADAPTIVE; units.mass = USER_UNIT_ADAPTIVE; units.time = USER_UNIT_ADAPTIVE; + units.temperature = USER_UNIT_ADAPTIVE; return unit_as_string_main(str, len_max, value, prec, type, split, pad, units); } @@ -844,6 +873,35 @@ static bool unit_distribute_negatives(char *str, const int len_max) return changed; } +/** + * Helper for #unit_scale_str for the process of correctly applying the order of operations + * for the unit's bias term. + */ +static int find_previous_non_value_char(const char *str, const int start_ofs) +{ + for (int i = start_ofs; i > 0; i--) { + if (ch_is_op(str[i - 1]) || strchr("( )", str[i - 1])) { + return i; + } + } + return 0; +} + +/** + * Helper for #unit_scale_str for the process of correctly applying the order of operations + * for the unit's bias term. + */ +static int find_end_of_value_chars(const char *str, const int len_max, const int start_ofs) +{ + int i; + for (i = start_ofs; i < len_max; i++) { + if (!strchr("0123456789eE.", str[i])) { + return i; + } + } + return i; +} + static int unit_scale_str(char *str, int len_max, char *str_tmp, @@ -867,6 +925,34 @@ static int unit_scale_str(char *str, int len = strlen(str); + /* Deal with unit bias for temperature units. Order of operations is important, so we + * have to add parentheses, add the bias, then multiply by the scalar like usual. + * + * Note: If these changes don't fit in the buffer properly unit evaluation has failed, + * just try not to destroy anything while failing. */ + if (unit->bias != 0.0) { + /* Add the open parenthesis. */ + int prev_op_ofs = find_previous_non_value_char(str, found_ofs); + if (len + 1 < len_max) { + memmove(str + prev_op_ofs + 1, str + prev_op_ofs, len - prev_op_ofs + 1); + str[prev_op_ofs] = '('; + len++; + found_ofs++; + str_found++; + } /* If this doesn't fit, we have failed. */ + + /* Add the addition sign, the bias, and the close parenthesis after the value. */ + int value_end_ofs = find_end_of_value_chars(str, len_max, prev_op_ofs + 2); + int len_bias_num = BLI_snprintf(str_tmp, TEMP_STR_SIZE, "+%.9g)", unit->bias); + if (value_end_ofs + len_bias_num < len_max) { + memmove(str + value_end_ofs + len_bias_num, str + value_end_ofs, len - value_end_ofs + 1); + memcpy(str + value_end_ofs, str_tmp, len_bias_num); + len += len_bias_num; + found_ofs += len_bias_num; + str_found += len_bias_num; + } /* If this doesn't fit, we have failed. */ + } + int len_name = strlen(replace_str); int len_move = (len - (found_ofs + len_name)) + 1; /* 1+ to copy the string terminator. */ @@ -990,15 +1076,15 @@ bool bUnit_ContainsUnit(const char *str, int type) return false; } -double bUnit_PreferredInputUnitScalar(const struct UnitSettings *settings, int type) +double bUnit_ApplyPreferredUnit(const struct UnitSettings *settings, int type, double value) { PreferredUnits units = preferred_units_from_UnitSettings(settings); const bUnitDef *unit = get_preferred_display_unit_if_used(type, units); - if (unit) { - return unit->scalar; - } - return bUnit_BaseScalar(units.system, type); + const double scalar = (unit == NULL) ? bUnit_BaseScalar(units.system, type) : unit->scalar; + const double bias = (unit == NULL) ? 0.0 : unit->bias; /* Base unit shouldn't have a bias. */ + + return value * scalar + bias; } /** diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 041b2fec00b..f8e3dda0ed3 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -298,7 +298,7 @@ bool user_string_to_number(bContext *C, } int success = BPY_run_string_as_number(C, NULL, str, error_prefix, r_value); - *r_value *= bUnit_PreferredInputUnitScalar(unit, type); + *r_value = bUnit_ApplyPreferredUnit(unit, type, *r_value); *r_value /= unit_scale; return success; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 219a7afa6c2..1a63c532c68 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1534,8 +1534,9 @@ typedef struct UnitSettings { char length_unit; char mass_unit; char time_unit; + char temperature_unit; - char _pad[5]; + char _pad[4]; } UnitSettings; /* ------------------------------------------- */ diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index ee7c045ebf9..1c488b2cac1 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -91,6 +91,7 @@ typedef enum PropertyUnit { PROP_UNIT_ACCELERATION = (8 << 16), /* m/(s^2) */ PROP_UNIT_CAMERA = (9 << 16), /* mm */ PROP_UNIT_POWER = (10 << 16), /* W */ + PROP_UNIT_TEMPERATURE = (11 << 16), /* C */ } PropertyUnit; #define RNA_SUBTYPE_UNIT(subtype) ((subtype)&0x00FF0000) @@ -156,6 +157,9 @@ typedef enum PropertySubType { /** Light */ PROP_POWER = 42 | PROP_UNIT_POWER, + + /* temperature */ + PROP_TEMPERATURE = 43 | PROP_UNIT_TEMPERATURE, } PropertySubType; /* Make sure enums are updated with these */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 2b1e5b3c702..a81bd4d0832 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -3199,6 +3199,8 @@ static const char *rna_property_subtypename(PropertySubType type) return "PROP_PASSWORD"; case PROP_POWER: return "PROP_POWER"; + case PROP_TEMPERATURE: + return "PROP_TEMPERATURE"; default: { /* in case we don't have a type preset that includes the subtype */ if (RNA_SUBTYPE_UNIT(type)) { @@ -3236,6 +3238,8 @@ static const char *rna_property_subtype_unit(PropertySubType type) return "PROP_UNIT_CAMERA"; case PROP_UNIT_POWER: return "PROP_UNIT_POWER"; + case PROP_UNIT_TEMPERATURE: + return "PROP_UNIT_TEMPERATURE"; default: return "PROP_UNIT_UNKNOWN"; } diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 9f5440be9f8..c7076d6c631 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -117,6 +117,7 @@ const EnumPropertyItem rna_enum_property_unit_items[] = { {PROP_UNIT_MASS, "MASS", 0, "Mass", ""}, {PROP_UNIT_CAMERA, "CAMERA", 0, "Camera", ""}, {PROP_UNIT_POWER, "POWER", 0, "Power", ""}, + {PROP_UNIT_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 65edaf0bcca..ab4ffda8888 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2568,6 +2568,15 @@ const EnumPropertyItem *rna_UnitSettings_time_unit_itemf(bContext *UNUSED(C), return rna_UnitSettings_itemf_wrapper(units->system, B_UNIT_TIME, r_free); } +const EnumPropertyItem *rna_UnitSettings_temperature_unit_itemf(bContext *UNUSED(C), + PointerRNA *ptr, + PropertyRNA *UNUSED(prop), + bool *r_free) +{ + UnitSettings *units = ptr->data; + return rna_UnitSettings_itemf_wrapper(units->system, B_UNIT_TEMPERATURE, r_free); +} + static void rna_UnitSettings_system_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) @@ -3906,6 +3915,13 @@ static void rna_def_unit_settings(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_UnitSettings_time_unit_itemf"); RNA_def_property_ui_text(prop, "Time Unit", "Unit that will be used to display time values"); RNA_def_property_update(prop, NC_WINDOW, NULL); + + prop = RNA_def_property(srna, "temperature_unit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_UnitSettings_temperature_unit_itemf"); + RNA_def_property_ui_text( + prop, "Temperature Unit", "Unit that will be used to display temperature values"); + RNA_def_property_update(prop, NC_WINDOW, NULL); } static void rna_def_view_layer_eevee(BlenderRNA *brna) diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index a78ed601d57..bc708bd4a89 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -172,6 +172,7 @@ static const EnumPropertyItem property_subtype_array_items[] = { {PROP_LAYER, "LAYER", 0, "Layer", ""}, {PROP_LAYER_MEMBER, "LAYER_MEMBER", 0, "Layer Member", ""}, {PROP_POWER, "POWER", 0, "Power", ""}, + {PROP_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""}, {PROP_NONE, "NONE", 0, "None", ""}, {0, NULL, 0, NULL, NULL}, -- cgit v1.2.3 From 97c6c4e478830bd9a38873c5208e1ca37840b69a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 7 Sep 2020 15:34:32 -0500 Subject: Decimate Modifier: Restore vertex group factor property in UI This property was inadvertently removed from the modifier's panel and it wasn't caught in time for the release of 2.90. Thanks to the user "VermossomreV" for bringing this to my attention. Differential Revision: https://developer.blender.org/D8790 --- source/blender/modifiers/intern/MOD_decimate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 68c330452b3..72a868cc6a7 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -257,6 +257,10 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(layout, ptr, "use_collapse_triangulate", 0, NULL, ICON_NONE); modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); + sub = uiLayoutRow(layout, true); + bool has_vertex_group = RNA_string_length(ptr, "vertex_group") != 0; + uiLayoutSetActive(sub, has_vertex_group); + uiItemR(sub, ptr, "vertex_group_factor", 0, NULL, ICON_NONE); } else if (decimate_type == MOD_DECIM_MODE_UNSUBDIV) { uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE); -- cgit v1.2.3 From b7a28b315a0ba85f9796845718e578abf5379f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 21:08:31 +0200 Subject: GPUFramebuffer: Make GPU_framebuffer_read_depth more flexible This is to make use of it in selection code. --- source/blender/draw/engines/gpencil/gpencil_render.c | 1 + source/blender/draw/engines/workbench/workbench_render.c | 1 + source/blender/editors/space_view3d/view3d_draw.c | 9 +++++++-- source/blender/gpu/GPU_framebuffer.h | 3 ++- source/blender/gpu/intern/gpu_framebuffer.cc | 5 +++-- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c index 5d417d995ac..b18013d742a 100644 --- a/source/blender/draw/engines/gpencil/gpencil_render.c +++ b/source/blender/draw/engines/gpencil/gpencil_render.c @@ -182,6 +182,7 @@ static void GPENCIL_render_result_z(struct RenderLayer *rl, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), + GPU_DATA_FLOAT, rp->rect); float winmat[4][4]; diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c index 8760f2651ee..2c3b5a5f935 100644 --- a/source/blender/draw/engines/workbench/workbench_render.c +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -124,6 +124,7 @@ static void workbench_render_result_z(struct RenderLayer *rl, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), + GPU_DATA_FLOAT, rp->rect); float winmat[4][4]; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c4da39bca2f..6cd940244b4 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2157,8 +2157,13 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0); GPU_framebuffer_bind(tmp_fb); - GPU_framebuffer_read_depth( - tmp_fb, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), data); + GPU_framebuffer_read_depth(tmp_fb, + rect->xmin, + rect->ymin, + BLI_rcti_size_x(rect), + BLI_rcti_size_y(rect), + GPU_DATA_FLOAT, + data); GPU_framebuffer_restore(); GPU_framebuffer_free(tmp_fb); diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index f4599ac44bb..c0391d96e06 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -188,7 +188,8 @@ void GPU_framebuffer_clear(GPUFrameBuffer *fb, void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4]); -void GPU_framebuffer_read_depth(GPUFrameBuffer *fb, int x, int y, int w, int h, float *data); +void GPU_framebuffer_read_depth( + GPUFrameBuffer *fb, int x, int y, int w, int h, eGPUDataFormat format, void *data); void GPU_framebuffer_read_color(GPUFrameBuffer *fb, int x, int y, diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index a0b05df583a..f9caa8df143 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -393,10 +393,11 @@ void GPU_clear_depth(float depth) GPU_context_active_get()->active_fb->clear(GPU_DEPTH_BIT, clear_col, depth, 0x0); } -void GPU_framebuffer_read_depth(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, float *data) +void GPU_framebuffer_read_depth( + GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, eGPUDataFormat format, void *data) { int rect[4] = {x, y, w, h}; - reinterpret_cast(gpu_fb)->read(GPU_DEPTH_BIT, GPU_DATA_FLOAT, rect, 1, 1, data); + reinterpret_cast(gpu_fb)->read(GPU_DEPTH_BIT, format, rect, 1, 1, data); } void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, -- cgit v1.2.3 From d4fd363d05943eaf021ef3bff8756cdf96241c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 21:09:18 +0200 Subject: GPU: Select Pick: Remove last GL call This is part of the Vulkan task T68990 This is just a cleanup. --- source/blender/gpu/intern/gpu_select_pick.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c index c3ccb68a998..769b52bf593 100644 --- a/source/blender/gpu/intern/gpu_select_pick.c +++ b/source/blender/gpu/intern/gpu_select_pick.c @@ -346,16 +346,9 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c ps->gl.rect_depth = depth_buf_malloc(rect_len); /* set initial 'far' value */ -#if 0 - glReadPixels(UNPACK4(ps->gl.clip_readpixels), - GL_DEPTH_COMPONENT, - GL_UNSIGNED_INT, - ps->gl.rect_depth->buf); -#else for (uint i = 0; i < rect_len; i++) { ps->gl.rect_depth->buf[i] = DEPTH_MAX; } -#endif ps->gl.is_init = false; ps->gl.prev_id = 0; @@ -486,10 +479,9 @@ bool gpu_select_pick_load_id(uint id, bool end) } const uint rect_len = ps->src.rect_len; - glReadPixels(UNPACK4(ps->gl.clip_readpixels), - GL_DEPTH_COMPONENT, - GL_UNSIGNED_INT, - ps->gl.rect_depth_test->buf); + GPUFrameBuffer *fb = GPU_framebuffer_active_get(); + GPU_framebuffer_read_depth( + fb, UNPACK4(ps->gl.clip_readpixels), GPU_DATA_UNSIGNED_INT, ps->gl.rect_depth_test->buf); /* perform initial check since most cases the array remains unchanged */ bool do_pass = false; -- cgit v1.2.3 From 5c2ac8520e070db2085b7d95d9d232b567edb247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 7 Sep 2020 23:52:55 +0200 Subject: GPUQuery: GL Backend isolation This is part of the Vulkan task T68990. This introduce a new GLQueryPool for managing queries in an implementation agnostic manner. This modify the GPU selection query to use this new object. This also make use of blender::Vector for better code quality. No real functionnal change. --- source/blender/gpu/CMakeLists.txt | 6 +- source/blender/gpu/intern/gpu_backend.hh | 2 + source/blender/gpu/intern/gpu_query.cc | 28 +++ source/blender/gpu/intern/gpu_query.hh | 59 ++++++ source/blender/gpu/intern/gpu_select_private.h | 8 + .../blender/gpu/intern/gpu_select_sample_query.c | 224 --------------------- .../blender/gpu/intern/gpu_select_sample_query.cc | 201 ++++++++++++++++++ source/blender/gpu/opengl/gl_backend.hh | 6 + source/blender/gpu/opengl/gl_context.hh | 16 +- source/blender/gpu/opengl/gl_query.cc | 78 +++++++ source/blender/gpu/opengl/gl_query.hh | 69 +++++++ 11 files changed, 464 insertions(+), 233 deletions(-) create mode 100644 source/blender/gpu/intern/gpu_query.cc create mode 100644 source/blender/gpu/intern/gpu_query.hh delete mode 100644 source/blender/gpu/intern/gpu_select_sample_query.c create mode 100644 source/blender/gpu/intern/gpu_select_sample_query.cc create mode 100644 source/blender/gpu/opengl/gl_query.cc create mode 100644 source/blender/gpu/opengl/gl_query.hh diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 6fdd510ad28..0a372125391 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -74,9 +74,10 @@ set(SRC intern/gpu_matrix.cc intern/gpu_node_graph.c intern/gpu_platform.cc + intern/gpu_query.cc intern/gpu_select.c intern/gpu_select_pick.c - intern/gpu_select_sample_query.c + intern/gpu_select_sample_query.cc intern/gpu_shader.cc intern/gpu_shader_builtin.c intern/gpu_shader_interface.cc @@ -95,6 +96,7 @@ set(SRC opengl/gl_framebuffer.cc opengl/gl_immediate.cc opengl/gl_index_buffer.cc + opengl/gl_query.cc opengl/gl_shader.cc opengl/gl_shader_interface.cc opengl/gl_state.cc @@ -146,6 +148,7 @@ set(SRC intern/gpu_node_graph.h intern/gpu_private.h intern/gpu_platform_private.hh + intern/gpu_query.hh intern/gpu_select_private.h intern/gpu_shader_private.hh intern/gpu_shader_interface.hh @@ -164,6 +167,7 @@ set(SRC opengl/gl_immediate.hh opengl/gl_index_buffer.hh opengl/gl_primitive.hh + opengl/gl_query.hh opengl/gl_shader.hh opengl/gl_shader_interface.hh opengl/gl_state.hh diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh index d074350e8d0..1a6a6668b42 100644 --- a/source/blender/gpu/intern/gpu_backend.hh +++ b/source/blender/gpu/intern/gpu_backend.hh @@ -34,6 +34,7 @@ class Batch; class DrawList; class FrameBuffer; class IndexBuf; +class QueryPool; class Shader; class Texture; class UniformBuf; @@ -53,6 +54,7 @@ class GPUBackend { virtual DrawList *drawlist_alloc(int list_length) = 0; virtual FrameBuffer *framebuffer_alloc(const char *name) = 0; virtual IndexBuf *indexbuf_alloc(void) = 0; + virtual QueryPool *querypool_alloc(void) = 0; virtual Shader *shader_alloc(const char *name) = 0; virtual Texture *texture_alloc(const char *name) = 0; virtual UniformBuf *uniformbuf_alloc(int size, const char *name) = 0; diff --git a/source/blender/gpu/intern/gpu_query.cc b/source/blender/gpu/intern/gpu_query.cc new file mode 100644 index 00000000000..ad9b6d21420 --- /dev/null +++ b/source/blender/gpu/intern/gpu_query.cc @@ -0,0 +1,28 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "gpu_query.hh" + +using namespace blender::gpu; + +/* TODO(fclem) Make the associated C-API to use inside DRW profiler. */ diff --git a/source/blender/gpu/intern/gpu_query.hh b/source/blender/gpu/intern/gpu_query.hh new file mode 100644 index 00000000000..5e3159a94f7 --- /dev/null +++ b/source/blender/gpu/intern/gpu_query.hh @@ -0,0 +1,59 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "BLI_span.hh" + +namespace blender::gpu { + +typedef enum GPUQueryType { + GPU_QUERY_OCCLUSION = 0, +} GPUQueryType; + +class QueryPool { + public: + virtual ~QueryPool(){}; + + /** + * Will start and end the query at this index inside the pool. The pool will resize + * automatically but does not support sparse allocation. So prefer using consecutive indices. + */ + virtual void init(GPUQueryType type) = 0; + + /** + * Will start and end the query at this index inside the pool. + * The pool will resize automatically. + */ + virtual void begin_query(void) = 0; + virtual void end_query(void) = 0; + + /** + * Must be fed with a buffer large enough to contain all the queries issued. + * IMPORTANT: Result for each query can be either binary or represent the number of samples + * drawn. + */ + virtual void get_occlusion_result(MutableSpan r_values) = 0; +}; + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_select_private.h b/source/blender/gpu/intern/gpu_select_private.h index e364b78bff2..f9a1aea8338 100644 --- a/source/blender/gpu/intern/gpu_select_private.h +++ b/source/blender/gpu/intern/gpu_select_private.h @@ -25,6 +25,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + /* gpu_select_pick */ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode); bool gpu_select_pick_load_id(uint id, bool end); @@ -42,3 +46,7 @@ bool gpu_select_query_load_id(uint id); uint gpu_select_query_end(void); #define SELECT_ID_NONE ((uint)0xffffffff) + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c deleted file mode 100644 index 45d52b22664..00000000000 --- a/source/blender/gpu/intern/gpu_select_sample_query.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2014 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - * - * Interface for accessing gpu-related methods for selection. The semantics will be - * similar to glRenderMode(GL_SELECT) since the goal is to maintain compatibility. - */ - -#include - -#include "GPU_framebuffer.h" -#include "GPU_glew.h" -#include "GPU_select.h" -#include "GPU_state.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_rect.h" - -#include "BLI_utildefines.h" - -#include "gpu_select_private.h" - -/* Ad hoc number of queries to allocate to skip doing many glGenQueries */ -#define ALLOC_QUERIES 200 - -typedef struct GPUQueryState { - /* Tracks whether a query has been issued so that gpu_load_id can end the previous one */ - bool query_issued; - /* array holding the OpenGL query identifiers */ - uint *queries; - /* array holding the id corresponding to each query */ - uint *id; - /* number of queries in *queries and *id */ - uint num_of_queries; - /* index to the next query to start */ - uint active_query; - /* cache on initialization */ - uint (*buffer)[4]; - /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/ - uint bufsize; - /* mode of operation */ - char mode; - uint index; - int oldhits; - - /* Previous state to restore after drawing. */ - int viewport[4]; - int scissor[4]; - eGPUWriteMask write_mask; - eGPUDepthTest depth_test; -} GPUQueryState; - -static GPUQueryState g_query_state = {0}; - -void gpu_select_query_begin( - uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits) -{ - g_query_state.query_issued = false; - g_query_state.active_query = 0; - g_query_state.num_of_queries = 0; - g_query_state.bufsize = bufsize; - g_query_state.buffer = buffer; - g_query_state.mode = mode; - g_query_state.index = 0; - g_query_state.oldhits = oldhits; - - g_query_state.num_of_queries = ALLOC_QUERIES; - - g_query_state.queries = MEM_mallocN( - g_query_state.num_of_queries * sizeof(*g_query_state.queries), "gpu selection queries"); - g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), - "gpu selection ids"); - glGenQueries(g_query_state.num_of_queries, g_query_state.queries); - - g_query_state.write_mask = GPU_write_mask_get(); - g_query_state.depth_test = GPU_depth_test_get(); - GPU_scissor_get(g_query_state.scissor); - GPU_viewport_size_get_i(g_query_state.viewport); - - /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see T7997). */ - GPU_color_mask(true, true, true, true); - - /* In order to save some fill rate we minimize the viewport using rect. - * 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 */ - - int viewport[4] = { - UNPACK2(g_query_state.viewport), BLI_rcti_size_x(input), BLI_rcti_size_y(input)}; - - GPU_viewport(UNPACK4(viewport)); - GPU_scissor(UNPACK4(viewport)); - GPU_scissor_test(false); - - /* 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 */ - if (mode == GPU_SELECT_ALL) { - /* glQueries on Windows+Intel drivers only works with depth testing turned on. - * See T62947 for details */ - GPU_depth_test(GPU_DEPTH_ALWAYS); - GPU_depth_mask(true); - } - else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) { - GPU_depth_test(GPU_DEPTH_LESS_EQUAL); - GPU_depth_mask(true); - GPU_clear_depth(1.0f); - } - else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) { - GPU_depth_test(GPU_DEPTH_EQUAL); - GPU_depth_mask(false); - } -} - -bool gpu_select_query_load_id(uint id) -{ - if (g_query_state.query_issued) { - glEndQuery(GL_SAMPLES_PASSED); - } - /* if required, allocate extra queries */ - if (g_query_state.active_query == g_query_state.num_of_queries) { - g_query_state.num_of_queries += ALLOC_QUERIES; - g_query_state.queries = MEM_reallocN( - g_query_state.queries, g_query_state.num_of_queries * sizeof(*g_query_state.queries)); - g_query_state.id = MEM_reallocN(g_query_state.id, - g_query_state.num_of_queries * sizeof(*g_query_state.id)); - glGenQueries(ALLOC_QUERIES, &g_query_state.queries[g_query_state.active_query]); - } - - glBeginQuery(GL_SAMPLES_PASSED, g_query_state.queries[g_query_state.active_query]); - g_query_state.id[g_query_state.active_query] = id; - g_query_state.active_query++; - g_query_state.query_issued = true; - - if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) { - /* Second pass should never run if first pass fails, can read past 'bufsize' in this case. */ - BLI_assert(g_query_state.oldhits != -1); - if (g_query_state.index < g_query_state.oldhits) { - if (g_query_state.buffer[g_query_state.index][3] == id) { - g_query_state.index++; - return true; - } - - return false; - } - } - - return true; -} - -uint gpu_select_query_end(void) -{ - int i; - - uint hits = 0; - const uint maxhits = g_query_state.bufsize; - - if (g_query_state.query_issued) { - glEndQuery(GL_SAMPLES_PASSED); - } - - for (i = 0; i < g_query_state.active_query; i++) { - uint result = 0; - /* We are not using GL_QUERY_RESULT_AVAILABLE and sleep to wait for results, - * because it causes lagging on Windows/NVIDIA, see T61474. */ - glGetQueryObjectuiv(g_query_state.queries[i], GL_QUERY_RESULT, &result); - if (result > 0) { - if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) { - - if (hits < maxhits) { - g_query_state.buffer[hits][0] = 1; - g_query_state.buffer[hits][1] = 0xFFFF; - g_query_state.buffer[hits][2] = 0xFFFF; - g_query_state.buffer[hits][3] = g_query_state.id[i]; - - hits++; - } - else { - hits = -1; - break; - } - } - else { - int j; - /* search in buffer and make selected object first */ - for (j = 0; j < g_query_state.oldhits; j++) { - if (g_query_state.buffer[j][3] == g_query_state.id[i]) { - g_query_state.buffer[j][1] = 0; - g_query_state.buffer[j][2] = 0; - } - } - break; - } - } - } - - glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries); - MEM_freeN(g_query_state.queries); - MEM_freeN(g_query_state.id); - - 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_select_sample_query.cc b/source/blender/gpu/intern/gpu_select_sample_query.cc new file mode 100644 index 00000000000..1b54cbff5dd --- /dev/null +++ b/source/blender/gpu/intern/gpu_select_sample_query.cc @@ -0,0 +1,201 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2014 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * Interface for accessing gpu-related methods for selection. The semantics will be + * similar to glRenderMode(GL_SELECT) since the goal is to maintain compatibility. + */ + +#include + +#include "GPU_framebuffer.h" +#include "GPU_select.h" +#include "GPU_state.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_rect.h" + +#include "BLI_bitmap.h" +#include "BLI_utildefines.h" +#include "BLI_vector.hh" + +#include "gpu_backend.hh" +#include "gpu_query.hh" + +#include "gpu_select_private.h" + +using namespace blender; +using namespace blender::gpu; + +typedef struct GPUSelectQueryState { + /* Tracks whether a query has been issued so that gpu_load_id can end the previous one */ + bool query_issued; + /* GPU queries abstraction. Contains an array of queries. */ + QueryPool *queries; + /* Array holding the id corresponding id to each query. */ + Vector *ids; + /* cache on initialization */ + uint (*buffer)[4]; + /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/ + uint bufsize; + /* mode of operation */ + char mode; + uint index; + int oldhits; + + /* Previous state to restore after drawing. */ + int viewport[4]; + int scissor[4]; + eGPUWriteMask write_mask; + eGPUDepthTest depth_test; +} GPUSelectQueryState; + +static GPUSelectQueryState g_query_state = {0}; + +void gpu_select_query_begin( + uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits) +{ + g_query_state.query_issued = false; + g_query_state.bufsize = bufsize; + g_query_state.buffer = buffer; + g_query_state.mode = mode; + g_query_state.index = 0; + g_query_state.oldhits = oldhits; + + g_query_state.ids = new Vector(); + g_query_state.queries = GPUBackend::get()->querypool_alloc(); + g_query_state.queries->init(GPU_QUERY_OCCLUSION); + + g_query_state.write_mask = GPU_write_mask_get(); + g_query_state.depth_test = GPU_depth_test_get(); + GPU_scissor_get(g_query_state.scissor); + GPU_viewport_size_get_i(g_query_state.viewport); + + /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see T7997). */ + GPU_color_mask(true, true, true, true); + + /* In order to save some fill rate we minimize the viewport using rect. + * 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 */ + + int viewport[4] = { + UNPACK2(g_query_state.viewport), BLI_rcti_size_x(input), BLI_rcti_size_y(input)}; + + GPU_viewport(UNPACK4(viewport)); + GPU_scissor(UNPACK4(viewport)); + GPU_scissor_test(false); + + /* 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 */ + if (mode == GPU_SELECT_ALL) { + /* glQueries on Windows+Intel drivers only works with depth testing turned on. + * See T62947 for details */ + GPU_depth_test(GPU_DEPTH_ALWAYS); + GPU_depth_mask(true); + } + else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) { + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); + GPU_depth_mask(true); + GPU_clear_depth(1.0f); + } + else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) { + GPU_depth_test(GPU_DEPTH_EQUAL); + GPU_depth_mask(false); + } +} + +bool gpu_select_query_load_id(uint id) +{ + if (g_query_state.query_issued) { + g_query_state.queries->end_query(); + } + + g_query_state.queries->begin_query(); + g_query_state.ids->append(id); + g_query_state.query_issued = true; + + if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) { + /* Second pass should never run if first pass fails, can read past 'bufsize' in this case. */ + BLI_assert(g_query_state.oldhits != -1); + if (g_query_state.index < g_query_state.oldhits) { + if (g_query_state.buffer[g_query_state.index][3] == id) { + g_query_state.index++; + return true; + } + return false; + } + } + return true; +} + +uint gpu_select_query_end(void) +{ + uint hits = 0; + const uint maxhits = g_query_state.bufsize; + + if (g_query_state.query_issued) { + g_query_state.queries->end_query(); + } + + Span ids = *g_query_state.ids; + Vector result(ids.size()); + g_query_state.queries->get_occlusion_result(result); + + for (int i = 0; i < result.size(); i++) { + if (result[i] != 0) { + if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) { + if (hits < maxhits) { + g_query_state.buffer[hits][0] = 1; + g_query_state.buffer[hits][1] = 0xFFFF; + g_query_state.buffer[hits][2] = 0xFFFF; + g_query_state.buffer[hits][3] = ids[i]; + hits++; + } + else { + hits = -1; + break; + } + } + else { + int j; + /* search in buffer and make selected object first */ + for (j = 0; j < g_query_state.oldhits; j++) { + if (g_query_state.buffer[j][3] == ids[i]) { + g_query_state.buffer[j][1] = 0; + g_query_state.buffer[j][2] = 0; + } + } + break; + } + } + } + + delete g_query_state.queries; + delete g_query_state.ids; + + 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/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index 0c759d2cd62..94ac1692108 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -32,6 +32,7 @@ #include "gl_drawlist.hh" #include "gl_framebuffer.hh" #include "gl_index_buffer.hh" +#include "gl_query.hh" #include "gl_shader.hh" #include "gl_texture.hh" #include "gl_uniform_buffer.hh" @@ -95,6 +96,11 @@ class GLBackend : public GPUBackend { return new GLIndexBuf(); }; + QueryPool *querypool_alloc(void) override + { + return new GLQueryPool(); + }; + Shader *shader_alloc(const char *name) override { return new GLShader(name); diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index f05029c7075..8bce0d2e345 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -68,13 +68,13 @@ class GLContext : public GPUContext { static bool unused_fb_slot_workaround; static float derivative_signs[2]; + /** VBO for missing vertex attrib binding. Avoid undefined behavior on some implementation. */ + GLuint default_attr_vbo_; + /** Used for debugging purpose. Bitflags of all bound slots. */ uint16_t bound_ubo_slots; - /* TODO(fclem) these needs to become private. */ - public: - /** VBO for missing vertex attrib binding. Avoid undefined behavior on some implementation. */ - GLuint default_attr_vbo_; + private: /** * GPUBatch & GPUFramebuffer have references to the context they are from, in the case the * context is destroyed, we need to remove any reference to it. @@ -112,12 +112,12 @@ class GLContext : public GPUContext { static void buf_free(GLuint buf_id); static void tex_free(GLuint tex_id); - /* TODO(fclem) these needs to become private. */ - public: - static void orphans_add(Vector &orphan_list, std::mutex &list_mutex, GLuint id); - void orphans_clear(void); void vao_cache_register(GLVaoCache *cache); void vao_cache_unregister(GLVaoCache *cache); + + private: + static void orphans_add(Vector &orphan_list, std::mutex &list_mutex, GLuint id); + void orphans_clear(void); }; } // namespace gpu diff --git a/source/blender/gpu/opengl/gl_query.cc b/source/blender/gpu/opengl/gl_query.cc new file mode 100644 index 00000000000..6da5cacfcb2 --- /dev/null +++ b/source/blender/gpu/opengl/gl_query.cc @@ -0,0 +1,78 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "gl_query.hh" + +namespace blender::gpu { + +#define QUERY_CHUNCK_LEN 256 + +GLQueryPool::~GLQueryPool() +{ + glDeleteQueries(query_ids_.size(), query_ids_.data()); +} + +void GLQueryPool::init(GPUQueryType type) +{ + BLI_assert(initialized_ == false); + initialized_ = true; + type_ = type; + gl_type_ = to_gl(type); + query_issued_ = 0; +} + +#if 0 /* TODO to avoid realloc of permanent query pool. */ +void GLQueryPool::reset(GPUQueryType type) +{ + initialized_ = false; +} +#endif + +void GLQueryPool::begin_query(void) +{ + /* TODO add assert about expected usage. */ + while (query_issued_ >= query_ids_.size()) { + int64_t prev_size = query_ids_.size(); + query_ids_.resize(prev_size + QUERY_CHUNCK_LEN); + glGenQueries(QUERY_CHUNCK_LEN, &query_ids_[prev_size]); + } + glBeginQuery(gl_type_, query_ids_[query_issued_++]); +} + +void GLQueryPool::end_query(void) +{ + /* TODO add assert about expected usage. */ + glEndQuery(gl_type_); +} + +void GLQueryPool::get_occlusion_result(MutableSpan r_values) +{ + BLI_assert(r_values.size() == query_issued_); + + for (int i = 0; i < query_issued_; i++) { + /* Note: This is a sync point. */ + glGetQueryObjectuiv(query_ids_[i], GL_QUERY_RESULT, &r_values[i]); + } +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/opengl/gl_query.hh b/source/blender/gpu/opengl/gl_query.hh new file mode 100644 index 00000000000..fc54c0ee1dd --- /dev/null +++ b/source/blender/gpu/opengl/gl_query.hh @@ -0,0 +1,69 @@ +/* + * 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. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "BLI_vector.hh" + +#include "gpu_query.hh" + +#include "glew-mx.h" + +namespace blender::gpu { + +class GLQueryPool : public QueryPool { + private: + /** Contains queries object handles. */ + Vector query_ids_; + /** Type of this query pool. */ + GPUQueryType type_; + /** Associated GL type. */ + GLenum gl_type_; + /** Number of queries that have been issued since last initialization. + * Should be equal to query_ids_.size(). */ + uint32_t query_issued_; + /** Can only be initialized once. */ + bool initialized_ = false; + + public: + ~GLQueryPool(); + + void init(GPUQueryType type) override; + + void begin_query(void) override; + void end_query(void) override; + + void get_occlusion_result(MutableSpan r_values) override; +}; + +static inline GLenum to_gl(GPUQueryType type) +{ + if (type == GPU_QUERY_OCCLUSION) { + /* TODO(fclem) try with GL_ANY_SAMPLES_PASSED​. */ + return GL_SAMPLES_PASSED; + } + BLI_assert(0); + return GL_SAMPLES_PASSED; +} + +} // namespace blender::gpu \ No newline at end of file -- cgit v1.2.3 From bedc68a83881b209b399bb5135fb08b0968b145a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 09:10:17 +1000 Subject: Cleanup: consistent syntax for doxygen parameters Also use back-slash instead of '@'. --- intern/guardedalloc/MEM_guardedalloc.h | 2 +- source/blender/blenkernel/intern/collection.c | 10 ++++----- source/blender/blenkernel/intern/lib_override.c | 24 +++++++++++----------- source/blender/blenkernel/intern/unit.c | 2 +- source/blender/editors/interface/interface_panel.c | 2 +- source/blender/gpu/intern/gpu_texture.cc | 4 ++-- source/blender/gpu/opengl/gl_framebuffer.hh | 14 ++++++------- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index c05bda030ad..71d3c512306 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -165,7 +165,7 @@ extern void (*MEM_set_error_callback)(void (*func)(const char *)); /** * Are the start/end block markers still correct ? * - * @retval true for correct memory, false for corrupted memory. */ + * \retval true for correct memory, false for corrupted memory. */ extern bool (*MEM_consistency_check)(void); /** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */ diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 8975be2b618..836ce542793 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -1182,10 +1182,10 @@ static bool collection_instance_find_recursive(Collection *collection, /** * Find potential cycles in collections. * - * \param new_ancestor the potential new owner of given \a collection, or the collection to check - * if the later is NULL. - * \param collection the collection we want to add to \a new_ancestor, may be NULL if we just want - * to ensure \a new_ancestor does not already have cycles. + * \param new_ancestor: the potential new owner of given \a collection, + * or the collection to check if the later is NULL. + * \param collection: the collection we want to add to \a new_ancestor, + * may be NULL if we just want to ensure \a new_ancestor does not already have cycles. * \return true if a cycle is found. */ bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection) @@ -1254,7 +1254,7 @@ static bool collection_cycle_fix_recursive(Main *bmain, /** * Find and fix potential cycles in collections. * - * \param collection the collection to check for existing cycles. + * \param collection: The collection to check for existing cycles. * \return true if cycles are found and fixed. */ bool BKE_collection_cycles_fix(Main *bmain, Collection *collection) diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 2908ef133f0..48ecbcae90c 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -409,9 +409,9 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain, * * This will include all local IDs, and all IDs from the same library as the \a id_root. * - * \param id_root The root of the hierarchy of dependencies to be tagged. - * \param do_create_main_relashionships Whether main relations needs to be created or already exist - * (in any case, they will be freed by this function). + * \param id_root: The root of the hierarchy of dependencies to be tagged. + * \param do_create_main_relashionships: Whether main relations needs to be created or already + * exist (in any case, they will be freed by this function). */ void BKE_lib_override_library_dependencies_tag(Main *bmain, ID *id_root, @@ -435,9 +435,9 @@ void BKE_lib_override_library_dependencies_tag(Main *bmain, * That is, all other liboverrides IDs (in)directly used by \a is_root one, sharing the same * library for their reference IDs. * - * \param id_root The root of the hierarchy of liboverride dependencies to be tagged. - * \param do_create_main_relashionships Whether main relations needs to be created or already exist - * (in any case, they will be freed by this function). + * \param id_root: The root of the hierarchy of liboverride dependencies to be tagged. + * \param do_create_main_relashionships: Whether main relations needs to be created or already + * exist (in any case, they will be freed by this function). */ void BKE_lib_override_library_override_group_tag(Main *bmain, ID *id_root, @@ -640,10 +640,10 @@ static void lib_override_library_create_post_process( * \note In the future that same function may be extended to support 'refresh' of overrides * (rebuilding overrides from linked data, trying to preserve local overrides already defined). * - * \param id_root The root ID to create an override from. - * \param id_reference some reference ID used to do some post-processing after overrides have been - * created, may be NULL. Typically, the Empty object instantiating the linked - * collection we override, currently. + * \param id_root: The root ID to create an override from. + * \param id_reference: Some reference ID used to do some post-processing after overrides have been + * created, may be NULL. Typically, the Empty object instantiating the linked + * collection we override, currently. * \return true if override was successfully created. */ bool BKE_lib_override_library_create( @@ -668,7 +668,7 @@ bool BKE_lib_override_library_create( * Advanced 'smart' function to resync, re-create fully functional overrides up-to-date with linked * data, from an existing override hierarchy. * - * \param id_root The root liboverride ID to resync from. + * \param id_root: The root liboverride ID to resync from. * \return true if override was successfully resynced. */ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root) @@ -790,7 +790,7 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_ * * \note All IDs tagged with `LIB_TAG_DOIT` will be deleted. * - * \param id_root The root liboverride ID to resync from. + * \param id_root: The root liboverride ID to resync from. */ void BKE_lib_override_library_delete(Main *bmain, ID *id_root) { diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index c5782d846bb..babb4965b1e 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -1099,7 +1099,7 @@ double bUnit_ApplyPreferredUnit(const struct UnitSettings *settings, int type, d * Values will be split by an add sign. * 5'2" -> 5*0.3048 + 2*0.0254 * - * \param str_prev is optional, when valid it is used to get a base unit when none is set. + * \param str_prev: is optional, when valid it is used to get a base unit when none is set. * * \return True of a change was made. */ diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index cf0bb8d4e8c..5c4877534f6 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -2074,7 +2074,7 @@ static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was * Supposing the block has a panel and isn't a menu, handle opening, closing, pinning, etc. * Code currently assumes layout style for location of widgets * - * \param mx The mouse x coordinate, in panel space. + * \param mx: The mouse x coordinate, in panel space. */ static void ui_handle_panel_header(const bContext *C, uiBlock *block, diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index ad9b690683c..0aa1a6553f9 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -365,8 +365,8 @@ void *GPU_texture_read(GPUTexture *tex_, eGPUDataFormat data_format, int miplvl) * Fills the whole texture with the same data for all pixels. * \warning Only work for 2D texture for now. * \warning Only clears the mip 0 of the texture. - * \param data_format data format of the pixel data. - * \param data 1 pixel worth of data to fill the texture with. + * \param data_format: data format of the pixel data. + * \param data: 1 pixel worth of data to fill the texture with. */ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data) { diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh index 73423425500..755f3f97567 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.hh +++ b/source/blender/gpu/opengl/gl_framebuffer.hh @@ -63,13 +63,13 @@ class GLFrameBuffer : public FrameBuffer { GLFrameBuffer(const char *name); /** - * Special Framebuffer encapsulating internal window framebuffer. - * (i.e.: GL_FRONT_LEFT, GL_BACK_RIGHT, ...) - * @param ctx context the handle is from. - * @param target the internal GL name (i.e: GL_BACK_LEFT). - * @param fbo the (optional) already created object for some implementation. Default is 0. - * @param w buffer width. - * @param h buffer height. + * Special frame-buffer encapsulating internal window frame-buffer. + * (i.e.: #GL_FRONT_LEFT, #GL_BACK_RIGHT, ...) + * \param ctx: context the handle is from. + * \param target: the internal GL name (i.e: #GL_BACK_LEFT). + * \param fbo: the (optional) already created object for some implementation. Default is 0. + * \param w: buffer width. + * \param h: buffer height. **/ GLFrameBuffer(const char *name, GLContext *ctx, GLenum target, GLuint fbo, int w, int h); -- cgit v1.2.3 From 38b1450848d89aae8b5888afdaf143b150ff3f1f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 09:23:02 +1000 Subject: Cleanup: tabs to spaces --- build_files/cmake/platform/platform_win32.cmake | 4 ++-- source/blender/blenkernel/intern/unit.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 007f77a583f..64e4b276610 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -149,8 +149,8 @@ include(build_files/cmake/platform/platform_win32_bundle_crt.cmake) remove_cc_flag("/MDd" "/MD" "/Zi") if(WITH_WINDOWS_PDB) - set(PDB_INFO_OVERRIDE_FLAGS "/Z7") - set(PDB_INFO_OVERRIDE_LINKER_FLAGS "/DEBUG /OPT:REF /OPT:ICF /INCREMENTAL:NO") + set(PDB_INFO_OVERRIDE_FLAGS "/Z7") + set(PDB_INFO_OVERRIDE_LINKER_FLAGS "/DEBUG /OPT:REF /OPT:ICF /INCREMENTAL:NO") endif() if(MSVC_CLANG) # Clangs version of cl doesn't support all flags diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index babb4965b1e..f4a280581f3 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -80,7 +80,7 @@ #define UN_SC_LB 0.45359237f #define UN_SC_OZ 0.028349523125f -#define UN_SC_FAH 0.555555555555f +#define UN_SC_FAH 0.555555555555f /* clang-format on */ @@ -334,15 +334,15 @@ static struct bUnitCollection buPowerCollection = {buPowerDef, 3, 0, UNIT_COLLEC /* Temperature */ static struct bUnitDef buMetricTempDef[] = { {"kelvin", "kelvin", "K", NULL, "Kelvin", "KELVIN", 1.0f, 0.0, B_UNIT_DEF_NONE}, /* Base unit. */ - {"celsius", "celsius", "°C", "C", "Celsius", "CELCIUS", 1.0f, 273.15, B_UNIT_DEF_NONE}, - NULL_UNIT, + {"celsius", "celsius", "°C", "C", "Celsius", "CELCIUS", 1.0f, 273.15, B_UNIT_DEF_NONE}, + NULL_UNIT, }; static struct bUnitCollection buMetricTempCollection = {buMetricTempDef, 0, 0, UNIT_COLLECTION_LENGTH(buMetricTempDef)}; static struct bUnitDef buImperialTempDef[] = { {"kelvin", "kelvin", "K", NULL, "Kelvin", "KELVIN", 1.0f, 0.0, B_UNIT_DEF_NONE}, /* Base unit. */ - {"fahrenheit", "fahrenheit", "°F", "F", "Fahrenheit", "FAHRENHEIT", UN_SC_FAH, 459.67, B_UNIT_DEF_NONE}, - NULL_UNIT, + {"fahrenheit", "fahrenheit", "°F", "F", "Fahrenheit", "FAHRENHEIT", UN_SC_FAH, 459.67, B_UNIT_DEF_NONE}, + NULL_UNIT, }; static struct bUnitCollection buImperialTempCollection = { buImperialTempDef, 1, 0, UNIT_COLLECTION_LENGTH(buImperialTempDef)}; -- cgit v1.2.3 From 80d134b6d102d604e5b977219997975abf429018 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 09:28:43 +1000 Subject: Cleanup: remove unused source file FX_shader_light.c was added by accident in 66da2f537ae80ce2. --- source/blender/shader_fx/intern/FX_shader_light.c | 106 ---------------------- 1 file changed, 106 deletions(-) delete mode 100644 source/blender/shader_fx/intern/FX_shader_light.c diff --git a/source/blender/shader_fx/intern/FX_shader_light.c b/source/blender/shader_fx/intern/FX_shader_light.c deleted file mode 100644 index 2fd93bff8aa..00000000000 --- a/source/blender/shader_fx/intern/FX_shader_light.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2018, Blender Foundation - * This is a new part of Blender - */ - -/** \file - * \ingroup shader_fx - */ - -#include - -#include "DNA_gpencil_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" - -#include "BLI_utildefines.h" - -#include "BKE_context.h" -#include "BKE_lib_query.h" -#include "BKE_modifier.h" -#include "BKE_screen.h" -#include "BKE_shader_fx.h" - -#include "UI_interface.h" -#include "UI_resources.h" - -#include "RNA_access.h" - -#include "FX_shader_types.h" -#include "FX_ui_common.h" - -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_build.h" - -static void initData(ShaderFxData *fx) -{ - LightShaderFxData *gpfx = (LightShaderFxData *)fx; - gpfx->energy = 10.0f; - gpfx->ambient = 5.0f; - gpfx->object = NULL; -} - -static void copyData(const ShaderFxData *md, ShaderFxData *target) -{ - BKE_shaderfx_copydata_generic(md, target); -} - -static void updateDepsgraph(ShaderFxData *md, const ModifierUpdateDepsgraphContext *ctx) -{ - LightShaderFxData *fxd = (LightShaderFxData *)md; - if (fxd->object != NULL) { - DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_TRANSFORM, "Light ShaderFx"); - } - DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Light ShaderFx"); -} - -static bool isDisabled(ShaderFxData *fx, int UNUSED(userRenderParams)) -{ - LightShaderFxData *fxd = (LightShaderFxData *)fx; - - return !fxd->object; -} - -static void foreachObjectLink(ShaderFxData *fx, - Object *ob, - ShaderFxObjectWalkFunc walk, - void *userData) -{ - LightShaderFxData *fxd = (LightShaderFxData *)fx; - - walk(userData, ob, &fxd->object, IDWALK_CB_NOP); -} - -ShaderFxTypeInfo shaderfx_Type_Light = { - /* name */ "Light", - /* structName */ "LightShaderFxData", - /* structSize */ sizeof(LightShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, - - /* copyData */ copyData, - - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachObjectLink */ foreachObjectLink, - /* foreachIDLink */ NULL, - /* panelRegister */ NULL, -}; -- cgit v1.2.3 From f23400490e236ebbb01e6d2abfae6d8041aac2b1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 10:41:12 +1000 Subject: Cleanup: doxygen syntax for idtype.c --- source/blender/blenkernel/intern/idtype.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c index 4ab7d362e0e..6ef3817bc1c 100644 --- a/source/blender/blenkernel/intern/idtype.c +++ b/source/blender/blenkernel/intern/idtype.c @@ -155,10 +155,10 @@ static const IDTypeInfo *idtype_get_info_from_name(const char *idtype_name) return NULL; } -/* Various helpers/wrappers around IDTypeInfo structure. */ +/* Various helpers/wrappers around #IDTypeInfo structure. */ /** - * Convert an idcode into a name. + * Convert an \a idcode into a name. * * \param idcode: The code to convert. * \return A static string representing the name of @@ -172,7 +172,7 @@ const char *BKE_idtype_idcode_to_name(const short idcode) } /** - * Convert an idcode into a name (plural). + * Convert an \a idcode into a name (plural). * * \param idcode: The code to convert. * \return A static string representing the name of @@ -186,7 +186,7 @@ const char *BKE_idtype_idcode_to_name_plural(const short idcode) } /** - * Convert an idcode into its translations' context. + * Convert an \a idcode into its translations' context. * * \param idcode: The code to convert. * \return A static string representing the i18n context of the code. @@ -199,10 +199,10 @@ const char *BKE_idtype_idcode_to_translation_context(const short idcode) } /** - * Convert an IDType name into an idcode (ie. ID_SCE) + * Convert an ID-type name into an \a idcode (ie. #ID_SCE) * - * \param idtype_name: The IDType's 'user visible name' to convert. - * \return The idcode for the name, or 0 if invalid. + * \param idtype_name: The ID-type's "user visible name" to convert. + * \return The \a idcode for the name, or 0 if invalid. */ short BKE_idtype_idcode_from_name(const char *idtype_name) { @@ -236,7 +236,7 @@ bool BKE_idtype_idcode_is_linkable(const short idcode) } /** - * Convert an idcode into an idfilter (e.g. ID_OB -> FILTER_ID_OB). + * Convert an \a idcode into an \a idfilter (e.g. ID_OB -> FILTER_ID_OB). */ uint64_t BKE_idtype_idcode_to_idfilter(const short idcode) { @@ -288,7 +288,7 @@ uint64_t BKE_idtype_idcode_to_idfilter(const short idcode) } /** - * Convert an idfilter into an idcode (e.g. FILTER_ID_OB -> ID_OB). + * Convert an \a idfilter into an \a idcode (e.g. #FILTER_ID_OB -> #ID_OB). */ short BKE_idtype_idcode_from_idfilter(const uint64_t idfilter) { @@ -339,7 +339,7 @@ short BKE_idtype_idcode_from_idfilter(const uint64_t idfilter) } /** - * Convert an idcode into an index (e.g. ID_OB -> INDEX_ID_OB). + * Convert an \a idcode into an index (e.g. #ID_OB -> #INDEX_ID_OB). */ int BKE_idtype_idcode_to_index(const short idcode) { @@ -401,7 +401,7 @@ int BKE_idtype_idcode_to_index(const short idcode) } /** - * Get an idcode from an index (e.g. INDEX_ID_OB -> ID_OB). + * Get an \a idcode from an index (e.g. #INDEX_ID_OB -> #ID_OB). */ short BKE_idtype_idcode_from_index(const int index) { @@ -473,7 +473,9 @@ short BKE_idtype_idcode_iter_step(int *index) return (*index < ARRAY_SIZE(id_types)) ? BKE_idtype_idcode_from_index((*index)++) : 0; } -/** Wrapper around IDTypeInfo foreach_cache that also handles embedded IDs. */ +/** + * Wrapper around #IDTypeInfo foreach_cache that also handles embedded IDs. + */ void BKE_idtype_id_foreach_cache(struct ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data) -- cgit v1.2.3 From 77f60a09310dad0cb41e2e2ec4a71f9bdb762e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 00:10:37 +0200 Subject: GPUState: Encapsulate glFlush and glFinish inside the GLContext Part of the Vulkan task T68990 Isolate the few remaining gl functions. --- source/blender/gpu/intern/gpu_context_private.hh | 6 ++++++ source/blender/gpu/intern/gpu_state.cc | 4 ++-- source/blender/gpu/opengl/gl_context.cc | 16 ++++++++++++++++ source/blender/gpu/opengl/gl_context.hh | 4 ++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 3d92b4eb587..5344cc6fb87 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -76,6 +76,12 @@ struct GPUContext { virtual void activate(void) = 0; virtual void deactivate(void) = 0; + + /* Will push all pending commands to the GPU. */ + virtual void flush(void) = 0; + /* Will wait until the GPU has finished executing all command. */ + virtual void finish(void) = 0; + virtual void memory_statistics_get(int *total_mem, int *free_mem) = 0; bool is_active_on_thread(void); diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index 90c6efad2e8..a88dc1beb00 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -295,12 +295,12 @@ bool GPU_mipmap_enabled(void) void GPU_flush(void) { - glFlush(); + GPU_context_active_get()->flush(); } void GPU_finish(void) { - glFinish(); + GPU_context_active_get()->finish(); } void GPU_unpack_row_length_set(uint len) diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index 5633d28023a..1f7e191d394 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -160,6 +160,22 @@ void GLContext::deactivate(void) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Flush, Finish & sync + * \{ */ + +void GLContext::flush(void) +{ + glFlush(); +} + +void GLContext::finish(void) +{ + glFinish(); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Safe object deletion * diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index 8bce0d2e345..ef0c13719e2 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -97,6 +97,10 @@ class GLContext : public GPUContext { void activate(void) override; void deactivate(void) override; + + void flush(void); + void finish(void); + void memory_statistics_get(int *total_mem, int *free_mem) override; static inline GLStateManager *state_manager_active_get() -- cgit v1.2.3 From 28ea459a61f65de03724db8709271d41f6bf135b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 00:30:38 +0200 Subject: GPUState: Encapsulate glPixelStorei inside the GLStateManager Part of the Vulkan task T68990 Isolate the last remaining gl functions. --- source/blender/gpu/GPU_state.h | 1 - source/blender/gpu/GPU_texture.h | 1 + source/blender/gpu/intern/gpu_state.cc | 5 ----- source/blender/gpu/intern/gpu_state_private.hh | 2 ++ source/blender/gpu/intern/gpu_texture.cc | 7 +++++++ source/blender/gpu/opengl/gl_state.cc | 5 +++++ source/blender/gpu/opengl/gl_state.hh | 2 ++ 7 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h index 869e8c32861..5e872001267 100644 --- a/source/blender/gpu/GPU_state.h +++ b/source/blender/gpu/GPU_state.h @@ -128,7 +128,6 @@ 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_unpack_row_length_set(uint len); void GPU_shadow_offset(bool enable); void GPU_clip_distances(int distances_enabled); bool GPU_mipmap_enabled(void); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index bae5bfbaae8..b31cb42d38d 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -228,6 +228,7 @@ void GPU_texture_update_sub(GPUTexture *tex, int width, int height, int depth); +void GPU_unpack_row_length_set(uint len); void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl); void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data); diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index a88dc1beb00..68f0c290bc6 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -303,11 +303,6 @@ void GPU_finish(void) GPU_context_active_get()->finish(); } -void GPU_unpack_row_length_set(uint len) -{ - glPixelStorei(GL_UNPACK_ROW_LENGTH, len); -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh index 6ce240df108..9fee45e7bd4 100644 --- a/source/blender/gpu/intern/gpu_state_private.hh +++ b/source/blender/gpu/intern/gpu_state_private.hh @@ -166,6 +166,8 @@ class GPUStateManager { virtual void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) = 0; virtual void texture_unbind(Texture *tex) = 0; virtual void texture_unbind_all(void) = 0; + + virtual void texture_unpack_row_length_set(uint len) = 0; }; } // namespace gpu diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 0aa1a6553f9..95f922173b5 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -380,6 +380,13 @@ void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void reinterpret_cast(tex)->update(data_format, data); } +/* Makes data interpretation aware of the source layout. + * Skipping pixels correctly when changing rows when doing partial update.*/ +void GPU_unpack_row_length_set(uint len) +{ + GPU_context_active_get()->state_manager->texture_unpack_row_length_set(len); +} + void GPU_invalid_tex_init(void) { /* TODO remove */ diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index b43b01aed4f..6dcb56288e8 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -520,6 +520,11 @@ void GLStateManager::texture_bind_apply(void) } } +void GLStateManager::texture_unpack_row_length_set(uint len) +{ + glPixelStorei(GL_UNPACK_ROW_LENGTH, len); +} + uint64_t GLStateManager::bound_texture_slots(void) { uint64_t bound_slots = 0; diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh index d5622b4ab89..db9b9721ad5 100644 --- a/source/blender/gpu/opengl/gl_state.hh +++ b/source/blender/gpu/opengl/gl_state.hh @@ -74,6 +74,8 @@ class GLStateManager : public GPUStateManager { void texture_unbind(Texture *tex) override; void texture_unbind_all(void) override; + void texture_unpack_row_length_set(uint len) override; + uint64_t bound_texture_slots(void); private: -- cgit v1.2.3 From ca8ffc523e3d08fc55c5cf000fa9fc3888950bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 03:15:06 +0200 Subject: fix flush --- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/draw/intern/draw_manager_shader.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 8d69ed05fc6..f7c126d2e99 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2862,7 +2862,6 @@ void DRW_opengl_render_context_enable(void *re_gl_context) void DRW_opengl_render_context_disable(void *re_gl_context) { - GPU_flush(); WM_opengl_context_release(re_gl_context); /* TODO get rid of the blocking. */ BLI_ticket_mutex_unlock(DST.gl_context_mutex); @@ -2880,6 +2879,7 @@ void DRW_gpu_render_context_enable(void *re_gpu_context) /* Needs to be called BEFORE DRW_opengl_render_context_disable() */ void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context)) { + GPU_flush(); GPU_context_active_set(NULL); } diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 7eeb5a2fb67..85c04b73529 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -29,6 +29,7 @@ #include "BLI_string_utils.h" #include "BLI_threads.h" +#include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" @@ -41,6 +42,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "wm_window.h" + #include "draw_manager.h" extern char datatoc_gpu_shader_2D_vert_glsl[]; @@ -73,6 +76,7 @@ typedef struct DRWShaderCompiler { ThreadMutex compilation_lock; void *gl_context; + GPUContext *gpu_context; bool own_context; int shaders_done; /* To compute progress. */ @@ -102,10 +106,10 @@ static void drw_deferred_shader_compilation_exec( { DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data; void *gl_context = comp->gl_context; + GPUContext *gpu_context = comp->gpu_context; -#if TRUST_NO_ONE BLI_assert(gl_context != NULL); -#endif + BLI_assert(gpu_context != NULL); const bool use_main_context_workaround = GPU_use_main_context_workaround(); if (use_main_context_workaround) { @@ -114,6 +118,7 @@ static void drw_deferred_shader_compilation_exec( } WM_opengl_context_activate(gl_context); + GPU_context_active_set(gpu_context); while (true) { BLI_spin_lock(&comp->list_lock); @@ -160,6 +165,7 @@ static void drw_deferred_shader_compilation_exec( BLI_spin_unlock(&comp->list_lock); } + GPU_context_active_set(NULL); WM_opengl_context_release(gl_context); if (use_main_context_workaround) { GPU_context_main_unlock(); @@ -188,7 +194,12 @@ static void drw_deferred_shader_compilation_free(void *custom_data) if (comp->own_context) { /* Only destroy if the job owns the context. */ + WM_opengl_context_activate(comp->gl_context); + GPU_context_active_set(comp->gpu_context); + GPU_context_discard(comp->gpu_context); WM_opengl_context_dispose(comp->gl_context); + + wm_window_reset_drawable(); } MEM_freeN(comp); @@ -238,6 +249,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) /* Do not recreate context, just pass ownership. */ if (old_comp->gl_context) { comp->gl_context = old_comp->gl_context; + comp->gpu_context = old_comp->gpu_context; old_comp->own_context = false; comp->own_context = job_own_context; } @@ -249,10 +261,15 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) if (comp->gl_context == NULL) { if (use_main_context) { comp->gl_context = DST.gl_context; + comp->gpu_context = DST.gpu_context; } else { comp->gl_context = WM_opengl_context_create(); + comp->gpu_context = GPU_context_create(NULL); + GPU_context_active_set(NULL); + WM_opengl_context_activate(DST.gl_context); + GPU_context_active_set(DST.gpu_context); } comp->own_context = job_own_context; } -- cgit v1.2.3 From ccc512cc619dc9f0e6fd79270a7a96ece34d23b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 03:18:49 +0200 Subject: GPUImmediate: Make activation / deactivation implicit This avoids unecessary complexity. Also makes the GPUImmediate threadsafe by using a threadlocal imm variable. --- intern/ghost/test/multitest/MultiTest.c | 1 - source/blender/draw/intern/draw_manager.c | 18 +----------------- source/blender/gpu/GPU_immediate.h | 6 ------ source/blender/gpu/intern/gpu_immediate.cc | 12 +----------- source/blender/gpu/intern/gpu_immediate_private.hh | 5 ++++- source/blender/gpu/intern/gpu_init_exit.c | 8 -------- source/blender/gpu/opengl/gl_context.cc | 4 ++++ source/blender/windowmanager/intern/wm_playanim.c | 3 --- source/blender/windowmanager/intern/wm_surface.c | 3 --- source/blender/windowmanager/intern/wm_window.c | 2 -- 10 files changed, 10 insertions(+), 52 deletions(-) diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c index cf7a06bf3e5..b6b83f2a47d 100644 --- a/intern/ghost/test/multitest/MultiTest.c +++ b/intern/ghost/test/multitest/MultiTest.c @@ -439,7 +439,6 @@ static void loggerwindow_do_draw(LoggerWindow *lw) GHOST_ActivateWindowDrawingContext(lw->win); GPU_context_active_set(lw->gpu_context); - immActivate(); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index f7c126d2e99..d2a95f9b7b3 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2767,17 +2767,11 @@ void DRW_opengl_context_create(void) BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */ DST.gl_context_mutex = BLI_ticket_mutex_alloc(); - if (!G.background) { - immDeactivate(); - } /* This changes the active context. */ DST.gl_context = WM_opengl_context_create(); WM_opengl_context_activate(DST.gl_context); /* Be sure to create gpu_context too. */ DST.gpu_context = GPU_context_create(0); - if (!G.background) { - immActivate(); - } /* So we activate the window's one afterwards. */ wm_window_reset_drawable(); } @@ -2794,25 +2788,15 @@ void DRW_opengl_context_destroy(void) } } -void DRW_opengl_context_enable_ex(bool restore) +void DRW_opengl_context_enable_ex(bool UNUSED(restore)) { if (DST.gl_context != NULL) { /* IMPORTANT: We dont support immediate mode in render mode! * This shall remain in effect until immediate mode supports * multiple threads. */ BLI_ticket_mutex_lock(DST.gl_context_mutex); - if (BLI_thread_is_main() && restore) { - if (!G.background) { - immDeactivate(); - } - } WM_opengl_context_activate(DST.gl_context); GPU_context_active_set(DST.gpu_context); - if (BLI_thread_is_main() && restore) { - if (!G.background) { - immActivate(); - } - } } } diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h index 6057770d2d9..edb7c9fe5b5 100644 --- a/source/blender/gpu/GPU_immediate.h +++ b/source/blender/gpu/GPU_immediate.h @@ -145,12 +145,6 @@ void immUniformThemeColorBlendShade(int color_id1, int color_id2, float fac, int void immUniformThemeColorBlend(int color_id1, int color_id2, float fac); void immThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset); -/* These are called by the system -- not part of drawing API. */ -void immInit(void); -void immActivate(void); -void immDeactivate(void); -void immDestroy(void); - #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index dd3e5bea604..9fc5e03a796 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -39,12 +39,7 @@ using namespace blender::gpu; -static Immediate *imm = NULL; - -void immInit(void) -{ - /* TODO Remove */ -} +static thread_local Immediate *imm = NULL; void immActivate(void) { @@ -56,11 +51,6 @@ void immDeactivate(void) imm = NULL; } -void immDestroy(void) -{ - /* TODO Remove */ -} - GPUVertFormat *immVertexFormat(void) { GPU_vertformat_clear(&imm->vertex_format); diff --git a/source/blender/gpu/intern/gpu_immediate_private.hh b/source/blender/gpu/intern/gpu_immediate_private.hh index aa99fb9a438..38db8131942 100644 --- a/source/blender/gpu/intern/gpu_immediate_private.hh +++ b/source/blender/gpu/intern/gpu_immediate_private.hh @@ -63,4 +63,7 @@ class Immediate { virtual void end(void) = 0; }; -} // namespace blender::gpu \ No newline at end of file +} // namespace blender::gpu + +void immActivate(void); +void immDeactivate(void); \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 129a66994b1..0eb2fe57c28 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -54,10 +54,6 @@ void GPU_init(void) gpu_batch_init(); - if (!G.background) { - immInit(); - } - #ifndef GPU_STANDALONE gpu_pbvh_init(); #endif @@ -69,10 +65,6 @@ void GPU_exit(void) gpu_pbvh_exit(); #endif - if (!G.background) { - immDestroy(); - } - gpu_batch_exit(); gpu_material_library_exit(); diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index 1f7e191d394..30279ccade1 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -32,6 +32,7 @@ #include "GHOST_C-api.h" #include "gpu_context_private.hh" +#include "gpu_immediate_private.hh" #include "gl_debug.hh" #include "gl_immediate.hh" @@ -151,10 +152,13 @@ void GLContext::activate(void) /* Not really following the state but we should consider * no ubo bound when activating a context. */ bound_ubo_slots = 0; + + immActivate(); } void GLContext::deactivate(void) { + immDeactivate(); is_active_ = false; } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 86d3f7f35dc..e3c763930c0 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -1292,7 +1292,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv) /* initialize OpenGL immediate mode */ g_WS.gpu_context = GPU_context_create(g_WS.ghost_window); GPU_init(); - immActivate(); /* initialize the font */ BLF_init(); @@ -1579,8 +1578,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv) GPU_shader_free_builtin_shaders(); - immDeactivate(); - if (g_WS.gpu_context) { GPU_context_active_set(g_WS.gpu_context); GPU_context_discard(g_WS.gpu_context); diff --git a/source/blender/windowmanager/intern/wm_surface.c b/source/blender/windowmanager/intern/wm_surface.c index e8cb5d9cd7d..4139574460b 100644 --- a/source/blender/windowmanager/intern/wm_surface.c +++ b/source/blender/windowmanager/intern/wm_surface.c @@ -56,8 +56,6 @@ void wm_surface_clear_drawable(void) WM_opengl_context_release(g_drawable->ghost_ctx); GPU_context_active_set(NULL); - immDeactivate(); - if (g_drawable->deactivate) { g_drawable->deactivate(); } @@ -79,7 +77,6 @@ void wm_surface_set_drawable(wmSurface *surface, bool activate) } GPU_context_active_set(surface->gpu_ctx); - immActivate(); } void wm_surface_make_drawable(wmSurface *surface) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 0e19f79e659..795205b8200 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1099,13 +1099,11 @@ static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool acti GHOST_ActivateWindowDrawingContext(win->ghostwin); } GPU_context_active_set(win->gpuctx); - immActivate(); } void wm_window_clear_drawable(wmWindowManager *wm) { if (wm->windrawable) { - immDeactivate(); wm->windrawable = NULL; } } -- cgit v1.2.3 From a30ad3634d2ed489d0c285b2ea77bc1c69e23826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 03:19:15 +0200 Subject: Cleanup: DRW: Replace 0 by NULL in GPU_context_create calls This was left from a previous refactor. --- source/blender/draw/engines/eevee/eevee_lightcache.c | 2 +- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/draw/tests/shaders_test.cc | 2 +- source/blender/render/intern/source/pipeline.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 5a676bf4004..f23cca41215 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -526,7 +526,7 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake) if (lbake->gl_context) { DRW_opengl_render_context_enable(lbake->gl_context); if (lbake->gpu_context == NULL) { - lbake->gpu_context = GPU_context_create(0); + lbake->gpu_context = GPU_context_create(NULL); } DRW_gpu_render_context_enable(lbake->gpu_context); } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index d2a95f9b7b3..e6d51bce54e 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2771,7 +2771,7 @@ void DRW_opengl_context_create(void) DST.gl_context = WM_opengl_context_create(); WM_opengl_context_activate(DST.gl_context); /* Be sure to create gpu_context too. */ - DST.gpu_context = GPU_context_create(0); + DST.gpu_context = GPU_context_create(NULL); /* So we activate the window's one afterwards. */ wm_window_reset_drawable(); } diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index a3a0b792a24..b82746e4609 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -27,7 +27,7 @@ class DrawTest : public ::testing::Test { GHOST_GLSettings glSettings = {0}; ghost_system = GHOST_CreateSystem(); ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings); - context = GPU_context_create(0); + context = GPU_context_create(NULL); GPU_init(); DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 8c61fd5b971..2d581a4765e 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1113,7 +1113,7 @@ void *RE_gl_context_get(Render *re) void *RE_gpu_context_get(Render *re) { if (re->gpu_context == NULL) { - re->gpu_context = GPU_context_create(0); + re->gpu_context = GPU_context_create(NULL); } return re->gpu_context; } -- cgit v1.2.3 From 33b25b6a9e86082a40a24b14bb0a6aad708dfb11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 03:22:35 +0200 Subject: GPUTexture: Remove unused functions and avoid GPU_texture_opengl_bindcode This is a cleanup. --- source/blender/gpu/GPU_texture.h | 5 ----- source/blender/gpu/intern/gpu_framebuffer.cc | 5 ----- source/blender/gpu/intern/gpu_texture.cc | 25 ++++-------------------- source/blender/gpu/intern/gpu_texture_private.hh | 14 +++++++++++++ source/blender/gpu/opengl/gl_framebuffer.cc | 4 ++-- source/blender/gpu/opengl/gl_texture.hh | 1 + 6 files changed, 21 insertions(+), 33 deletions(-) diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index b31cb42d38d..f2ddb5d8a22 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -233,10 +233,6 @@ void GPU_unpack_row_length_set(uint len); void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl); void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data); -void GPU_invalid_tex_init(void); -void GPU_invalid_tex_bind(int mode); -void GPU_invalid_tex_free(void); - void GPU_texture_free(GPUTexture *tex); void GPU_texture_ref(GPUTexture *tex); @@ -262,7 +258,6 @@ int GPU_texture_orig_width(const GPUTexture *tex); int GPU_texture_orig_height(const GPUTexture *tex); void GPU_texture_orig_size_set(GPUTexture *tex, int w, int h); eGPUTextureFormat GPU_texture_format(const GPUTexture *tex); -int GPU_texture_samples(const GPUTexture *tex); bool GPU_texture_array(const GPUTexture *tex); bool GPU_texture_cube(const GPUTexture *tex); bool GPU_texture_depth(const GPUTexture *tex); diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index f9caa8df143..05cc8a30a43 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -455,11 +455,6 @@ void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, BLI_assert(GPU_texture_stencil(read_tex) && GPU_texture_stencil(write_tex)); BLI_assert(GPU_texture_format(read_tex) == GPU_texture_format(write_tex)); } - if (GPU_texture_samples(write_tex) != 0 || GPU_texture_samples(read_tex) != 0) { - /* Can only blit multisample textures to another texture of the same size. */ - BLI_assert((GPU_texture_width(write_tex) == GPU_texture_width(read_tex)) && - (GPU_texture_height(write_tex) == GPU_texture_height(read_tex))); - } #endif fb_read->blit_to(blit_buffers, read_slot, fb_write, write_slot, 0, 0); diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 95f922173b5..05b97129f00 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -190,7 +190,7 @@ uint GPU_texture_memory_usage_get(void) return 0; } -/* ------ Texture Creation ------ */ +/* ------ Creation ------ */ static inline GPUTexture *gpu_texture_create(const char *name, const int w, @@ -329,6 +329,8 @@ GPUTexture *GPU_texture_create_error(int dimension, bool is_array) return gpu_texture_create("invalid_tex", w, h, d, type, 1, GPU_RGBA8, pixel); } +/* ------ Update ------ */ + void GPU_texture_update_mipmap(GPUTexture *tex_, int miplvl, eGPUDataFormat data_format, @@ -387,20 +389,7 @@ void GPU_unpack_row_length_set(uint len) GPU_context_active_get()->state_manager->texture_unpack_row_length_set(len); } -void GPU_invalid_tex_init(void) -{ - /* TODO remove */ -} - -void GPU_invalid_tex_bind(int UNUSED(mode)) -{ - /* TODO remove */ -} - -void GPU_invalid_tex_free(void) -{ - /* TODO remove */ -} +/* ------ Binding ------ */ void GPU_texture_bind_ex(GPUTexture *tex_, eGPUSamplerState state, @@ -547,12 +536,6 @@ eGPUTextureFormat GPU_texture_format(const GPUTexture *tex) return reinterpret_cast(tex)->format_get(); } -/* TODO remove */ -int GPU_texture_samples(const GPUTexture *UNUSED(tex)) -{ - return 0; -} - bool GPU_texture_depth(const GPUTexture *tex) { return (reinterpret_cast(tex)->format_flag_get() & GPU_FORMAT_DEPTH) != 0; diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index d237540f654..19022b228b2 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -241,6 +241,20 @@ class Texture { virtual bool init_internal(GPUVertBuf *vbo) = 0; }; +/* Syntacting suggar. */ +static inline GPUTexture *wrap(Texture *vert) +{ + return reinterpret_cast(vert); +} +static inline Texture *unwrap(GPUTexture *vert) +{ + return reinterpret_cast(vert); +} +static inline const Texture *unwrap(const GPUTexture *vert) +{ + return reinterpret_cast(vert); +} + #undef DEBUG_NAME_LEN inline size_t to_bytesize(eGPUTextureFormat format) diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index d0644b356ac..61270fe0acc 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -187,7 +187,7 @@ void GLFrameBuffer::update_attachments(void) glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, 0, 0); continue; } - GLuint gl_tex = GPU_texture_opengl_bindcode(attach.tex); + GLuint gl_tex = static_cast(unwrap(attach.tex))->tex_id_; if (attach.layer > -1 && GPU_texture_cube(attach.tex) && !GPU_texture_array(attach.tex)) { /* Could be avoided if ARB_direct_state_access is required. In this case * #glFramebufferTextureLayer would bind the correct face. */ @@ -216,7 +216,7 @@ void GLFrameBuffer::update_attachments(void) GPUAttachmentType type = GPU_FB_COLOR_ATTACHMENT0 + i; GPUAttachment &attach = attachments_[type]; if (attach.tex != NULL) { - gl_tex = GPU_texture_opengl_bindcode(attach.tex); + gl_tex = static_cast(unwrap(attach.tex))->tex_id_; } else if (gl_tex != 0) { GLenum gl_attachment = to_gl(type); diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh index bdb8a4df4b7..13e546eb879 100644 --- a/source/blender/gpu/opengl/gl_texture.hh +++ b/source/blender/gpu/opengl/gl_texture.hh @@ -46,6 +46,7 @@ namespace gpu { class GLTexture : public Texture { friend class GLStateManager; + friend class GLFrameBuffer; private: /** All samplers states. */ -- cgit v1.2.3 From d2e9de93b8d1d6cd45abce8164d0f92af8f636d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 03:34:47 +0200 Subject: GPU: Cleanup implementation casts - Use the syntactic wrap/unwrap method to make code more readable. - Update comment about hidden struct behind opaque types. - Cleanup GPUDrawList type. --- source/blender/gpu/GPU_drawlist.h | 11 ++--- source/blender/gpu/GPU_framebuffer.h | 6 +-- source/blender/gpu/GPU_index_buffer.h | 6 +-- source/blender/gpu/GPU_texture.h | 2 + source/blender/gpu/GPU_uniform_buffer.h | 6 +-- source/blender/gpu/GPU_vertex_buffer.h | 1 + source/blender/gpu/intern/gpu_drawlist.cc | 16 +++---- source/blender/gpu/intern/gpu_drawlist_private.hh | 16 +++++++ source/blender/gpu/intern/gpu_framebuffer.cc | 51 ++++++++++------------ .../blender/gpu/intern/gpu_framebuffer_private.hh | 14 ++++++ source/blender/gpu/intern/gpu_shader.cc | 35 +++++++-------- source/blender/gpu/intern/gpu_shader_private.hh | 16 ++++++- source/blender/gpu/intern/gpu_texture_private.hh | 4 ++ source/blender/gpu/intern/gpu_uniform_buffer.cc | 12 ++--- .../gpu/intern/gpu_uniform_buffer_private.hh | 14 ++++++ .../gpu/intern/gpu_vertex_buffer_private.hh | 4 ++ 16 files changed, 134 insertions(+), 80 deletions(-) diff --git a/source/blender/gpu/GPU_drawlist.h b/source/blender/gpu/GPU_drawlist.h index 27f70da8cf8..485b90f48d4 100644 --- a/source/blender/gpu/GPU_drawlist.h +++ b/source/blender/gpu/GPU_drawlist.h @@ -32,14 +32,15 @@ extern "C" { struct GPUBatch; -typedef void *GPUDrawList; /* Opaque pointer. */ +/** Opaque type hiding blender::gpu::DrawList. */ +typedef struct GPUDrawList GPUDrawList; /* Create a list with at least length drawcalls. Length can affect performance. */ -GPUDrawList GPU_draw_list_create(int length); -void GPU_draw_list_discard(GPUDrawList list); +GPUDrawList *GPU_draw_list_create(int length); +void GPU_draw_list_discard(GPUDrawList *list); -void GPU_draw_list_append(GPUDrawList list, GPUBatch *batch, int i_first, int i_count); -void GPU_draw_list_submit(GPUDrawList list); +void GPU_draw_list_append(GPUDrawList *list, GPUBatch *batch, int i_first, int i_count); +void GPU_draw_list_submit(GPUDrawList *list); #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index c0391d96e06..be55cd7af2d 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -54,10 +54,8 @@ typedef enum eGPUBackBuffer { GPU_BACKBUFFER_RIGHT, } eGPUBackBuffer; -/** Opaque pointer hiding blender::gpu::FrameBuffer. */ -typedef struct GPUFrameBuffer { - void *dummy; -} GPUFrameBuffer; +/** Opaque type hiding blender::gpu::FrameBuffer. */ +typedef struct GPUFrameBuffer GPUFrameBuffer; typedef struct GPUOffScreen GPUOffScreen; diff --git a/source/blender/gpu/GPU_index_buffer.h b/source/blender/gpu/GPU_index_buffer.h index df24e07caef..0c71dd539a6 100644 --- a/source/blender/gpu/GPU_index_buffer.h +++ b/source/blender/gpu/GPU_index_buffer.h @@ -31,11 +31,7 @@ extern "C" { #endif -/** - * IMPORTANT: Do not allocate manually as the real struct is bigger (i.e: GLIndexBuf). This is only - * the common and "public" part of the struct. Use the provided allocator. - * TODO(fclem) Make the content of this struct hidden and expose getters/setters. - **/ +/** Opaque type hiding blender::gpu::IndexBuf. */ typedef struct GPUIndexBuf GPUIndexBuf; GPUIndexBuf *GPU_indexbuf_calloc(void); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index f2ddb5d8a22..2ce2ba093cf 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -36,6 +36,8 @@ struct MovieClipUser; struct PreviewImage; struct GPUFrameBuffer; + +/** Opaque type hiding blender::gpu::Texture. */ typedef struct GPUTexture GPUTexture; /* GPU Samplers state diff --git a/source/blender/gpu/GPU_uniform_buffer.h b/source/blender/gpu/GPU_uniform_buffer.h index 605e2b14434..ebcaa80e6f6 100644 --- a/source/blender/gpu/GPU_uniform_buffer.h +++ b/source/blender/gpu/GPU_uniform_buffer.h @@ -36,10 +36,8 @@ extern "C" { struct ListBase; -/** Opaque pointer hiding blender::gpu::UniformBuf. */ -typedef struct GPUUniformBuf { - void *dummy; -} GPUUniformBuf; +/** Opaque type hiding blender::gpu::UniformBuf. */ +typedef struct GPUUniformBuf GPUUniformBuf; GPUUniformBuf *GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name); GPUUniformBuf *GPU_uniformbuf_create_from_list(struct ListBase *inputs, const char *name); diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index 80f0501edc0..2af9929db35 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -61,6 +61,7 @@ typedef enum { GPU_USAGE_DYNAMIC, } GPUUsageType; +/** Opaque type hiding blender::gpu::VertBuf. */ typedef struct GPUVertBuf GPUVertBuf; GPUVertBuf *GPU_vertbuf_calloc(void); diff --git a/source/blender/gpu/intern/gpu_drawlist.cc b/source/blender/gpu/intern/gpu_drawlist.cc index 7b807a2fa80..ecea4f7c5e4 100644 --- a/source/blender/gpu/intern/gpu_drawlist.cc +++ b/source/blender/gpu/intern/gpu_drawlist.cc @@ -34,26 +34,26 @@ using namespace blender::gpu; -GPUDrawList GPU_draw_list_create(int list_length) +GPUDrawList *GPU_draw_list_create(int list_length) { DrawList *list_ptr = GPUBackend::get()->drawlist_alloc(list_length); - return reinterpret_cast(list_ptr); + return wrap(list_ptr); } -void GPU_draw_list_discard(GPUDrawList list) +void GPU_draw_list_discard(GPUDrawList *list) { - DrawList *list_ptr = reinterpret_cast(list); + DrawList *list_ptr = unwrap(list); delete list_ptr; } -void GPU_draw_list_append(GPUDrawList list, GPUBatch *batch, int i_first, int i_count) +void GPU_draw_list_append(GPUDrawList *list, GPUBatch *batch, int i_first, int i_count) { - DrawList *list_ptr = reinterpret_cast(list); + DrawList *list_ptr = unwrap(list); list_ptr->append(batch, i_first, i_count); } -void GPU_draw_list_submit(GPUDrawList list) +void GPU_draw_list_submit(GPUDrawList *list) { - DrawList *list_ptr = reinterpret_cast(list); + DrawList *list_ptr = unwrap(list); list_ptr->submit(); } diff --git a/source/blender/gpu/intern/gpu_drawlist_private.hh b/source/blender/gpu/intern/gpu_drawlist_private.hh index ddb09fb0c89..fd223c3f255 100644 --- a/source/blender/gpu/intern/gpu_drawlist_private.hh +++ b/source/blender/gpu/intern/gpu_drawlist_private.hh @@ -25,6 +25,8 @@ #include "MEM_guardedalloc.h" +#include "GPU_drawlist.h" + namespace blender { namespace gpu { @@ -40,5 +42,19 @@ class DrawList { virtual void submit() = 0; }; +/* Syntacting suggar. */ +static inline GPUDrawList *wrap(DrawList *vert) +{ + return reinterpret_cast(vert); +} +static inline DrawList *unwrap(GPUDrawList *vert) +{ + return reinterpret_cast(vert); +} +static inline const DrawList *unwrap(const GPUDrawList *vert) +{ + return reinterpret_cast(vert); +} + } // namespace gpu } // namespace blender diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index 05cc8a30a43..e548eb241cf 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -194,21 +194,20 @@ GPUFrameBuffer *GPU_framebuffer_create(const char *name) { /* We generate the FB object later at first use in order to * create the frame-buffer in the right opengl context. */ - return (GPUFrameBuffer *)GPUBackend::get()->framebuffer_alloc(name); + return wrap(GPUBackend::get()->framebuffer_alloc(name)); } void GPU_framebuffer_free(GPUFrameBuffer *gpu_fb) { - delete reinterpret_cast(gpu_fb); + delete unwrap(gpu_fb); } /* ---------- Binding ----------- */ void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb) { - FrameBuffer *fb = reinterpret_cast(gpu_fb); const bool enable_srgb = true; - fb->bind(enable_srgb); + unwrap(gpu_fb)->bind(enable_srgb); } /** @@ -216,9 +215,8 @@ void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb) */ void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *gpu_fb) { - FrameBuffer *fb = reinterpret_cast(gpu_fb); const bool enable_srgb = false; - fb->bind(enable_srgb); + unwrap(gpu_fb)->bind(enable_srgb); } /** @@ -244,14 +242,14 @@ void GPU_framebuffer_restore(void) GPUFrameBuffer *GPU_framebuffer_active_get(void) { GPUContext *ctx = GPU_context_active_get(); - return reinterpret_cast(ctx ? ctx->active_fb : NULL); + return wrap(ctx ? ctx->active_fb : NULL); } /* Returns the default frame-buffer. Will always exists even if it's just a dummy. */ GPUFrameBuffer *GPU_framebuffer_back_get(void) { GPUContext *ctx = GPU_context_active_get(); - return reinterpret_cast(ctx ? ctx->back_left : NULL); + return wrap(ctx ? ctx->back_left : NULL); } bool GPU_framebuffer_bound(GPUFrameBuffer *gpu_fb) @@ -263,14 +261,14 @@ bool GPU_framebuffer_bound(GPUFrameBuffer *gpu_fb) bool GPU_framebuffer_check_valid(GPUFrameBuffer *gpu_fb, char err_out[256]) { - return reinterpret_cast(gpu_fb)->check(err_out); + return unwrap(gpu_fb)->check(err_out); } void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment attachment, int slot) { Texture *tex = reinterpret_cast(attachment.tex); GPUAttachmentType type = tex->attachment_type(slot); - reinterpret_cast(gpu_fb)->attachment_set(type, attachment); + unwrap(gpu_fb)->attachment_set(type, attachment); } void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip) @@ -293,10 +291,9 @@ void GPU_framebuffer_texture_cubeface_attach( GPU_framebuffer_texture_attach_ex(fb, attachment, slot); } -void GPU_framebuffer_texture_detach(GPUFrameBuffer *gpu_fb, GPUTexture *tex) +void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex) { - FrameBuffer *fb = reinterpret_cast(gpu_fb); - reinterpret_cast(tex)->detach_from(fb); + unwrap(tex)->detach_from(unwrap(fb)); } /** @@ -309,7 +306,7 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb, const GPUAttachment *config, int config_len) { - FrameBuffer *fb = reinterpret_cast(gpu_fb); + FrameBuffer *fb = unwrap(gpu_fb); const GPUAttachment &depth_attachment = config[0]; Span color_attachments(config + 1, config_len - 1); @@ -346,12 +343,12 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb, void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height) { int viewport_rect[4] = {x, y, width, height}; - reinterpret_cast(gpu_fb)->viewport_set(viewport_rect); + unwrap(gpu_fb)->viewport_set(viewport_rect); } void GPU_framebuffer_viewport_get(GPUFrameBuffer *gpu_fb, int r_viewport[4]) { - reinterpret_cast(gpu_fb)->viewport_get(r_viewport); + unwrap(gpu_fb)->viewport_get(r_viewport); } /** @@ -359,7 +356,7 @@ void GPU_framebuffer_viewport_get(GPUFrameBuffer *gpu_fb, int r_viewport[4]) */ void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb) { - reinterpret_cast(gpu_fb)->viewport_reset(); + unwrap(gpu_fb)->viewport_reset(); } /* ---------- Framebuffer Operations ----------- */ @@ -370,7 +367,7 @@ void GPU_framebuffer_clear(GPUFrameBuffer *gpu_fb, float clear_depth, uint clear_stencil) { - reinterpret_cast(gpu_fb)->clear(buffers, clear_col, clear_depth, clear_stencil); + unwrap(gpu_fb)->clear(buffers, clear_col, clear_depth, clear_stencil); } /** @@ -378,7 +375,7 @@ void GPU_framebuffer_clear(GPUFrameBuffer *gpu_fb, */ void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float (*clear_cols)[4]) { - reinterpret_cast(gpu_fb)->clear_multi(clear_cols); + unwrap(gpu_fb)->clear_multi(clear_cols); } void GPU_clear_color(float red, float green, float blue, float alpha) @@ -397,7 +394,7 @@ void GPU_framebuffer_read_depth( GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, eGPUDataFormat format, void *data) { int rect[4] = {x, y, w, h}; - reinterpret_cast(gpu_fb)->read(GPU_DEPTH_BIT, format, rect, 1, 1, data); + unwrap(gpu_fb)->read(GPU_DEPTH_BIT, format, rect, 1, 1, data); } void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, @@ -411,7 +408,7 @@ void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, void *data) { int rect[4] = {x, y, w, h}; - reinterpret_cast(gpu_fb)->read(GPU_COLOR_BIT, format, rect, channels, slot, data); + unwrap(gpu_fb)->read(GPU_COLOR_BIT, format, rect, channels, slot, data); } /* TODO(fclem) rename to read_color. */ @@ -430,8 +427,8 @@ void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, int write_slot, eGPUFrameBufferBits blit_buffers) { - FrameBuffer *fb_read = reinterpret_cast(gpufb_read); - FrameBuffer *fb_write = reinterpret_cast(gpufb_write); + FrameBuffer *fb_read = unwrap(gpufb_read); + FrameBuffer *fb_write = unwrap(gpufb_write); BLI_assert(blit_buffers != 0); FrameBuffer *prev_fb = GPU_context_active_get()->active_fb; @@ -473,7 +470,7 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *gpu_fb, void (*callback)(void *userData, int level), void *userData) { - reinterpret_cast(gpu_fb)->recursive_downsample(max_lvl, callback, userData); + unwrap(gpu_fb)->recursive_downsample(max_lvl, callback, userData); } /** \} */ @@ -616,9 +613,9 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save) { if (save) { GPUFrameBuffer *fb = GPU_framebuffer_active_get(); - gpuPushFrameBuffer(reinterpret_cast(fb)); + gpuPushFrameBuffer(fb); } - reinterpret_cast(gpu_offscreen_fb_get(ofs))->bind(false); + unwrap(gpu_offscreen_fb_get(ofs))->bind(false); } void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore) @@ -639,7 +636,7 @@ void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore) void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y) { GPUContext *ctx = GPU_context_active_get(); - FrameBuffer *ofs_fb = reinterpret_cast(gpu_offscreen_fb_get(ofs)); + FrameBuffer *ofs_fb = unwrap(gpu_offscreen_fb_get(ofs)); ofs_fb->blit_to(GPU_COLOR_BIT, 0, ctx->active_fb, 0, x, y); } diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh index 81507f4111a..da44773039b 100644 --- a/source/blender/gpu/intern/gpu_framebuffer_private.hh +++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh @@ -209,6 +209,20 @@ class FrameBuffer { }; }; +/* Syntacting suggar. */ +static inline GPUFrameBuffer *wrap(FrameBuffer *vert) +{ + return reinterpret_cast(vert); +} +static inline FrameBuffer *unwrap(GPUFrameBuffer *vert) +{ + return reinterpret_cast(vert); +} +static inline const FrameBuffer *unwrap(const GPUFrameBuffer *vert) +{ + return reinterpret_cast(vert); +} + #undef DEBUG_NAME_LEN } // namespace gpu diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 38acc773c49..eb0f7935b63 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -52,11 +52,6 @@ extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[]; using namespace blender; using namespace blender::gpu; -/** Opaque type hidding blender::gpu::Shader */ -struct GPUShader { - char _pad[1]; -}; - /* -------------------------------------------------------------------- */ /** \name Debug functions * \{ */ @@ -333,12 +328,12 @@ GPUShader *GPU_shader_create_ex(const char *vertcode, return NULL; }; - return reinterpret_cast(shader); + return wrap(shader); } void GPU_shader_free(GPUShader *shader) { - delete reinterpret_cast(shader); + delete unwrap(shader); } /** \} */ @@ -460,7 +455,7 @@ struct GPUShader *GPU_shader_create_from_arrays_impl( void GPU_shader_bind(GPUShader *gpu_shader) { - Shader *shader = reinterpret_cast(gpu_shader); + Shader *shader = unwrap(gpu_shader); GPUContext *ctx = GPU_context_active_get(); @@ -481,7 +476,7 @@ void GPU_shader_unbind(void) #ifndef NDEBUG GPUContext *ctx = GPU_context_active_get(); if (ctx->shader) { - reinterpret_cast(ctx->shader)->unbind(); + ctx->shader->unbind(); } ctx->shader = NULL; #endif @@ -497,12 +492,12 @@ void GPU_shader_unbind(void) bool GPU_shader_transform_feedback_enable(GPUShader *shader, GPUVertBuf *vertbuf) { - return reinterpret_cast(shader)->transform_feedback_enable(vertbuf); + return unwrap(shader)->transform_feedback_enable(vertbuf); } void GPU_shader_transform_feedback_disable(GPUShader *shader) { - reinterpret_cast(shader)->transform_feedback_disable(); + unwrap(shader)->transform_feedback_disable(); } /** \} */ @@ -513,48 +508,48 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader) int GPU_shader_get_uniform(GPUShader *shader, const char *name) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *uniform = interface->uniform_get(name); return uniform ? uniform->location : -1; } int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; return interface->uniform_builtin((GPUUniformBuiltin)builtin); } int GPU_shader_get_builtin_block(GPUShader *shader, int builtin) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; return interface->ubo_builtin((GPUUniformBlockBuiltin)builtin); } /* DEPRECATED. */ int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *ubo = interface->ubo_get(name); return ubo ? ubo->location : -1; } int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *ubo = interface->ubo_get(name); return ubo ? ubo->binding : -1; } int GPU_shader_get_texture_binding(GPUShader *shader, const char *name) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *tex = interface->uniform_get(name); return tex ? tex->binding : -1; } int GPU_shader_get_attribute(GPUShader *shader, const char *name) { - ShaderInterface *interface = reinterpret_cast(shader)->interface; + ShaderInterface *interface = unwrap(shader)->interface; const ShaderInput *attr = interface->attr_get(name); return attr ? attr->location : -1; } @@ -581,13 +576,13 @@ int GPU_shader_get_program(GPUShader *UNUSED(shader)) void GPU_shader_uniform_vector( GPUShader *shader, int loc, int len, int arraysize, const float *value) { - reinterpret_cast(shader)->uniform_float(loc, len, arraysize, value); + unwrap(shader)->uniform_float(loc, len, arraysize, value); } void GPU_shader_uniform_vector_int( GPUShader *shader, int loc, int len, int arraysize, const int *value) { - reinterpret_cast(shader)->uniform_int(loc, len, arraysize, value); + unwrap(shader)->uniform_int(loc, len, arraysize, value); } void GPU_shader_uniform_int(GPUShader *shader, int location, int value) diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index fa086892760..b7acc0f9353 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -23,8 +23,8 @@ #include "BLI_span.hh" #include "GPU_shader.h" -#include "gpu_vertex_buffer_private.hh" #include "gpu_shader_interface.hh" +#include "gpu_vertex_buffer_private.hh" namespace blender { namespace gpu { @@ -73,6 +73,20 @@ class Shader { void print_errors(Span sources, char *log, const char *stage); }; +/* Syntacting suggar. */ +static inline GPUShader *wrap(Shader *vert) +{ + return reinterpret_cast(vert); +} +static inline Shader *unwrap(GPUShader *vert) +{ + return reinterpret_cast(vert); +} +static inline const Shader *unwrap(const GPUShader *vert) +{ + return reinterpret_cast(vert); +} + } // namespace gpu } // namespace blender diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 19022b228b2..04156632c5e 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -68,6 +68,10 @@ ENUM_OPERATORS(eGPUTextureType) /* Maximum number of FBOs a texture can be attached to. */ #define GPU_TEX_MAX_FBO_ATTACHED 14 +/** + * Implementation of Textures. + * Base class which is then specialized for each implementation (GL, VK, ...). + **/ class Texture { public: /** Internal Sampler state. */ diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc index 4926a5fa2dc..2dea98f03ca 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer.cc +++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc @@ -198,7 +198,7 @@ GPUUniformBuf *GPU_uniformbuf_create_ex(size_t size, const void *data, const cha if (data != NULL) { ubo->update(data); } - return reinterpret_cast(ubo); + return wrap(ubo); } /** @@ -222,27 +222,27 @@ GPUUniformBuf *GPU_uniformbuf_create_from_list(ListBase *inputs, const char *nam UniformBuf *ubo = GPUBackend::get()->uniformbuf_alloc(buffer_size, name); /* Defer data upload. */ ubo->attach_data(data); - return reinterpret_cast(ubo); + return wrap(ubo); } void GPU_uniformbuf_free(GPUUniformBuf *ubo) { - delete reinterpret_cast(ubo); + delete unwrap(ubo); } void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data) { - reinterpret_cast(ubo)->update(data); + unwrap(ubo)->update(data); } void GPU_uniformbuf_bind(GPUUniformBuf *ubo, int slot) { - reinterpret_cast(ubo)->bind(slot); + unwrap(ubo)->bind(slot); } void GPU_uniformbuf_unbind(GPUUniformBuf *ubo) { - reinterpret_cast(ubo)->unbind(); + unwrap(ubo)->unbind(); } void GPU_uniformbuf_unbind_all(void) diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh index cf6447ccd37..00d10776864 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh @@ -63,6 +63,20 @@ class UniformBuf { } }; +/* Syntacting suggar. */ +static inline GPUUniformBuf *wrap(UniformBuf *vert) +{ + return reinterpret_cast(vert); +} +static inline UniformBuf *unwrap(GPUUniformBuf *vert) +{ + return reinterpret_cast(vert); +} +static inline const UniformBuf *unwrap(const GPUUniformBuf *vert) +{ + return reinterpret_cast(vert); +} + #undef DEBUG_NAME_LEN } // namespace gpu diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh index 61af0a215a9..f1de0a2ac96 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh @@ -29,6 +29,10 @@ namespace blender::gpu { +/** + * Implementation of Vertex Buffers. + * Base class which is then specialized for each implementation (GL, VK, ...). + **/ class VertBuf { public: static size_t memory_usage; -- cgit v1.2.3 From 48690d967a7731367cda01ab8dca64e7f4c3f6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 04:12:12 +0200 Subject: GPUContext: Move GPUContext to gpu::Context for more consistency This makes the GPUContext follow the same naming convention as the rest of the module. Also add a static getter for extra bonus style (no need for casts): - Context::get() - GLContext::get() --- source/blender/gpu/GPU_context.h | 5 ++- source/blender/gpu/intern/gpu_backend.hh | 6 +-- source/blender/gpu/intern/gpu_batch.cc | 2 +- source/blender/gpu/intern/gpu_capabilities.cc | 4 +- source/blender/gpu/intern/gpu_context.cc | 40 +++++++++++-------- source/blender/gpu/intern/gpu_context_private.hh | 51 ++++++++++++++---------- source/blender/gpu/intern/gpu_framebuffer.cc | 22 +++++----- source/blender/gpu/intern/gpu_immediate.cc | 2 +- source/blender/gpu/intern/gpu_matrix.cc | 16 ++++---- source/blender/gpu/intern/gpu_shader.cc | 4 +- source/blender/gpu/intern/gpu_state.cc | 40 +++++++++---------- source/blender/gpu/intern/gpu_texture.cc | 10 ++--- source/blender/gpu/opengl/gl_backend.hh | 2 +- source/blender/gpu/opengl/gl_batch.cc | 10 ++--- source/blender/gpu/opengl/gl_context.cc | 10 ++--- source/blender/gpu/opengl/gl_context.hh | 13 ++++-- source/blender/gpu/opengl/gl_debug.cc | 2 +- source/blender/gpu/opengl/gl_drawlist.cc | 6 +-- source/blender/gpu/opengl/gl_framebuffer.cc | 12 +++--- source/blender/gpu/opengl/gl_immediate.cc | 2 +- source/blender/gpu/opengl/gl_shader.cc | 4 +- source/blender/gpu/opengl/gl_texture.cc | 6 +-- source/blender/gpu/opengl/gl_uniform_buffer.cc | 6 +-- source/blender/gpu/opengl/gl_vertex_array.cc | 2 +- source/blender/gpu/opengl/gl_vertex_buffer.cc | 4 +- 25 files changed, 153 insertions(+), 128 deletions(-) diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h index be7e604fb96..82f13424502 100644 --- a/source/blender/gpu/GPU_context.h +++ b/source/blender/gpu/GPU_context.h @@ -32,8 +32,6 @@ extern "C" { #endif -typedef struct GPUContext GPUContext; - typedef enum eGPUBackendType { GPU_BACKEND_NONE = 0, GPU_BACKEND_OPENGL, @@ -42,6 +40,9 @@ typedef enum eGPUBackendType { void GPU_backend_init(eGPUBackendType backend); void GPU_backend_exit(void); +/** Opaque type hiding blender::gpu::Context. */ +typedef struct GPUContext GPUContext; + GPUContext *GPU_context_create(void *ghost_window); void GPU_context_discard(GPUContext *); diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh index 1a6a6668b42..04ec82a9213 100644 --- a/source/blender/gpu/intern/gpu_backend.hh +++ b/source/blender/gpu/intern/gpu_backend.hh @@ -25,11 +25,11 @@ #pragma once -struct GPUContext; - namespace blender { namespace gpu { +class Context; + class Batch; class DrawList; class FrameBuffer; @@ -48,7 +48,7 @@ class GPUBackend { virtual void samplers_update(void) = 0; - virtual GPUContext *context_alloc(void *ghost_window) = 0; + virtual Context *context_alloc(void *ghost_window) = 0; virtual Batch *batch_alloc(void) = 0; virtual DrawList *drawlist_alloc(int list_length) = 0; diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index d6f4f223a83..de079a89de7 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -258,7 +258,7 @@ void GPU_batch_draw_instanced(GPUBatch *batch, int i_count) void GPU_batch_draw_advanced( GPUBatch *gpu_batch, int v_first, int v_count, int i_first, int i_count) { - BLI_assert(GPU_context_active_get()->shader != NULL); + BLI_assert(Context::get()->shader != NULL); Batch *batch = static_cast(gpu_batch); if (v_count == 0) { diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc index 0ee25ea2569..a79ce27ba63 100644 --- a/source/blender/gpu/intern/gpu_capabilities.cc +++ b/source/blender/gpu/intern/gpu_capabilities.cc @@ -115,13 +115,13 @@ bool GPU_mem_stats_supported(void) void GPU_mem_stats_get(int *totalmem, int *freemem) { - GPU_context_active_get()->memory_statistics_get(totalmem, freemem); + Context::get()->memory_statistics_get(totalmem, freemem); } /* Return support for the active context + window. */ bool GPU_stereo_quadbuffer_support(void) { - return GPU_context_active_get()->front_right != nullptr; + return Context::get()->front_right != nullptr; } /** \} */ diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 8ebd49a658e..188225b3eed 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -54,20 +54,22 @@ using namespace blender::gpu; -static thread_local GPUContext *active_ctx = NULL; +static thread_local Context *active_ctx = NULL; /* -------------------------------------------------------------------- */ -/** \name GPUContext methods +/** \name gpu::Context methods * \{ */ -GPUContext::GPUContext() +namespace blender::gpu { + +Context::Context() { thread_ = pthread_self(); is_active_ = false; matrix_state = GPU_matrix_state_create(); } -GPUContext::~GPUContext() +Context::~Context() { GPU_matrix_state_discard(matrix_state); delete state_manager; @@ -78,11 +80,18 @@ GPUContext::~GPUContext() delete imm; } -bool GPUContext::is_active_on_thread(void) +bool Context::is_active_on_thread(void) { return (this == active_ctx) && pthread_equal(pthread_self(), thread_); } +Context *Context::get(void) +{ + return active_ctx; +} + +} // namespace blender::gpu + /** \} */ /* -------------------------------------------------------------------- */ @@ -94,22 +103,25 @@ GPUContext *GPU_context_create(void *ghost_window) GPU_backend_init(GPU_BACKEND_OPENGL); } - GPUContext *ctx = GPUBackend::get()->context_alloc(ghost_window); + Context *ctx = GPUBackend::get()->context_alloc(ghost_window); - GPU_context_active_set(ctx); - return ctx; + GPU_context_active_set(wrap(ctx)); + return wrap(ctx); } /* to be called after GPU_context_active_set(ctx_to_destroy) */ -void GPU_context_discard(GPUContext *ctx) +void GPU_context_discard(GPUContext *ctx_) { + Context *ctx = unwrap(ctx_); delete ctx; active_ctx = NULL; } /* ctx can be NULL */ -void GPU_context_active_set(GPUContext *ctx) +void GPU_context_active_set(GPUContext *ctx_) { + Context *ctx = unwrap(ctx_); + if (active_ctx) { active_ctx->deactivate(); } @@ -123,13 +135,7 @@ void GPU_context_active_set(GPUContext *ctx) GPUContext *GPU_context_active_get(void) { - return active_ctx; -} - -struct GPUMatrixState *gpu_context_active_matrix_state_get() -{ - BLI_assert(active_ctx); - return active_ctx->matrix_state; + return wrap(Context::get()); } /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 5344cc6fb87..bc07bea4bb1 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -34,22 +34,20 @@ #include "gpu_shader_private.hh" #include "gpu_state_private.hh" -#include #include -#include -#include -#include struct GPUMatrixState; -struct GPUContext { +namespace blender::gpu { + +class Context { public: /** State management */ - blender::gpu::Shader *shader = NULL; - blender::gpu::FrameBuffer *active_fb = NULL; + Shader *shader = NULL; + FrameBuffer *active_fb = NULL; GPUMatrixState *matrix_state = NULL; - blender::gpu::GPUStateManager *state_manager = NULL; - blender::gpu::Immediate *imm = NULL; + GPUStateManager *state_manager = NULL; + Immediate *imm = NULL; /** * All 4 window frame-buffers. @@ -58,10 +56,10 @@ struct GPUContext { * Front frame-buffers contains (in principle, but not always) the last frame color. * Default frame-buffer is back_left. */ - blender::gpu::FrameBuffer *back_left = NULL; - blender::gpu::FrameBuffer *front_left = NULL; - blender::gpu::FrameBuffer *back_right = NULL; - blender::gpu::FrameBuffer *front_right = NULL; + FrameBuffer *back_left = NULL; + FrameBuffer *front_left = NULL; + FrameBuffer *back_right = NULL; + FrameBuffer *front_right = NULL; protected: /** Thread on which this context is active. */ @@ -71,8 +69,10 @@ struct GPUContext { void *ghost_window_; public: - GPUContext(); - virtual ~GPUContext(); + Context(); + virtual ~Context(); + + static Context *get(void); virtual void activate(void) = 0; virtual void deactivate(void) = 0; @@ -85,11 +85,20 @@ struct GPUContext { virtual void memory_statistics_get(int *total_mem, int *free_mem) = 0; bool is_active_on_thread(void); - - MEM_CXX_CLASS_ALLOC_FUNCS("GPUContext") }; -void gpu_context_active_framebuffer_set(GPUContext *ctx, struct GPUFrameBuffer *fb); -struct GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx); - -struct GPUMatrixState *gpu_context_active_matrix_state_get(void); +/* Syntacting suggar. */ +static inline GPUContext *wrap(Context *ctx) +{ + return reinterpret_cast(ctx); +} +static inline Context *unwrap(GPUContext *ctx) +{ + return reinterpret_cast(ctx); +} +static inline const Context *unwrap(const GPUContext *ctx) +{ + return reinterpret_cast(ctx); +} + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index e548eb241cf..88779dead28 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -224,7 +224,7 @@ void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *gpu_fb) */ void GPU_backbuffer_bind(eGPUBackBuffer buffer) { - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); if (buffer == GPU_BACKBUFFER_LEFT) { ctx->back_left->bind(false); @@ -236,19 +236,19 @@ void GPU_backbuffer_bind(eGPUBackBuffer buffer) void GPU_framebuffer_restore(void) { - GPU_context_active_get()->back_left->bind(false); + Context::get()->back_left->bind(false); } GPUFrameBuffer *GPU_framebuffer_active_get(void) { - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); return wrap(ctx ? ctx->active_fb : NULL); } /* Returns the default frame-buffer. Will always exists even if it's just a dummy. */ GPUFrameBuffer *GPU_framebuffer_back_get(void) { - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); return wrap(ctx ? ctx->back_left : NULL); } @@ -381,13 +381,13 @@ void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float (*clear_col void GPU_clear_color(float red, float green, float blue, float alpha) { float clear_col[4] = {red, green, blue, alpha}; - GPU_context_active_get()->active_fb->clear(GPU_COLOR_BIT, clear_col, 0.0f, 0x0); + Context::get()->active_fb->clear(GPU_COLOR_BIT, clear_col, 0.0f, 0x0); } void GPU_clear_depth(float depth) { float clear_col[4] = {0}; - GPU_context_active_get()->active_fb->clear(GPU_DEPTH_BIT, clear_col, depth, 0x0); + Context::get()->active_fb->clear(GPU_DEPTH_BIT, clear_col, depth, 0x0); } void GPU_framebuffer_read_depth( @@ -416,7 +416,7 @@ void GPU_frontbuffer_read_pixels( int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data) { int rect[4] = {x, y, w, h}; - GPU_context_active_get()->front_left->read(GPU_COLOR_BIT, format, rect, channels, 0, data); + Context::get()->front_left->read(GPU_COLOR_BIT, format, rect, channels, 0, data); } /* read_slot and write_slot are only used for color buffers. */ @@ -431,7 +431,7 @@ void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, FrameBuffer *fb_write = unwrap(gpufb_write); BLI_assert(blit_buffers != 0); - FrameBuffer *prev_fb = GPU_context_active_get()->active_fb; + FrameBuffer *prev_fb = Context::get()->active_fb; #ifndef NDEBUG GPUTexture *read_tex, *write_tex; @@ -509,7 +509,7 @@ static GPUFrameBuffer *gpuPopFrameBuffer(void) struct GPUOffScreen { struct { - GPUContext *ctx; + Context *ctx; GPUFrameBuffer *fb; } framebuffers[MAX_CTX_FB_LEN]; @@ -522,7 +522,7 @@ struct GPUOffScreen { */ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs) { - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); BLI_assert(ctx); for (int i = 0; i < MAX_CTX_FB_LEN; i++) { @@ -635,7 +635,7 @@ void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore) void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y) { - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); FrameBuffer *ofs_fb = unwrap(gpu_offscreen_fb_get(ofs)); ofs_fb->blit_to(GPU_COLOR_BIT, 0, ctx->active_fb, 0, x, y); } diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index 9fc5e03a796..0a488c0dfc0 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -43,7 +43,7 @@ static thread_local Immediate *imm = NULL; void immActivate(void) { - imm = GPU_context_active_get()->imm; + imm = Context::get()->imm; } void immDeactivate(void) diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc index cdb6d303588..0274966d4b9 100644 --- a/source/blender/gpu/intern/gpu_matrix.cc +++ b/source/blender/gpu/intern/gpu_matrix.cc @@ -35,6 +35,8 @@ #include "MEM_guardedalloc.h" +using namespace blender::gpu; + #define MATRIX_STACK_DEPTH 32 typedef float Mat4[4][4]; @@ -59,10 +61,10 @@ typedef struct GPUMatrixState { */ } GPUMatrixState; -#define ModelViewStack gpu_context_active_matrix_state_get()->model_view_stack +#define ModelViewStack Context::get()->matrix_state->model_view_stack #define ModelView ModelViewStack.stack[ModelViewStack.top] -#define ProjectionStack gpu_context_active_matrix_state_get()->projection_stack +#define ProjectionStack Context::get()->matrix_state->projection_stack #define Projection ProjectionStack.stack[ProjectionStack.top] GPUMatrixState *GPU_matrix_state_create(void) @@ -93,13 +95,13 @@ void GPU_matrix_state_discard(GPUMatrixState *state) static void gpu_matrix_state_active_set_dirty(bool value) { - GPUMatrixState *state = gpu_context_active_matrix_state_get(); + GPUMatrixState *state = Context::get()->matrix_state; state->dirty = value; } void GPU_matrix_reset(void) { - GPUMatrixState *state = gpu_context_active_matrix_state_get(); + GPUMatrixState *state = Context::get()->matrix_state; state->model_view_stack.top = 0; state->projection_stack.top = 0; unit_m4(ModelView); @@ -686,7 +688,7 @@ void GPU_matrix_bind(GPUShader *shader) bool GPU_matrix_dirty_get(void) { - GPUMatrixState *state = gpu_context_active_matrix_state_get(); + GPUMatrixState *state = Context::get()->matrix_state; return state->dirty; } @@ -699,13 +701,13 @@ BLI_STATIC_ASSERT(GPU_PY_MATRIX_STACK_LEN + 1 == MATRIX_STACK_DEPTH, "define mis int GPU_matrix_stack_level_get_model_view(void) { - GPUMatrixState *state = gpu_context_active_matrix_state_get(); + GPUMatrixState *state = Context::get()->matrix_state; return (int)state->model_view_stack.top; } int GPU_matrix_stack_level_get_projection(void) { - GPUMatrixState *state = gpu_context_active_matrix_state_get(); + GPUMatrixState *state = Context::get()->matrix_state; return (int)state->projection_stack.top; } diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index eb0f7935b63..1bd076f96f8 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -457,7 +457,7 @@ void GPU_shader_bind(GPUShader *gpu_shader) { Shader *shader = unwrap(gpu_shader); - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); if (ctx->shader != shader) { ctx->shader = shader; @@ -474,7 +474,7 @@ void GPU_shader_bind(GPUShader *gpu_shader) void GPU_shader_unbind(void) { #ifndef NDEBUG - GPUContext *ctx = GPU_context_active_get(); + Context *ctx = Context::get(); if (ctx->shader) { ctx->shader->unbind(); } diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index 68f0c290bc6..529c8795327 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -41,7 +41,7 @@ using namespace blender::gpu; #define SET_STATE(_prefix, _state, _value) \ do { \ - GPUStateManager *stack = GPU_context_active_get()->state_manager; \ + GPUStateManager *stack = Context::get()->state_manager; \ auto &state_object = stack->_prefix##state; \ state_object._state = (_value); \ } while (0) @@ -105,7 +105,7 @@ void GPU_write_mask(eGPUWriteMask mask) void GPU_color_mask(bool r, bool g, bool b, bool a) { - GPUStateManager *stack = GPU_context_active_get()->state_manager; + GPUStateManager *stack = Context::get()->state_manager; auto &state = stack->state; uint32_t write_mask = state.write_mask; SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED); @@ -117,7 +117,7 @@ void GPU_color_mask(bool r, bool g, bool b, bool a) void GPU_depth_mask(bool depth) { - GPUStateManager *stack = GPU_context_active_get()->state_manager; + GPUStateManager *stack = Context::get()->state_manager; auto &state = stack->state; uint32_t write_mask = state.write_mask; SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH); @@ -142,7 +142,7 @@ void GPU_state_set(eGPUWriteMask write_mask, eGPUStencilOp stencil_op, eGPUProvokingVertex provoking_vert) { - GPUStateManager *stack = GPU_context_active_get()->state_manager; + GPUStateManager *stack = Context::get()->state_manager; auto &state = stack->state; state.write_mask = (uint32_t)write_mask; state.blend = (uint32_t)blend; @@ -161,7 +161,7 @@ void GPU_state_set(eGPUWriteMask write_mask, void GPU_depth_range(float near, float far) { - GPUStateManager *stack = GPU_context_active_get()->state_manager; + GPUStateManager *stack = Context::get()->state_manager; auto &state = stack->mutable_state; copy_v2_fl2(state.depth_range, near, far); } @@ -182,7 +182,7 @@ void GPU_point_size(float size) /* TODO remove and use program point size everywhere */ void GPU_program_point_size(bool enable) { - GPUStateManager *stack = GPU_context_active_get()->state_manager; + GPUStateManager *stack = Context::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); @@ -190,19 +190,19 @@ void GPU_program_point_size(bool enable) void GPU_scissor_test(bool enable) { - GPU_context_active_get()->active_fb->scissor_test_set(enable); + Context::get()->active_fb->scissor_test_set(enable); } void GPU_scissor(int x, int y, int width, int height) { int scissor_rect[4] = {x, y, width, height}; - GPU_context_active_get()->active_fb->scissor_set(scissor_rect); + Context::get()->active_fb->scissor_set(scissor_rect); } void GPU_viewport(int x, int y, int width, int height) { int viewport_rect[4] = {x, y, width, height}; - GPU_context_active_get()->active_fb->viewport_set(viewport_rect); + Context::get()->active_fb->viewport_set(viewport_rect); } void GPU_stencil_reference_set(uint reference) @@ -228,43 +228,43 @@ void GPU_stencil_compare_mask_set(uint compare_mask) eGPUBlend GPU_blend_get() { - GPUState &state = GPU_context_active_get()->state_manager->state; + GPUState &state = Context::get()->state_manager->state; return (eGPUBlend)state.blend; } eGPUWriteMask GPU_write_mask_get() { - GPUState &state = GPU_context_active_get()->state_manager->state; + GPUState &state = Context::get()->state_manager->state; return (eGPUWriteMask)state.write_mask; } uint GPU_stencil_mask_get() { - GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state; + GPUStateMutable &state = Context::get()->state_manager->mutable_state; return state.stencil_write_mask; } eGPUDepthTest GPU_depth_test_get() { - GPUState &state = GPU_context_active_get()->state_manager->state; + GPUState &state = Context::get()->state_manager->state; return (eGPUDepthTest)state.depth_test; } eGPUStencilTest GPU_stencil_test_get() { - GPUState &state = GPU_context_active_get()->state_manager->state; + GPUState &state = Context::get()->state_manager->state; return (eGPUStencilTest)state.stencil_test; } void GPU_scissor_get(int coords[4]) { - GPU_context_active_get()->active_fb->scissor_get(coords); + Context::get()->active_fb->scissor_get(coords); } void GPU_viewport_size_get_f(float coords[4]) { int viewport[4]; - GPU_context_active_get()->active_fb->viewport_get(viewport); + Context::get()->active_fb->viewport_get(viewport); for (int i = 0; i < 4; i++) { coords[i] = viewport[i]; } @@ -272,12 +272,12 @@ void GPU_viewport_size_get_f(float coords[4]) void GPU_viewport_size_get_i(int coords[4]) { - GPU_context_active_get()->active_fb->viewport_get(coords); + Context::get()->active_fb->viewport_get(coords); } bool GPU_depth_mask_get(void) { - GPUState &state = GPU_context_active_get()->state_manager->state; + GPUState &state = Context::get()->state_manager->state; return (state.write_mask & GPU_WRITE_DEPTH) != 0; } @@ -295,12 +295,12 @@ bool GPU_mipmap_enabled(void) void GPU_flush(void) { - GPU_context_active_get()->flush(); + Context::get()->flush(); } void GPU_finish(void) { - GPU_context_active_get()->finish(); + Context::get()->finish(); } /** \} */ diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 05b97129f00..b22fd53f0f6 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -386,7 +386,7 @@ void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void * Skipping pixels correctly when changing rows when doing partial update.*/ void GPU_unpack_row_length_set(uint len) { - GPU_context_active_get()->state_manager->texture_unpack_row_length_set(len); + Context::get()->state_manager->texture_unpack_row_length_set(len); } /* ------ Binding ------ */ @@ -398,24 +398,24 @@ void GPU_texture_bind_ex(GPUTexture *tex_, { Texture *tex = reinterpret_cast(tex_); state = (state >= GPU_SAMPLER_MAX) ? tex->sampler_state : state; - GPU_context_active_get()->state_manager->texture_bind(tex, state, unit); + Context::get()->state_manager->texture_bind(tex, state, unit); } void GPU_texture_bind(GPUTexture *tex_, int unit) { Texture *tex = reinterpret_cast(tex_); - GPU_context_active_get()->state_manager->texture_bind(tex, tex->sampler_state, unit); + Context::get()->state_manager->texture_bind(tex, tex->sampler_state, unit); } void GPU_texture_unbind(GPUTexture *tex_) { Texture *tex = reinterpret_cast(tex_); - GPU_context_active_get()->state_manager->texture_unbind(tex); + Context::get()->state_manager->texture_unbind(tex); } void GPU_texture_unbind_all(void) { - GPU_context_active_get()->state_manager->texture_unbind_all(); + Context::get()->state_manager->texture_unbind_all(); } void GPU_texture_generate_mipmap(GPUTexture *tex) diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index 94ac1692108..231e5811b45 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -71,7 +71,7 @@ class GLBackend : public GPUBackend { GLTexture::samplers_update(); }; - GPUContext *context_alloc(void *ghost_window) override + Context *context_alloc(void *ghost_window) override { return new GLContext(ghost_window, shared_orphan_list_); }; diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index c28d3e33e65..b25bafad6a3 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -151,7 +151,7 @@ void GLVaoCache::remove(const GLShaderInterface *interface) void GLVaoCache::clear(void) { - GLContext *ctx = static_cast(GPU_context_active_get()); + GLContext *ctx = GLContext::get(); const int count = (is_dynamic_vao_count) ? dynamic_vaos.count : GPU_VAO_STATIC_LEN; GLuint *vaos = (is_dynamic_vao_count) ? dynamic_vaos.vao_ids : static_vaos.vao_ids; const GLShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces : @@ -209,7 +209,7 @@ GLuint GLVaoCache::lookup(const GLShaderInterface *interface) * Reset the cache if trying to draw in another context; */ void GLVaoCache::context_check(void) { - GLContext *ctx = static_cast(GPU_context_active_get()); + GLContext *ctx = GLContext::get(); BLI_assert(ctx); if (context_ != ctx) { @@ -228,7 +228,7 @@ GLuint GLVaoCache::base_instance_vao_get(GPUBatch *batch, int i_first) { this->context_check(); /* Make sure the interface is up to date. */ - Shader *shader = GPU_context_active_get()->shader; + Shader *shader = GLContext::get()->shader; GLShaderInterface *interface = static_cast(shader->interface); if (interface_ != interface) { vao_get(batch); @@ -260,7 +260,7 @@ GLuint GLVaoCache::vao_get(GPUBatch *batch) { this->context_check(); - Shader *shader = GPU_context_active_get()->shader; + Shader *shader = GLContext::get()->shader; GLShaderInterface *interface = static_cast(shader->interface); if (interface_ != interface) { interface_ = interface; @@ -298,7 +298,7 @@ GLBatch::~GLBatch() void GLBatch::bind(int i_first) { - GPU_context_active_get()->state_manager->apply_state(); + GLContext::get()->state_manager->apply_state(); if (flag & GPU_BATCH_DIRTY) { flag &= ~GPU_BATCH_DIRTY; diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index 30279ccade1..6b3b06ef12b 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -190,7 +190,7 @@ void GLContext::finish(void) void GLSharedOrphanLists::orphans_clear(void) { /* Check if any context is active on this thread! */ - BLI_assert(GPU_context_active_get()); + BLI_assert(GLContext::get()); lists_mutex.lock(); if (!buffers.is_empty()) { @@ -232,7 +232,7 @@ void GLContext::orphans_add(Vector &orphan_list, std::mutex &list_mutex, void GLContext::vao_free(GLuint vao_id) { - if (this == GPU_context_active_get()) { + if (this == GLContext::get()) { glDeleteVertexArrays(1, &vao_id); } else { @@ -242,7 +242,7 @@ void GLContext::vao_free(GLuint vao_id) void GLContext::fbo_free(GLuint fbo_id) { - if (this == GPU_context_active_get()) { + if (this == GLContext::get()) { glDeleteFramebuffers(1, &fbo_id); } else { @@ -253,7 +253,7 @@ void GLContext::fbo_free(GLuint fbo_id) void GLContext::buf_free(GLuint buf_id) { /* Any context can free. */ - if (GPU_context_active_get()) { + if (GLContext::get()) { glDeleteBuffers(1, &buf_id); } else { @@ -265,7 +265,7 @@ void GLContext::buf_free(GLuint buf_id) void GLContext::tex_free(GLuint tex_id) { /* Any context can free. */ - if (GPU_context_active_get()) { + if (GLContext::get()) { glDeleteTextures(1, &tex_id); } else { diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index ef0c13719e2..63014903e0a 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -53,7 +53,7 @@ class GLSharedOrphanLists { void orphans_clear(void); }; -class GLContext : public GPUContext { +class GLContext : public Context { public: /** Capabilities. */ static GLint max_texture_3d_size; @@ -103,9 +103,14 @@ class GLContext : public GPUContext { void memory_statistics_get(int *total_mem, int *free_mem) override; - static inline GLStateManager *state_manager_active_get() + static GLContext *get() { - GLContext *ctx = static_cast(GPU_context_active_get()); + return static_cast(Context::get()); + } + + static GLStateManager *state_manager_active_get() + { + GLContext *ctx = GLContext::get(); return static_cast(ctx->state_manager); }; @@ -122,6 +127,8 @@ class GLContext : public GPUContext { private: static void orphans_add(Vector &orphan_list, std::mutex &list_mutex, GLuint id); void orphans_clear(void); + + MEM_CXX_CLASS_ALLOC_FUNCS("GLContext") }; } // namespace gpu diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc index d54ea0919b6..53a71516018 100644 --- a/source/blender/gpu/opengl/gl_debug.cc +++ b/source/blender/gpu/opengl/gl_debug.cc @@ -197,7 +197,7 @@ void check_gl_resources(const char *info) return; } - GLContext *ctx = static_cast(GPU_context_active_get()); + GLContext *ctx = GLContext::get(); ShaderInterface *interface = ctx->shader->interface; /* NOTE: This only check binding. To be valid, the bound ubo needs to * be big enough to feed the data range the shader awaits. */ diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index 039ef18ad72..6e3b1107b9c 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -93,7 +93,7 @@ GLDrawList::~GLDrawList() void GLDrawList::init(void) { - BLI_assert(GPU_context_active_get()); + BLI_assert(GLContext::get()); BLI_assert(MDI_ENABLED); BLI_assert(data_ == NULL); batch_ = NULL; @@ -102,7 +102,7 @@ void GLDrawList::init(void) if (buffer_id_ == 0) { /* Allocate on first use. */ glGenBuffers(1, &buffer_id_); - context_ = static_cast(GPU_context_active_get()); + context_ = GLContext::get(); } glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer_id_); @@ -180,7 +180,7 @@ void GLDrawList::submit(void) /* Something's wrong if we get here without MDI support. */ BLI_assert(MDI_ENABLED); BLI_assert(data_); - BLI_assert(GPU_context_active_get()->shader != NULL); + BLI_assert(GLContext::get()->shader != NULL); /* Only do multi-draw indirect if doing more than 2 drawcall. This avoids the overhead of * buffer mapping if scene is not very instance friendly. BUT we also need to take into diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index 61270fe0acc..85fa973daff 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -78,7 +78,7 @@ GLFrameBuffer::~GLFrameBuffer() return; } - if (context_ == GPU_context_active_get()) { + if (context_ == GLContext::get()) { /* Context might be partially freed. This happens when destroying the window frame-buffers. */ glDeleteFramebuffers(1, &fbo_id_); } @@ -89,14 +89,14 @@ GLFrameBuffer::~GLFrameBuffer() if (context_->active_fb == this && context_->back_left != this) { /* If this assert triggers it means the frame-buffer is being freed while in use by another * context which, by the way, is TOTALLY UNSAFE!!! */ - BLI_assert(context_ == GPU_context_active_get()); + BLI_assert(context_ == GLContext::get()); GPU_framebuffer_restore(); } } void GLFrameBuffer::init(void) { - context_ = static_cast(GPU_context_active_get()); + context_ = GLContext::get(); state_manager_ = static_cast(context_->state_manager); glGenFramebuffers(1, &fbo_id_); @@ -274,7 +274,7 @@ void GLFrameBuffer::bind(bool enabled_srgb) this->init(); } - if (context_ != GPU_context_active_get()) { + if (context_ != GLContext::get()) { BLI_assert(!"Trying to use the same frame-buffer in multiple context"); return; } @@ -320,7 +320,7 @@ void GLFrameBuffer::clear(eGPUFrameBufferBits buffers, float clear_depth, uint clear_stencil) { - BLI_assert(GPU_context_active_get() == context_); + BLI_assert(GLContext::get() == context_); BLI_assert(context_->active_fb == this); /* Save and restore the state. */ @@ -360,7 +360,7 @@ void GLFrameBuffer::clear_attachment(GPUAttachmentType type, eGPUDataFormat data_format, const void *clear_value) { - BLI_assert(GPU_context_active_get() == context_); + BLI_assert(GLContext::get() == context_); BLI_assert(context_->active_fb == this); /* Save and restore the state. */ diff --git a/source/blender/gpu/opengl/gl_immediate.cc b/source/blender/gpu/opengl/gl_immediate.cc index 7f12f41a598..26b1df88b64 100644 --- a/source/blender/gpu/opengl/gl_immediate.cc +++ b/source/blender/gpu/opengl/gl_immediate.cc @@ -160,7 +160,7 @@ void GLImmediate::end(void) GL_CHECK_ERROR("Immediate Post-Unmap"); if (vertex_len > 0) { - GPU_context_active_get()->state_manager->apply_state(); + GLContext::get()->state_manager->apply_state(); /* We convert the offset in vertex offset from the buffer's start. * This works because we added some padding to align the first vertex vertex. */ diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index a303229fc3c..ca38efe37b5 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -44,7 +44,7 @@ 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); + BLI_assert(GLContext::get() != NULL); #endif shader_program_ = glCreateProgram(); @@ -61,7 +61,7 @@ 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); + BLI_assert(GLContext::get() != NULL); #endif /* Invalid handles are silently ignored. */ glDeleteShader(vert_shader_); diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index b4a8e43c931..ae3923b960f 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -44,7 +44,7 @@ namespace blender::gpu { GLTexture::GLTexture(const char *name) : Texture(name) { - BLI_assert(GPU_context_active_get() != NULL); + BLI_assert(GLContext::get() != NULL); glGenTextures(1, &tex_id_); } @@ -54,7 +54,7 @@ GLTexture::~GLTexture() if (framebuffer_) { GPU_framebuffer_free(framebuffer_); } - GPUContext *ctx = GPU_context_active_get(); + GLContext *ctx = GLContext::get(); if (ctx != NULL && is_bound_) { /* This avoid errors when the texture is still inside the bound texture array. */ ctx->state_manager->texture_unbind(this); @@ -662,7 +662,7 @@ void GLTexture::check_feedback_loop(void) if (GPU_mip_render_workaround()) { return; } - GLFrameBuffer *fb = static_cast(GPU_context_active_get()->active_fb); + GLFrameBuffer *fb = static_cast(GLContext::get()->active_fb); for (int i = 0; i < ARRAY_SIZE(fb_); i++) { if (fb_[i] == fb) { GPUAttachmentType type = fb_attachment_[i]; diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc index a06fadf4785..62c590d289f 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.cc +++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc @@ -56,7 +56,7 @@ GLUniformBuf::~GLUniformBuf() void GLUniformBuf::init(void) { - BLI_assert(GPU_context_active_get()); + BLI_assert(GLContext::get()); glGenBuffers(1, &ubo_id_); glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_); @@ -112,7 +112,7 @@ void GLUniformBuf::bind(int slot) #ifdef DEBUG BLI_assert(slot < 16); - static_cast(GPU_context_active_get())->bound_ubo_slots |= 1 << slot; + GLContext::get()->bound_ubo_slots |= 1 << slot; #endif } @@ -122,7 +122,7 @@ void GLUniformBuf::unbind(void) /* NOTE: This only unbinds the last bound slot. */ glBindBufferBase(GL_UNIFORM_BUFFER, slot_, 0); /* Hope that the context did not change. */ - static_cast(GPU_context_active_get())->bound_ubo_slots &= ~(1 << slot_); + GLContext::get()->bound_ubo_slots &= ~(1 << slot_); #endif slot_ = 0; } diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc index 4e49828d39d..732221cfab3 100644 --- a/source/blender/gpu/opengl/gl_vertex_array.cc +++ b/source/blender/gpu/opengl/gl_vertex_array.cc @@ -138,7 +138,7 @@ void GLVertArray::update_bindings(const GLuint vao, if (attr_mask != 0 && GLEW_ARB_vertex_attrib_binding) { for (uint16_t mask = 1, a = 0; a < 16; a++, mask <<= 1) { if (attr_mask & mask) { - GLContext *ctx = static_cast(GPU_context_active_get()); + GLContext *ctx = GLContext::get(); /* This replaces glVertexAttrib4f(a, 0.0f, 0.0f, 0.0f, 1.0f); with a more modern style. * Fix issues for some drivers (see T75069). */ glBindVertexBuffer(a, ctx->default_attr_vbo_, (intptr_t)0, (intptr_t)0); diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc index d56f5d1aa52..a724c94775e 100644 --- a/source/blender/gpu/opengl/gl_vertex_buffer.cc +++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc @@ -52,7 +52,7 @@ void GLVertBuf::release_data(void) void GLVertBuf::duplicate_data(VertBuf *dst_) { - BLI_assert(GPU_context_active_get() != NULL); + BLI_assert(GLContext::get() != NULL); GLVertBuf *src = this; GLVertBuf *dst = static_cast(dst_); @@ -82,7 +82,7 @@ void GLVertBuf::upload_data(void) void GLVertBuf::bind(void) { - BLI_assert(GPU_context_active_get() != NULL); + BLI_assert(GLContext::get() != NULL); if (vbo_id_ == 0) { glGenBuffers(1, &vbo_id_); -- cgit v1.2.3 From e467c54d58c88316d959f2481dc7484037a4c0be Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 15:32:43 +1000 Subject: Refactor: move library linking arguments into a parameter struct Move arguments to BLO_library_link_{begin/named_part/end} into a single parameter struct, to ensure arguments always match. This allows is to skip tagging ID's LIB_TAG_DOIT when it's not needed, previously it was always cleared just in case it was needed. This also makes it possible to remove BLO_library_link_named_part_ex which was only used when tagging was needed. --- .../blender/blenkernel/intern/blender_copybuffer.c | 13 +- source/blender/blenloader/BLO_readfile.h | 60 ++++++-- source/blender/blenloader/intern/readfile.c | 164 ++++++++++++--------- source/blender/python/intern/bpy_library_load.c | 9 +- .../blender/windowmanager/intern/wm_files_link.c | 10 +- 5 files changed, 168 insertions(+), 88 deletions(-) diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c index e950e94655a..9f5e038fb82 100644 --- a/source/blender/blenkernel/intern/blender_copybuffer.c +++ b/source/blender/blenkernel/intern/blender_copybuffer.c @@ -93,9 +93,12 @@ bool BKE_copybuffer_read(Main *bmain_dst, return false; } /* Here appending/linking starts. */ - Main *mainl = BLO_library_link_begin(bmain_dst, &bh, libname); + const int flag = 0; + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init(&liblink_params, bmain_dst, flag); + Main *mainl = BLO_library_link_begin(&bh, libname, &liblink_params); BLO_library_link_copypaste(mainl, bh, id_types_mask); - BLO_library_link_end(mainl, &bh, 0, NULL, NULL, NULL, NULL); + BLO_library_link_end(mainl, &bh, &liblink_params); /* Mark all library linked objects to be updated. */ BKE_main_lib_objects_recalc_all(bmain_dst); IMB_colormanagement_check_file_config(bmain_dst); @@ -144,11 +147,13 @@ int BKE_copybuffer_paste(bContext *C, BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &bh, libname); + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init_with_context(&liblink_params, bmain, flag, scene, view_layer, v3d); + mainl = BLO_library_link_begin(&bh, libname, &liblink_params); const int num_pasted = BLO_library_link_copypaste(mainl, bh, id_types_mask); - BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d); + BLO_library_link_end(mainl, &bh, &liblink_params); /* mark all library linked objects to be updated */ BKE_main_lib_objects_recalc_all(bmain); diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index c9e837eb3b5..c83d8e037c8 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -138,6 +138,10 @@ void BLO_blendhandle_close(BlendHandle *bh); bool BLO_has_bfile_extension(const char *str); bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name); +/* -------------------------------------------------------------------- */ +/** \name BLO Blend File Linking API + * \{ */ + /* Options controlling behavior of append/link code. * Note: merged with 'user-level' options from operators etc. in 16 lower bits * (see eFileSel_Params_Flag in DNA_space_types.h). */ @@ -146,25 +150,63 @@ typedef enum BLO_LibLinkFlags { BLO_LIBLINK_USE_PLACEHOLDERS = 1 << 16, /* Force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). */ BLO_LIBLINK_FORCE_INDIRECT = 1 << 17, + /** + * When set, tag ID types that pass the internal check #library_link_idcode_needs_tag_check + * + * Currently this is only used to instantiate objects in the scene. + * Set this from #BLO_library_link_params_init_with_context so callers + * don't need to remember to set this flag. + */ + BLO_LIBLINK_NEEDS_ID_TAG_DOIT = 1 << 18, } BLO_LinkFlags; -struct Main *BLO_library_link_begin(struct Main *mainvar, BlendHandle **bh, const char *filepath); +/** + * Struct for passing arguments to + * #BLO_library_link_begin, #BLO_library_link_named_part & #BLO_library_link_end. + * Wrap these in parameters since it's important both functions receive matching values. + */ +struct LibraryLink_Params { + /** The current main database, e.g. #G_MAIN or `CTX_data_main(C)`. */ + struct Main *bmain; + /** Options for linking, used for instantiating. */ + int flag; + /** Context for instancing objects (optional, no instantiation will be performed when NULL). */ + struct { + /** The scene in which to instantiate objects/collections. */ + struct Scene *scene; + /** The scene layer in which to instantiate objects/collections. */ + struct ViewLayer *view_layer; + /** The active 3D viewport (only used to define local-view). */ + const struct View3D *v3d; + } context; +}; + +void BLO_library_link_params_init(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag); +void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag, + struct Scene *scene, + struct ViewLayer *view_layer, + const struct View3D *v3d); + +struct Main *BLO_library_link_begin(BlendHandle **bh, + const char *filepath, + const struct LibraryLink_Params *params); struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, const short idcode, - const char *name); -struct ID *BLO_library_link_named_part_ex( - struct Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag); + const char *name, + const struct LibraryLink_Params *params); void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, - int flag, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer, - const struct View3D *v3d); + const struct LibraryLink_Params *params); int BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh, const uint64_t id_types_mask); +/** \} */ + void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname); /* internal function but we need to expose it */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 84cb898a426..35534963433 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -262,6 +262,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname); static void direct_link_modifiers(BlendDataReader *reader, ListBase *lb, Object *ob); static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name); static BHead *find_bhead_from_idname(FileData *fd, const char *idname); +static bool library_link_idcode_needs_tag_check(const short idcode, const int flag); #ifdef USE_COLLECTION_COMPAT_28 static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc); @@ -10469,6 +10470,14 @@ static ID *link_named_part( /* if we found the id but the id is NULL, this is really bad */ BLI_assert(!((bhead != NULL) && (id == NULL))); + /* Tag as loose object (or data associated with objects) + * needing to be instantiated in #LibraryLink_Params.scene. */ + if ((id != NULL) && (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT)) { + if (library_link_idcode_needs_tag_check(idcode, flag)) { + id->tag |= LIB_TAG_DOIT; + } + } + return id; } @@ -10514,23 +10523,6 @@ int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const uint64_t id_t return num_directly_linked; } -static ID *link_named_part_ex( - Main *mainl, FileData *fd, const short idcode, const char *name, const int flag) -{ - ID *id = link_named_part(mainl, fd, idcode, name, flag); - - if (id && (GS(id->name) == ID_OB)) { - /* Tag as loose object needing to be instantiated somewhere... */ - id->tag |= LIB_TAG_DOIT; - } - else if (id && (GS(id->name) == ID_GR)) { - /* tag as needing to be instantiated or linked */ - id->tag |= LIB_TAG_DOIT; - } - - return id; -} - /** * Link a named data-block from an external blend file. * @@ -10543,41 +10535,53 @@ static ID *link_named_part_ex( ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcode, - const char *name) + const char *name, + const struct LibraryLink_Params *params) { FileData *fd = (FileData *)(*bh); - return link_named_part(mainl, fd, idcode, name, 0); + return link_named_part(mainl, fd, idcode, name, params->flag); } +/* common routine to append/link something from a library */ + /** - * Link a named data-block from an external blend file. - * Optionally instantiate the object/collection in the scene when the flags are set. - * - * \param mainl: The main database to link from (not the active one). - * \param bh: The blender file handle. - * \param idcode: The kind of data-block to link. - * \param name: The name of the data-block (without the 2 char ID prefix). - * \param flag: Options for linking, used for instantiating. - * \return the linked ID when found. + * Checks if the \a idcode needs to be tagged with #LIB_TAG_DOIT when linking/appending. */ -ID *BLO_library_link_named_part_ex( - Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag) +static bool library_link_idcode_needs_tag_check(const short idcode, const int flag) { - FileData *fd = (FileData *)(*bh); - return link_named_part_ex(mainl, fd, idcode, name, flag); + if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) { + /* Always true because of #add_loose_objects_to_scene & #add_collections_to_scene. */ + if (ELEM(idcode, ID_OB, ID_GR)) { + return true; + } + } + return false; } -/* common routine to append/link something from a library */ +/** + * Clears #LIB_TAG_DOIT based on the result of #library_link_idcode_needs_tag_check. + */ +static void library_link_clear_tag(Main *mainvar, const int flag) +{ + for (int i = 0; i < MAX_LIBARRAY; i++) { + const short idcode = BKE_idtype_idcode_from_index(i); + BLI_assert(idcode != -1); + if (library_link_idcode_needs_tag_check(idcode, flag)) { + BKE_main_id_tag_idcode(mainvar, idcode, LIB_TAG_DOIT, false); + } + } +} -static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath) +static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath, const int flag) { Main *mainl; (*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist"); - /* clear for objects and collections instantiating tag */ - BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false); - BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false); + if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) { + /* Clear for objects and collections instantiating tag. */ + library_link_clear_tag(mainvar, flag); + } /* make mains */ blo_split_main((*fd)->mainlist, mainvar); @@ -10595,19 +10599,49 @@ static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepa return mainl; } +void BLO_library_link_params_init(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag) +{ + memset(params, 0, sizeof(*params)); + params->bmain = bmain; + params->flag = flag; +} + +void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag, + /* Context arguments. */ + struct Scene *scene, + struct ViewLayer *view_layer, + const struct View3D *v3d) +{ + BLO_library_link_params_init(params, bmain, flag); + if (scene != NULL) { + /* Tagging is needed for instancing. */ + params->flag |= BLO_LIBLINK_NEEDS_ID_TAG_DOIT; + + params->context.scene = scene; + params->context.view_layer = view_layer; + params->context.v3d = v3d; + } +} + /** * Initialize the #BlendHandle for linking library data. * - * \param mainvar: The current main database, e.g. #G_MAIN or #CTX_data_main(C). * \param bh: A blender file handle as returned by * #BLO_blendhandle_from_file or #BLO_blendhandle_from_memory. * \param filepath: Used for relative linking, copied to the `lib->filepath`. - * \return the library #Main, to be passed to #BLO_library_link_named_part_ex as \a mainl. + * \param params: Settings for linking that don't change from beginning to end of linking. + * \return the library #Main, to be passed to #BLO_library_link_named_part as \a mainl. */ -Main *BLO_library_link_begin(Main *mainvar, BlendHandle **bh, const char *filepath) +Main *BLO_library_link_begin(BlendHandle **bh, + const char *filepath, + const struct LibraryLink_Params *params) { FileData *fd = (FileData *)(*bh); - return library_link_begin(mainvar, &fd, filepath); + return library_link_begin(params->bmain, &fd, filepath, params->flag); } static void split_main_newid(Main *mainptr, Main *main_newid) @@ -10642,8 +10676,8 @@ static void split_main_newid(Main *mainptr, Main *main_newid) */ static void library_link_end(Main *mainl, FileData **fd, - const short flag, Main *bmain, + const int flag, Scene *scene, ViewLayer *view_layer, const View3D *v3d) @@ -10720,19 +10754,18 @@ static void library_link_end(Main *mainl, /* Give a base to loose objects and collections. * Only directly linked objects & collections are instantiated by - * #BLO_library_link_named_part_ex & co, + * #BLO_library_link_named_part & co, * here we handle indirect ones and other possible edge-cases. */ - if (scene) { - add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); - add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); - } - else { - /* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */ - } + if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) { + /* Should always be true. */ + if (scene != NULL) { + add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); + add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); + } - /* Clear objects and collections instantiating tag. */ - BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false); - BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false); + /* Clear objects and collections instantiating tag. */ + library_link_clear_tag(mainvar, flag); + } /* patch to prevent switch_endian happens twice */ if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) { @@ -10748,25 +10781,18 @@ static void library_link_end(Main *mainl, * * \param mainl: The main database to link from (not the active one). * \param bh: The blender file handle (WARNING! may be freed by this function!). - * \param flag: Options for linking, used for instantiating. - * \param bmain: The main database in which to instantiate objects/collections - * \param scene: The scene in which to instantiate objects/collections - * (if NULL, no instantiation is done). - * \param view_layer: The scene layer in which to instantiate objects/collections - * (if NULL, no instantiation is done). - * \param v3d: The active 3D viewport - * (only to define local-view for instantiated objects & groups, can be NULL). + * \param params: Settings for linking that don't change from beginning to end of linking. */ -void BLO_library_link_end(Main *mainl, - BlendHandle **bh, - int flag, - Main *bmain, - Scene *scene, - ViewLayer *view_layer, - const View3D *v3d) +void BLO_library_link_end(Main *mainl, BlendHandle **bh, const struct LibraryLink_Params *params) { FileData *fd = (FileData *)(*bh); - library_link_end(mainl, &fd, flag, bmain, scene, view_layer, v3d); + library_link_end(mainl, + &fd, + params->bmain, + params->flag, + params->context.scene, + params->context.view_layer, + params->context.v3d); *bh = (BlendHandle *)fd; } diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index bdad4d03ae7..a3750d348f5 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -327,7 +327,10 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &(self->blo_handle), self->relpath); + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init(&liblink_params, bmain, self->flag); + + mainl = BLO_library_link_begin(&(self->blo_handle), self->relpath, &liblink_params); { int idcode_step = 0, idcode; @@ -350,7 +353,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) if (item_idname) { ID *id = BLO_library_link_named_part( - mainl, &(self->blo_handle), idcode, item_idname); + mainl, &(self->blo_handle), idcode, item_idname, &liblink_params); if (id) { #ifdef USE_RNA_DATABLOCKS /* swap name for pointer to the id */ @@ -394,7 +397,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) } Library *lib = mainl->curlib; /* newly added lib, assign before append end */ - BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL); + BLO_library_link_end(mainl, &(self->blo_handle), &liblink_params); BLO_blendhandle_close(self->blo_handle); self->blo_handle = NULL; diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 6ccc5d79962..8c14055696c 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -250,7 +250,11 @@ static void wm_link_do(WMLinkAppendData *lapp_data, } /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &bh, libname); + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init_with_context( + &liblink_params, bmain, flag, scene, view_layer, v3d); + + mainl = BLO_library_link_begin(&bh, libname, &liblink_params); lib = mainl->curlib; BLI_assert(lib); UNUSED_VARS_NDEBUG(lib); @@ -276,7 +280,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data, continue; } - new_id = BLO_library_link_named_part_ex(mainl, &bh, item->idcode, item->name, flag); + new_id = BLO_library_link_named_part(mainl, &bh, item->idcode, item->name, &liblink_params); if (new_id) { /* If the link is successful, clear item's libs 'todo' flags. @@ -286,7 +290,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data, } } - BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d); + BLO_library_link_end(mainl, &bh, &liblink_params); BLO_blendhandle_close(bh); } } -- cgit v1.2.3 From 748deced1c7b85009142d1ebbffba4c1f2405a3f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 16:02:16 +1000 Subject: Link/Append: support instancing object data This patch supports instantiating object data on append/link, reported as a bug T58304. This is an option, available when linking/appending, similar to the existing "Instance Collections" option. Reviewed by @sybren Ref D8792 --- source/blender/blenloader/intern/readfile.c | 60 ++++++++++++++++++++++ source/blender/blenloader/intern/versioning_280.c | 2 +- source/blender/makesdna/DNA_space_types.h | 2 +- .../blender/windowmanager/intern/wm_files_link.c | 13 ++++- 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 35534963433..c809a87b188 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10328,6 +10328,60 @@ static void add_loose_objects_to_scene(Main *mainvar, } } +static void add_loose_object_data_to_scene(Main *mainvar, + Main *bmain, + Scene *scene, + ViewLayer *view_layer, + const View3D *v3d, + const short flag) +{ + if ((flag & FILE_OBDATA_INSTANCE) == 0) { + return; + } + + Collection *active_collection = scene->master_collection; + if (flag & FILE_ACTIVE_COLLECTION) { + LayerCollection *lc = BKE_layer_collection_get_active(view_layer); + active_collection = lc->collection; + } + + /* Loop over all ID types, instancing object-data for ID types that have support for it. */ + ListBase *lbarray[MAX_LIBARRAY]; + int i = set_listbasepointers(mainvar, lbarray); + while (i--) { + const short idcode = BKE_idtype_idcode_from_index(i); + if (!OB_DATA_SUPPORT_ID(idcode)) { + continue; + } + + LISTBASE_FOREACH (ID *, id, lbarray[i]) { + if (id->tag & LIB_TAG_DOIT) { + const int type = BKE_object_obdata_to_type(id); + BLI_assert(type != -1); + Object *ob = BKE_object_add_only_object(bmain, type, id->name + 2); + ob->data = id; + id_us_plus(id); + BKE_object_materials_test(bmain, ob, ob->data); + + BKE_collection_object_add(bmain, active_collection, ob); + Base *base = BKE_view_layer_base_find(view_layer, ob); + + if (v3d != NULL) { + base->local_view_bits |= v3d->local_view_uuid; + } + + if (flag & FILE_AUTOSELECT) { + base->flag |= BASE_SELECTED; + } + + BKE_scene_object_base_flag_sync_from_base(base); + + copy_v3_v3(ob->loc, scene->cursor.location); + } + } + } +} + static void add_collections_to_scene(Main *mainvar, Main *bmain, Scene *scene, @@ -10554,6 +10608,11 @@ static bool library_link_idcode_needs_tag_check(const short idcode, const int fl if (ELEM(idcode, ID_OB, ID_GR)) { return true; } + if (flag & FILE_OBDATA_INSTANCE) { + if (OB_DATA_SUPPORT_ID(idcode)) { + return true; + } + } } return false; } @@ -10761,6 +10820,7 @@ static void library_link_end(Main *mainl, if (scene != NULL) { add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); + add_loose_object_data_to_scene(mainvar, bmain, scene, view_layer, v3d, flag); } /* Clear objects and collections instantiating tag. */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 2434d9e9f74..e07ee7ee2b9 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -3422,7 +3422,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) SpaceFile *sfile = (SpaceFile *)sl; if (sfile->params) { sfile->params->flag &= ~(FILE_PARAMS_FLAG_UNUSED_1 | FILE_PARAMS_FLAG_UNUSED_6 | - FILE_PARAMS_FLAG_UNUSED_9); + FILE_OBDATA_INSTANCE); } break; } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index ad1635ba0c0..7778a3aa234 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -813,7 +813,7 @@ typedef enum eFileSel_Params_Flag { FILE_PARAMS_FLAG_UNUSED_6 = (1 << 6), /* cleared */ FILE_DIRSEL_ONLY = (1 << 7), FILE_FILTER = (1 << 8), - FILE_PARAMS_FLAG_UNUSED_9 = (1 << 9), /* cleared */ + FILE_OBDATA_INSTANCE = (1 << 9), FILE_GROUP_INSTANCE = (1 << 10), FILE_SORT_INVERT = (1 << 11), FILE_HIDE_TOOL_PROPS = (1 << 12), diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 8c14055696c..6c7205b25d4 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -137,6 +137,9 @@ static short wm_link_append_flag(wmOperator *op) if (RNA_boolean_get(op->ptr, "instance_collections")) { flag |= FILE_GROUP_INSTANCE; } + if (RNA_boolean_get(op->ptr, "instance_object_data")) { + flag |= FILE_OBDATA_INSTANCE; + } return flag; } @@ -395,7 +398,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) RPT_WARNING, "Scene '%s' is linked, instantiation of objects & groups is disabled", scene->id.name + 2); - flag &= ~FILE_GROUP_INSTANCE; + flag &= ~(FILE_GROUP_INSTANCE | FILE_OBDATA_INSTANCE); scene = NULL; } @@ -566,6 +569,14 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link) "Instance Collections", "Create instances for collections, rather than adding them directly to the scene"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + prop = RNA_def_boolean( + ot->srna, + "instance_object_data", + true, + "Instance Object Data", + "Create instances for object data which are not referenced by any objects"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } void WM_OT_link(wmOperatorType *ot) -- cgit v1.2.3 From d20b08281e0e5cf47b7b549910b6f5ab7f61e57d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 16:41:55 +1000 Subject: Cleanup: naming for library link enum Use 'e' prefix, update comments. --- source/blender/blenloader/BLO_readfile.h | 16 +++++++++------- source/blender/makesdna/DNA_space_types.h | 6 ++++-- source/blender/windowmanager/intern/wm_files_link.c | 7 ++++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index c83d8e037c8..4571e50dd36 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -142,13 +142,15 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha /** \name BLO Blend File Linking API * \{ */ -/* Options controlling behavior of append/link code. - * Note: merged with 'user-level' options from operators etc. in 16 lower bits - * (see eFileSel_Params_Flag in DNA_space_types.h). */ -typedef enum BLO_LibLinkFlags { - /* Generate a placeholder (empty ID) if not found in current lib file. */ +/** + * Options controlling behavior of append/link code. + * \note merged with 'user-level' options from operators etc. in 16 lower bits + * (see #eFileSel_Params_Flag in DNA_space_types.h). + */ +typedef enum eBLOLibLinkFlags { + /** Generate a placeholder (empty ID) if not found in current lib file. */ BLO_LIBLINK_USE_PLACEHOLDERS = 1 << 16, - /* Force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). */ + /** Force loaded ID to be tagged as #LIB_TAG_INDIRECT (used in reload context only). */ BLO_LIBLINK_FORCE_INDIRECT = 1 << 17, /** * When set, tag ID types that pass the internal check #library_link_idcode_needs_tag_check @@ -158,7 +160,7 @@ typedef enum BLO_LibLinkFlags { * don't need to remember to set this flag. */ BLO_LIBLINK_NEEDS_ID_TAG_DOIT = 1 << 18, -} BLO_LinkFlags; +} eBLOLibLinkFlags; /** * Struct for passing arguments to diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 7778a3aa234..92cf9d21e07 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -801,8 +801,10 @@ typedef enum eFileSel_Action { } eFileSel_Action; /* sfile->params->flag */ -/* Note: short flag, also used as 16 lower bits of flags in link/append code - * (WM and BLO code area, see BLO_LibLinkFlags in BLO_readfile.h). */ +/** + * \note short flag, also used as 16 lower bits of flags in link/append code + * (WM and BLO code area, see #eBLOLibLinkFlags in BLO_readfile.h). + */ typedef enum eFileSel_Params_Flag { FILE_PARAMS_FLAG_UNUSED_1 = (1 << 0), /* cleared */ FILE_RELPATH = (1 << 1), diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 6c7205b25d4..559eb6a78c2 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -159,8 +159,9 @@ typedef struct WMLinkAppendData { LinkNodePair items; int num_libraries; int num_items; - /** Combines #eFileSel_Params_Flag from DNA_space_types.h and - * BLO_LibLinkFlags from BLO_readfile.h */ + /** + * Combines #eFileSel_Params_Flag from DNA_space_types.h & #eBLOLibLinkFlags from BLO_readfile.h + */ int flag; /* Internal 'private' data */ @@ -402,7 +403,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) scene = NULL; } - /* We need to add nothing from BLO_LibLinkFlags to flag here. */ + /* We need to add nothing from #eBLOLibLinkFlags to flag here. */ /* from here down, no error returns */ -- cgit v1.2.3 From 59653a450ec02ed4f94aa3f059da069525490a21 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 16:49:17 +1000 Subject: Cleanup: rename group to collection for internal instancing flag Also update old comment. --- source/blender/blenloader/intern/readfile.c | 8 +++++--- source/blender/makesdna/DNA_space_types.h | 2 +- source/blender/windowmanager/intern/wm_files_link.c | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c809a87b188..195bb1e7f9f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10313,9 +10313,9 @@ static void add_loose_objects_to_scene(Main *mainvar, } if (flag & FILE_AUTOSELECT) { - base->flag |= BASE_SELECTED; /* Do NOT make base active here! screws up GUI stuff, - * if you want it do it on src/ level. */ + * if you want it do it at the editor level. */ + base->flag |= BASE_SELECTED; } BKE_scene_object_base_flag_sync_from_base(base); @@ -10371,6 +10371,8 @@ static void add_loose_object_data_to_scene(Main *mainvar, } if (flag & FILE_AUTOSELECT) { + /* Do NOT make base active here! screws up GUI stuff, + * if you want it do it at the editor level. */ base->flag |= BASE_SELECTED; } @@ -10398,7 +10400,7 @@ static void add_collections_to_scene(Main *mainvar, /* Give all objects which are tagged a base. */ LISTBASE_FOREACH (Collection *, collection, &mainvar->collections) { - if ((flag & FILE_GROUP_INSTANCE) && (collection->id.tag & LIB_TAG_DOIT)) { + if ((flag & FILE_COLLECTION_INSTANCE) && (collection->id.tag & LIB_TAG_DOIT)) { /* Any indirect collection should not have been tagged. */ BLI_assert((collection->id.tag & LIB_TAG_INDIRECT) == 0); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 92cf9d21e07..6fe6a5461e1 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -816,7 +816,7 @@ typedef enum eFileSel_Params_Flag { FILE_DIRSEL_ONLY = (1 << 7), FILE_FILTER = (1 << 8), FILE_OBDATA_INSTANCE = (1 << 9), - FILE_GROUP_INSTANCE = (1 << 10), + FILE_COLLECTION_INSTANCE = (1 << 10), FILE_SORT_INVERT = (1 << 11), FILE_HIDE_TOOL_PROPS = (1 << 12), FILE_CHECK_EXISTING = (1 << 13), diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 559eb6a78c2..6ed9dcd4cdc 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -135,7 +135,7 @@ static short wm_link_append_flag(wmOperator *op) flag |= FILE_LINK; } if (RNA_boolean_get(op->ptr, "instance_collections")) { - flag |= FILE_GROUP_INSTANCE; + flag |= FILE_COLLECTION_INSTANCE; } if (RNA_boolean_get(op->ptr, "instance_object_data")) { flag |= FILE_OBDATA_INSTANCE; @@ -397,9 +397,9 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) if (scene && scene->id.lib) { BKE_reportf(op->reports, RPT_WARNING, - "Scene '%s' is linked, instantiation of objects & groups is disabled", + "Scene '%s' is linked, instantiation of objects is disabled", scene->id.name + 2); - flag &= ~(FILE_GROUP_INSTANCE | FILE_OBDATA_INSTANCE); + flag &= ~(FILE_COLLECTION_INSTANCE | FILE_OBDATA_INSTANCE); scene = NULL; } -- cgit v1.2.3 From 1896c2c0e8bf5386b52e6f1b4d29fada284710af Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 17:15:09 +1000 Subject: Docs: comment values for DispList.type --- source/blender/blenkernel/BKE_displist.h | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 7e1a6e54ede..b2502031029 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -30,16 +30,24 @@ extern "C" { #endif -/* dl->type */ -#define DL_POLY 0 -#define DL_SEGM 1 -#define DL_SURF 2 -#define DL_INDEX3 4 -#define DL_INDEX4 5 -// #define DL_VERTCOL 6 // UNUSED -#define DL_VERTS 7 - -/* dl->flag */ +/** #DispList.type */ +enum { + /** A closed polygon (that can be filled). */ + DL_POLY = 0, + /** An open polygon. */ + DL_SEGM = 1, + /** A grid surface that respects #DL_CYCL_U & #DL_CYCL_V. */ + DL_SURF = 2, + /** Triangles. */ + DL_INDEX3 = 4, + /** Quads, with support for triangles (when values of the 3rd and 4th indices match). */ + DL_INDEX4 = 5, + // DL_VERTCOL = 6, /* UNUSED */ + /** Isolated points. */ + DL_VERTS = 7, +}; + +/** #DispList.type */ enum { /** U/V swapped here compared with #Nurb.flagu, #Nurb.flagv and #CU_NURB_CYCLIC */ DL_CYCL_U = (1 << 0), -- cgit v1.2.3 From c2419cdc5e581d6acb841f386a94a5d42f83852e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2020 18:04:03 +1000 Subject: Fix T80238: Crash adding properties to material node-trees The localized node-tree was freeing the materials ID properties twice. This matches how animation data behaves, setting to NULL after freeing. --- source/blender/blenkernel/intern/lib_id_delete.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c index 561db7d62c2..22ea5f2c854 100644 --- a/source/blender/blenkernel/intern/lib_id_delete.c +++ b/source/blender/blenkernel/intern/lib_id_delete.c @@ -56,10 +56,12 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user) if (id->properties) { IDP_FreePropertyContent_ex(id->properties, do_id_user); MEM_freeN(id->properties); + id->properties = NULL; } if (id->override_library) { BKE_lib_override_library_free(&id->override_library, do_id_user); + id->override_library = NULL; } BKE_animdata_free(id, do_id_user); -- cgit v1.2.3 From b8d4a2aff8069dd7d6fb91ad0d9427eed489b68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Sep 2020 10:04:41 +0200 Subject: Cleanup: Refactor `ED_object_parent_set` Refactor `ED_object_parent_set`: - Mark parameters `ob` and `par` as `const` so that it's clear the function doesn't assign any other value to them. - Rename `pararm` to `is_armature_parent`; I mis-read it as `param` all the time, and it was very confusing. - Replace repeated `if-else` statements with `switch` statements. - Reorder preconditions to have some simple checks first. - Flip condition on a huge `if`-statement to return early and unindent the remainder of the function. This function still requires splitting up into smaller functions, but at least this is a step forward. No functional changes. --- source/blender/editors/object/object_relations.c | 316 ++++++++++++----------- 1 file changed, 165 insertions(+), 151 deletions(-) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index fd4a7ae1d4a..4adf1a8d9f2 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -678,8 +678,8 @@ EnumPropertyItem prop_make_parent_types[] = { bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, - Object *ob, - Object *par, + Object *const ob, + Object *const par, int partype, const bool xmirror, const bool keep_transform, @@ -689,99 +689,111 @@ bool ED_object_parent_set(ReportList *reports, Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); bPoseChannel *pchan = NULL; bPoseChannel *pchan_eval = NULL; - const bool pararm = ELEM( - partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); Object *parent_eval = DEG_get_evaluated_object(depsgraph, par); DEG_id_tag_update(&par->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - /* preconditions */ - if (partype == PAR_FOLLOW || partype == PAR_PATH_CONST) { - if (par->type != OB_CURVE) { - return 0; - } - Curve *cu = par->data; - Curve *cu_eval = parent_eval->data; - if ((cu->flag & CU_PATH) == 0) { - cu->flag |= CU_PATH | CU_FOLLOW; - cu_eval->flag |= CU_PATH | CU_FOLLOW; - /* force creation of path data */ - BKE_displist_make_curveTypes(depsgraph, scene, par, false, false); - } - else { - cu->flag |= CU_FOLLOW; - cu_eval->flag |= CU_FOLLOW; - } + /* Preconditions. */ + if (ob == par) { + /* Parenting an object to itself is impossible. */ + return true; + } - /* if follow, add F-Curve for ctime (i.e. "eval_time") so that path-follow works */ - if (partype == PAR_FOLLOW) { - /* get or create F-Curve */ - bAction *act = ED_id_action_ensure(bmain, &cu->id); - FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, NULL, "eval_time", 0); + if (BKE_object_parent_loop_check(par, ob)) { + BKE_report(reports, RPT_ERROR, "Loop in parents"); + return false; + } - /* setup dummy 'generator' modifier here to get 1-1 correspondence still working */ - if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) { - add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu); + switch (partype) { + case PAR_FOLLOW: + case PAR_PATH_CONST: { + if (par->type != OB_CURVE) { + return false; + } + Curve *cu = par->data; + Curve *cu_eval = parent_eval->data; + if ((cu->flag & CU_PATH) == 0) { + cu->flag |= CU_PATH | CU_FOLLOW; + cu_eval->flag |= CU_PATH | CU_FOLLOW; + /* force creation of path data */ + BKE_displist_make_curveTypes(depsgraph, scene, par, false, false); + } + else { + cu->flag |= CU_FOLLOW; + cu_eval->flag |= CU_FOLLOW; } - } - /* fall back on regular parenting now (for follow only) */ - if (partype == PAR_FOLLOW) { - partype = PAR_OBJECT; - } - } - else if (ELEM(partype, PAR_BONE, PAR_BONE_RELATIVE)) { - pchan = BKE_pose_channel_active(par); - pchan_eval = BKE_pose_channel_active(parent_eval); + /* if follow, add F-Curve for ctime (i.e. "eval_time") so that path-follow works */ + if (partype == PAR_FOLLOW) { + /* get or create F-Curve */ + bAction *act = ED_id_action_ensure(bmain, &cu->id); + FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, NULL, "eval_time", 0); - if (pchan == NULL) { - BKE_report(reports, RPT_ERROR, "No active bone"); - return false; - } - } + /* setup dummy 'generator' modifier here to get 1-1 correspondence still working */ + if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) { + add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu); + } + } - if (ob != par) { - if (BKE_object_parent_loop_check(par, ob)) { - BKE_report(reports, RPT_ERROR, "Loop in parents"); - return false; + /* fall back on regular parenting now (for follow only) */ + if (partype == PAR_FOLLOW) { + partype = PAR_OBJECT; + } + break; } + case PAR_BONE: + case PAR_BONE_RELATIVE: + pchan = BKE_pose_channel_active(par); + pchan_eval = BKE_pose_channel_active(parent_eval); - Object workob; + if (pchan == NULL) { + BKE_report(reports, RPT_ERROR, "No active bone"); + return false; + } + } - /* apply transformation of previous parenting */ - if (keep_transform) { - /* was removed because of bug [#23577], - * but this can be handy in some cases too [#32616], so make optional */ - BKE_object_apply_mat4(ob, ob->obmat, false, false); - } + Object workob; - /* set the parent (except for follow-path constraint option) */ - if (partype != PAR_PATH_CONST) { - ob->parent = par; - /* Always clear parentinv matrix for sake of consistency, see T41950. */ - unit_m4(ob->parentinv); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); - } + /* Apply transformation of previous parenting. */ + if (keep_transform) { + /* was removed because of bug [#23577], + * but this can be handy in some cases too [#32616], so make optional */ + BKE_object_apply_mat4(ob, ob->obmat, false, false); + } - /* handle types */ - if (pchan) { - BLI_strncpy(ob->parsubstr, pchan->name, sizeof(ob->parsubstr)); - } - else { - ob->parsubstr[0] = 0; - } + /* Set the parent (except for follow-path constraint option). */ + if (partype != PAR_PATH_CONST) { + ob->parent = par; + /* Always clear parentinv matrix for sake of consistency, see T41950. */ + unit_m4(ob->parentinv); + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + } - if (partype == PAR_PATH_CONST) { - /* don't do anything here, since this is not technically "parenting" */ - } - else if (ELEM(partype, PAR_CURVE, PAR_LATTICE) || (pararm)) { + /* Handle types. */ + if (pchan) { + BLI_strncpy(ob->parsubstr, pchan->name, sizeof(ob->parsubstr)); + } + else { + ob->parsubstr[0] = 0; + } + + switch (partype) { + case PAR_PATH_CONST: + /* Don't do anything here, since this is not technically "parenting". */ + break; + case PAR_CURVE: + case PAR_LATTICE: + case PAR_ARMATURE: + case PAR_ARMATURE_NAME: + case PAR_ARMATURE_ENVELOPE: + case PAR_ARMATURE_AUTO: /* partype is now set to PAROBJECT so that invisible 'virtual' * modifiers don't need to be created. * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL, * creating the virtual modifiers. */ - ob->partype = PAROBJECT; /* note, dna define, not operator property */ - /* ob->partype = PARSKEL; */ /* note, dna define, not operator property */ + ob->partype = PAROBJECT; /* Note: DNA define, not operator property. */ + /* ob->partype = PARSKEL; */ /* Note: DNA define, not operator property. */ /* BUT, to keep the deforms, we need a modifier, * and then we need to set the object that it uses @@ -823,109 +835,111 @@ bool ED_object_parent_set(ReportList *reports, break; } } - } - else if (partype == PAR_BONE) { - ob->partype = PARBONE; /* note, dna define, not operator property */ + break; + case PAR_BONE: + ob->partype = PARBONE; /* Note: DNA define, not operator property. */ if (pchan->bone) { pchan->bone->flag &= ~BONE_RELATIVE_PARENTING; pchan_eval->bone->flag &= ~BONE_RELATIVE_PARENTING; } - } - else if (partype == PAR_BONE_RELATIVE) { - ob->partype = PARBONE; /* note, dna define, not operator property */ + break; + case PAR_BONE_RELATIVE: + ob->partype = PARBONE; /* Note: DNA define, not operator property. */ if (pchan->bone) { pchan->bone->flag |= BONE_RELATIVE_PARENTING; pchan_eval->bone->flag |= BONE_RELATIVE_PARENTING; } - } - else if (partype == PAR_VERTEX) { + break; + case PAR_VERTEX: ob->partype = PARVERT1; ob->par1 = vert_par[0]; - } - else if (partype == PAR_VERTEX_TRI) { + break; + case PAR_VERTEX_TRI: ob->partype = PARVERT3; copy_v3_v3_int(&ob->par1, vert_par); - } - else { - ob->partype = PAROBJECT; /* note, dna define, not operator property */ - } + break; + case PAR_OBJECT: + case PAR_FOLLOW: + ob->partype = PAROBJECT; /* Note: DNA define, not operator property. */ + break; + } - /* constraint */ - if (partype == PAR_PATH_CONST) { - bConstraint *con; - bFollowPathConstraint *data; - float cmat[4][4], vec[3]; + /* Constraint and set parent inverse. */ + const bool is_armature_parent = ELEM( + partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); + if (partype == PAR_PATH_CONST) { + bConstraint *con; + bFollowPathConstraint *data; + float cmat[4][4], vec[3]; - con = BKE_constraint_add_for_object(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH); + con = BKE_constraint_add_for_object(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH); - data = con->data; - data->tar = par; + data = con->data; + data->tar = par; - BKE_constraint_target_matrix_get( - depsgraph, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); - sub_v3_v3v3(vec, ob->obmat[3], cmat[3]); + BKE_constraint_target_matrix_get( + depsgraph, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); + sub_v3_v3v3(vec, ob->obmat[3], cmat[3]); - copy_v3_v3(ob->loc, vec); + copy_v3_v3(ob->loc, vec); + } + else if (is_armature_parent && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) { + if (partype == PAR_ARMATURE_NAME) { + ED_object_vgroup_calc_from_armature( + reports, depsgraph, scene, ob, par, ARM_GROUPS_NAME, false); } - else if (pararm && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) { - if (partype == PAR_ARMATURE_NAME) { - ED_object_vgroup_calc_from_armature( - reports, depsgraph, scene, ob, par, ARM_GROUPS_NAME, false); - } - else if (partype == PAR_ARMATURE_ENVELOPE) { - ED_object_vgroup_calc_from_armature( - reports, depsgraph, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); - } - else if (partype == PAR_ARMATURE_AUTO) { - WM_cursor_wait(1); - ED_object_vgroup_calc_from_armature( - reports, depsgraph, scene, ob, par, ARM_GROUPS_AUTO, xmirror); - WM_cursor_wait(0); - } - /* get corrected inverse */ - ob->partype = PAROBJECT; - BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); - - invert_m4_m4(ob->parentinv, workob.obmat); + else if (partype == PAR_ARMATURE_ENVELOPE) { + ED_object_vgroup_calc_from_armature( + reports, depsgraph, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); } - else if (pararm && (ob->type == OB_GPENCIL) && (par->type == OB_ARMATURE)) { - if (partype == PAR_ARMATURE) { - ED_gpencil_add_armature(C, reports, ob, par); - } - else if (partype == PAR_ARMATURE_NAME) { - ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_NAME); - } - else if ((partype == PAR_ARMATURE_AUTO) || (partype == PAR_ARMATURE_ENVELOPE)) { - WM_cursor_wait(1); - ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_AUTO); - WM_cursor_wait(0); - } - /* get corrected inverse */ - ob->partype = PAROBJECT; - BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); - - invert_m4_m4(ob->parentinv, workob.obmat); + else if (partype == PAR_ARMATURE_AUTO) { + WM_cursor_wait(1); + ED_object_vgroup_calc_from_armature( + reports, depsgraph, scene, ob, par, ARM_GROUPS_AUTO, xmirror); + WM_cursor_wait(0); } - else if ((ob->type == OB_GPENCIL) && (par->type == OB_LATTICE)) { - /* Add Lattice modifier */ - if (partype == PAR_LATTICE) { - ED_gpencil_add_lattice_modifier(C, reports, ob, par); - } - /* get corrected inverse */ - ob->partype = PAROBJECT; - BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); + /* get corrected inverse */ + ob->partype = PAROBJECT; + BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); - invert_m4_m4(ob->parentinv, workob.obmat); + invert_m4_m4(ob->parentinv, workob.obmat); + } + else if (is_armature_parent && (ob->type == OB_GPENCIL) && (par->type == OB_ARMATURE)) { + if (partype == PAR_ARMATURE) { + ED_gpencil_add_armature(C, reports, ob, par); } - else { - /* calculate inverse parent matrix */ - BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); - invert_m4_m4(ob->parentinv, workob.obmat); + else if (partype == PAR_ARMATURE_NAME) { + ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_NAME); + } + else if ((partype == PAR_ARMATURE_AUTO) || (partype == PAR_ARMATURE_ENVELOPE)) { + WM_cursor_wait(1); + ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_AUTO); + WM_cursor_wait(0); } + /* get corrected inverse */ + ob->partype = PAROBJECT; + BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + invert_m4_m4(ob->parentinv, workob.obmat); + } + else if ((ob->type == OB_GPENCIL) && (par->type == OB_LATTICE)) { + /* Add Lattice modifier */ + if (partype == PAR_LATTICE) { + ED_gpencil_add_lattice_modifier(C, reports, ob, par); + } + /* get corrected inverse */ + ob->partype = PAROBJECT; + BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); + + invert_m4_m4(ob->parentinv, workob.obmat); + } + else { + /* calculate inverse parent matrix */ + BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); + invert_m4_m4(ob->parentinv, workob.obmat); } + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); return true; } -- cgit v1.2.3 From 63dc72c35215d38c437a5d20a8dc8f6e25e1fc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Sep 2020 11:33:35 +0200 Subject: Cleanup: USD export, refactor mesh instancing Extract the mesh instancing code from the mesh writing function into a generic 'mark as instance' function on the abstract USD writer. This will help in supporting non-mesh instances. No functional changes. --- .../blender/io/usd/intern/usd_writer_abstract.cc | 27 ++++++++++++++++++++++ source/blender/io/usd/intern/usd_writer_abstract.h | 4 ++++ source/blender/io/usd/intern/usd_writer_mesh.cc | 23 +++++------------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index 4910b7f11dd..082a60d102e 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -21,6 +21,8 @@ #include +#include "BLI_assert.h" + /* TfToken objects are not cheap to construct, so we do it once. */ namespace usdtokens { // Materials @@ -128,6 +130,31 @@ void USDAbstractWriter::write_visibility(const HierarchyContext &context, usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode); } +/* Reference the original data instead of writing a copy. */ +bool USDAbstractWriter::mark_as_instance(HierarchyContext &context, const pxr::UsdPrim &prim) +{ + BLI_assert(context.is_instance()); + + if (context.export_path == context.original_export_path) { + printf("USD ref error: export path is reference path: %s\n", context.export_path.c_str()); + BLI_assert(!"USD reference error"); + return false; + } + + pxr::SdfPath ref_path(context.original_export_path); + if (!prim.GetReferences().AddInternalReference(ref_path)) { + /* See this URL for a description fo why referencing may fail" + * https://graphics.pixar.com/usd/docs/api/class_usd_references.html#Usd_Failing_References + */ + printf("USD Export warning: unable to add reference from %s to %s, not instancing object\n", + context.export_path.c_str(), + context.original_export_path.c_str()); + return false; + } + + return true; +} + } // 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 248bdd22a3b..f702768f734 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -76,6 +76,10 @@ class USDAbstractWriter : public AbstractHierarchyWriter { void write_visibility(const HierarchyContext &context, const pxr::UsdTimeCode timecode, pxr::UsdGeomImageable &usd_geometry); + + /* Turn `prim` into an instance referencing `context.original_export_path`. + * Return true when the instancing was succesful, false otherwise. */ + virtual bool mark_as_instance(HierarchyContext &context, const pxr::UsdPrim &prim); }; } // 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 7d3ea911a65..2073d4cbe87 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -160,29 +160,18 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh) get_geometry_data(mesh, usd_mesh_data); if (usd_export_context_.export_params.use_instancing && context.is_instance()) { - // This object data is instanced, just reference the original instead of writing a copy. - if (context.export_path == context.original_export_path) { - printf("USD ref error: export path is reference path: %s\n", context.export_path.c_str()); - BLI_assert(!"USD reference error"); - return; - } - pxr::SdfPath ref_path(context.original_export_path); - if (!usd_mesh.GetPrim().GetReferences().AddInternalReference(ref_path)) { - /* See this URL for a description fo why referencing may fail" - * https://graphics.pixar.com/usd/docs/api/class_usd_references.html#Usd_Failing_References - */ - printf("USD Export warning: unable to add reference from %s to %s, not instancing object\n", - context.export_path.c_str(), - context.original_export_path.c_str()); + if (!mark_as_instance(context, usd_mesh.GetPrim())) { return; } + /* The material path will be of the form , which is outside the - sub-tree pointed to by ref_path. As a result, the referenced data is not allowed to point out - of its own sub-tree. It does work when we override the material with exactly the same path, - though.*/ + * sub-tree pointed to by ref_path. As a result, the referenced data is not allowed to point + * out of its own sub-tree. It does work when we override the material with exactly the same + * path, though.*/ if (usd_export_context_.export_params.export_materials) { assign_materials(context, usd_mesh, usd_mesh_data.face_groups); } + return; } -- cgit v1.2.3 From 5becbf97192e3759fe36b12e4a03f7c7c88e682d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Sep 2020 11:45:31 +0200 Subject: Cleanup: Refactor USD Exporter, make parameter const Follow-up of 63dc72c3521, make parameter `const`. No functional changes. --- source/blender/io/usd/intern/usd_writer_abstract.cc | 2 +- source/blender/io/usd/intern/usd_writer_abstract.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index 082a60d102e..0edfbc62d6b 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -131,7 +131,7 @@ void USDAbstractWriter::write_visibility(const HierarchyContext &context, } /* Reference the original data instead of writing a copy. */ -bool USDAbstractWriter::mark_as_instance(HierarchyContext &context, const pxr::UsdPrim &prim) +bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim) { BLI_assert(context.is_instance()); diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index f702768f734..88df7cb1cc6 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -79,7 +79,7 @@ class USDAbstractWriter : public AbstractHierarchyWriter { /* Turn `prim` into an instance referencing `context.original_export_path`. * Return true when the instancing was succesful, false otherwise. */ - virtual bool mark_as_instance(HierarchyContext &context, const pxr::UsdPrim &prim); + virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim); }; } // namespace usd -- cgit v1.2.3 From 489aeabb9e500ab852a42e73b4e19cf1e80c62ba Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 8 Sep 2020 08:51:34 +0200 Subject: DrawManager: Move tests in namespace Using blender::draw::tests as namespaces. --- source/blender/draw/tests/shaders_test.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index b82746e4609..eb7a37711e6 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -15,6 +15,8 @@ #include "engines/overlay/overlay_private.h" #include "engines/workbench/workbench_private.h" +namespace blender::draw::tests { + /* Base class for draw test cases. It will setup and tear down the GPU part around each test. */ class DrawTest : public ::testing::Test { private: @@ -319,4 +321,6 @@ TEST_F(DrawTest, eevee_glsl_shaders_static) EXPECT_NE(EEVEE_shaders_effect_screen_raytrace_sh_get(ssr_option), nullptr); } EEVEE_shaders_free(); -} \ No newline at end of file +} + +} // namespace blender::draw::tests \ No newline at end of file -- cgit v1.2.3 From 0d68f55789aff106bdf9e038812d358ca55c060f Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 8 Sep 2020 10:40:30 +0200 Subject: DrawManager: Fixed memory leak in test cases Memory leak is introduced as test cases reinitializes the GPU stack. Added a call to GPU_backend_exit to fix this. In GPU_backend_exit the GPU backend was destroyed but the pointer wasn't reset for reuse. This patch also clears the pointer to be reused. --- source/blender/draw/tests/shaders_test.cc | 1 + source/blender/gpu/intern/gpu_context.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index eb7a37711e6..95474dad8b8 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -37,6 +37,7 @@ class DrawTest : public ::testing::Test { void TearDown() override { GPU_exit(); + GPU_backend_exit(); GPU_context_discard(context); GHOST_DisposeOpenGLContext(ghost_system, ghost_context); GHOST_DisposeSystem(ghost_system); diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 188225b3eed..119c1ef9c55 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -185,6 +185,7 @@ void GPU_backend_exit(void) /* TODO assert no resource left. Currently UI textures are still not freed in their context * correctly. */ delete g_backend; + g_backend = NULL; } GPUBackend *GPUBackend::get(void) -- cgit v1.2.3 From ab6f59ff3b8c7e821b4cb486c83ab1faada42e5e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 8 Sep 2020 11:31:47 +0200 Subject: GPU: Extract GPU Base Test case The draw manager test case initialized ghost, gpu and draw manager. This change splits the base test case to GPU specific and draw manager specific test case. The GPU test base test case will be used for low level GPU tests. --- source/blender/draw/CMakeLists.txt | 2 +- source/blender/draw/tests/shaders_test.cc | 29 +++++------------------------ source/blender/gpu/CMakeLists.txt | 16 ++++++++++++++++ source/blender/gpu/tests/gpu_testing.cc | 31 +++++++++++++++++++++++++++++++ source/blender/gpu/tests/gpu_testing.hh | 27 +++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 25 deletions(-) create mode 100644 source/blender/gpu/tests/gpu_testing.cc create mode 100644 source/blender/gpu/tests/gpu_testing.hh diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index b299df50852..8aea2f8e969 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -437,9 +437,9 @@ if(WITH_GTESTS) ) set(TEST_INC "../../../intern/ghost/" + "../gpu/tests/" ) set(TEST_LIB - bf_draw ) include(GTestTesting) blender_add_test_lib(bf_draw_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index 95474dad8b8..b73c94208b5 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -7,41 +7,22 @@ #include "GPU_context.h" #include "GPU_init_exit.h" #include "GPU_shader.h" - -#include "GHOST_C-api.h" +#include "gpu_testing.hh" #include "engines/eevee/eevee_private.h" #include "engines/gpencil/gpencil_engine.h" #include "engines/overlay/overlay_private.h" #include "engines/workbench/workbench_private.h" -namespace blender::draw::tests { +namespace blender::draw { /* Base class for draw test cases. It will setup and tear down the GPU part around each test. */ -class DrawTest : public ::testing::Test { - private: - GHOST_SystemHandle ghost_system; - GHOST_ContextHandle ghost_context; - GPUContext *context; - +class DrawTest : public blender::gpu::GPUTest { void SetUp() override { - GHOST_GLSettings glSettings = {0}; - ghost_system = GHOST_CreateSystem(); - ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings); - context = GPU_context_create(NULL); - GPU_init(); + GPUTest::SetUp(); DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); } - - void TearDown() override - { - GPU_exit(); - GPU_backend_exit(); - GPU_context_discard(context); - GHOST_DisposeOpenGLContext(ghost_system, ghost_context); - GHOST_DisposeSystem(ghost_system); - } }; TEST_F(DrawTest, workbench_glsl_shaders) @@ -324,4 +305,4 @@ TEST_F(DrawTest, eevee_glsl_shaders_static) EEVEE_shaders_free(); } -} // namespace blender::draw::tests \ No newline at end of file +} // namespace blender::draw \ No newline at end of file diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 0a372125391..bb50cd3744f 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -379,3 +379,19 @@ if(WITH_IMAGE_DDS) endif() blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +if(WITH_GTESTS) + if(WITH_OPENGL_DRAW_TESTS) + set(TEST_SRC + tests/gpu_testing.cc + ) + set(TEST_INC + "../../../intern/ghost/" + ) + set(TEST_LIB + + ) + include(GTestTesting) + blender_add_test_lib(bf_gpu_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") + endif() +endif() diff --git a/source/blender/gpu/tests/gpu_testing.cc b/source/blender/gpu/tests/gpu_testing.cc new file mode 100644 index 00000000000..2772139b8f6 --- /dev/null +++ b/source/blender/gpu/tests/gpu_testing.cc @@ -0,0 +1,31 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "GPU_context.h" +#include "GPU_init_exit.h" +#include "gpu_testing.hh" + +#include "GHOST_C-api.h" + +namespace blender::gpu { + +void GPUTest::SetUp() +{ + GHOST_GLSettings glSettings = {0}; + ghost_system = GHOST_CreateSystem(); + ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings); + context = GPU_context_create(NULL); + GPU_init(); +} + +void GPUTest::TearDown() +{ + GPU_exit(); + GPU_backend_exit(); + GPU_context_discard(context); + GHOST_DisposeOpenGLContext(ghost_system, ghost_context); + GHOST_DisposeSystem(ghost_system); +} + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/tests/gpu_testing.hh b/source/blender/gpu/tests/gpu_testing.hh new file mode 100644 index 00000000000..7e9203d2d7c --- /dev/null +++ b/source/blender/gpu/tests/gpu_testing.hh @@ -0,0 +1,27 @@ +#include "testing/testing.h" + +#include "GHOST_C-api.h" + +struct GPUContext; + +namespace blender::gpu { + +/* Test class that setups a GPUContext for test cases. + * + * Usage: + * TEST_F(GPUTest, my_gpu_test) { + * ... + * } + */ +class GPUTest : public ::testing::Test { + private: + GHOST_SystemHandle ghost_system; + GHOST_ContextHandle ghost_context; + struct GPUContext *context; + + protected: + void SetUp() override; + void TearDown() override; +}; + +} // namespace blender::gpu \ No newline at end of file -- cgit v1.2.3 From 2af70acc3a66d49cf048e44ade55bdd71c65ed3c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 8 Sep 2020 15:20:07 +0200 Subject: Cleanup: reduce variable scopes in drawnode.c --- source/blender/editors/space_node/drawnode.c | 145 +++++++++++---------------- 1 file changed, 58 insertions(+), 87 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 82f3b71eb32..9db89ec1ba2 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -116,12 +116,10 @@ static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiLayout *row, *col; - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - col = uiLayoutColumn(layout, false); - row = uiLayoutRow(col, true); + uiLayout *col = uiLayoutColumn(layout, false); + uiLayout *row = uiLayoutRow(col, true); uiItemR(row, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE); if (ELEM(ntree->type, NTREE_COMPOSIT, NTREE_TEXTURE)) { uiItemR(row, ptr, "use_alpha", DEFAULT_FLAGS, "", ICON_IMAGE_RGB_ALPHA); @@ -132,7 +130,6 @@ static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiLayout *row; #if 0 /* XXX no context access here .. */ bNode *node = ptr->data; @@ -148,7 +145,7 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false, false); - row = uiLayoutRow(layout, true); + uiLayout *row = uiLayoutRow(layout, true); uiItemR(row, ptr, "frame_start", DEFAULT_FLAGS, IFACE_("Sta"), ICON_NONE); uiItemR(row, ptr, "frame_end", DEFAULT_FLAGS, IFACE_("End"), ICON_NONE); } @@ -317,12 +314,9 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, { const float margin = 1.5f * U.widget_unit; NodeFrame *data = (NodeFrame *)node->storage; - bool bbinit; - bNode *tnode; - rctf rect, noderect; - float xmax, ymax; /* init rect from current frame size */ + rctf rect; node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax); node_to_view( node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin); @@ -330,15 +324,15 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, /* frame can be resized manually only if shrinking is disabled or no children are attached */ data->flag |= NODE_FRAME_RESIZEABLE; /* for shrinking bbox, initialize the rect from first child node */ - bbinit = (data->flag & NODE_FRAME_SHRINK); + bool bbinit = (data->flag & NODE_FRAME_SHRINK); /* fit bounding box to all children */ - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { + LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) { if (tnode->parent != node) { continue; } /* add margin to node rect */ - noderect = tnode->totr; + rctf noderect = tnode->totr; noderect.xmin -= margin; noderect.xmax += margin; noderect.ymin -= margin; @@ -357,6 +351,7 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, /* now adjust the frame size from view-space bounding box */ node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety); + float xmax, ymax; node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax); node->width = xmax - node->offsetx; node->height = -ymax + node->offsety; @@ -369,17 +364,9 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp /* XXX font id is crap design */ const int fontid = UI_style_get()->widgetlabel.uifont_id; NodeFrame *data = (NodeFrame *)node->storage; - rctf *rct = &node->totr; - int color_id = node_get_colorid(node); - char label[MAX_NAME]; - /* XXX a bit hacky, should use separate align values for x and y */ - float width, ascender; - float x, y; const int font_size = data->label_size / aspect; - const float margin = (float)(NODE_DY / 4); - int label_height; - uchar color[3]; + char label[MAX_NAME]; nodeLabel(ntree, node, label, sizeof(label)); BLF_enable(fontid, BLF_ASPECT); @@ -388,16 +375,21 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp BLF_size(fontid, MIN2(24, font_size), U.dpi); /* title color */ + int color_id = node_get_colorid(node); + uchar color[3]; UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color); BLF_color3ubv(fontid, color); - width = BLF_width(fontid, label, sizeof(label)); - ascender = BLF_ascender(fontid); - label_height = ((margin / aspect) + (ascender * aspect)); + const float margin = (float)(NODE_DY / 4); + const float width = BLF_width(fontid, label, sizeof(label)); + const float ascender = BLF_ascender(fontid); + const int label_height = ((margin / aspect) + (ascender * aspect)); /* 'x' doesn't need aspect correction */ - x = BLI_rctf_cent_x(rct) - (0.5f * width); - y = rct->ymax - label_height; + rctf *rct = &node->totr; + /* XXX a bit hacky, should use separate align values for x and y */ + float x = BLI_rctf_cent_x(rct) - (0.5f * width); + float y = rct->ymax - label_height; BLF_position(fontid, x, y, 0); BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX); @@ -405,17 +397,15 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp /* draw text body */ if (node->id) { Text *text = (Text *)node->id; - TextLine *line; const int line_height_max = BLF_height_max(fontid); const float line_spacing = (line_height_max * aspect); const float line_width = (BLI_rctf_size_x(rct) - margin) / aspect; - int y_min; /* 'x' doesn't need aspect correction */ x = rct->xmin + margin; y = rct->ymax - (label_height + line_spacing); /* early exit */ - y_min = y + ((margin * 2) - (y - rct->ymin)); + int y_min = y + ((margin * 2) - (y - rct->ymin)); BLF_enable(fontid, BLF_CLIPPING | BLF_WORD_WRAP); BLF_clipping(fontid, @@ -427,7 +417,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp BLF_wordwrap(fontid, line_width); - for (line = text->lines.first; line; line = line->next) { + LISTBASE_FOREACH (TextLine *, line, &text->lines) { struct ResultBLF info; if (line->line[0]) { BLF_position(fontid, x, y, 0); @@ -455,9 +445,6 @@ static void node_draw_frame(const bContext *C, bNode *node, bNodeInstanceKey UNUSED(key)) { - rctf *rct = &node->totr; - float color[4]; - float alpha; /* skip if out of view */ if (BLI_rctf_isect(&node->totr, ®ion->v2d.cur, NULL) == false) { @@ -466,8 +453,9 @@ static void node_draw_frame(const bContext *C, return; } + float color[4]; UI_GetThemeColor4fv(TH_NODE_FRAME, color); - alpha = color[3]; + const float alpha = color[3]; /* shadow */ node_draw_shadow(snode, node, BASIS_RAD, alpha); @@ -480,6 +468,7 @@ static void node_draw_frame(const bContext *C, UI_GetThemeColor4fv(TH_NODE_FRAME, color); } + const rctf *rct = &node->totr; UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color); @@ -544,15 +533,12 @@ static void node_draw_reroute_prepare(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node) { - bNodeSocket *nsock; - float locx, locy; - float size = NODE_REROUTE_SIZE; - /* get "global" coords */ + float locx, locy; node_to_view(node, 0.0f, 0.0f, &locx, &locy); /* reroute node has exactly one input and one output, both in the same place */ - nsock = node->outputs.first; + bNodeSocket *nsock = node->outputs.first; nsock->locx = locx; nsock->locy = locy; @@ -560,6 +546,7 @@ static void node_draw_reroute_prepare(const bContext *UNUSED(C), nsock->locx = locx; nsock->locy = locy; + const float size = NODE_REROUTE_SIZE; node->width = size * 2; node->totr.xmin = locx - size; node->totr.xmax = locx + size; @@ -687,18 +674,15 @@ static void node_buts_image_user(uiLayout *layout, PointerRNA *iuserptr, bool compositor) { - uiLayout *col; - int source; - if (!imaptr->data) { return; } - col = uiLayoutColumn(layout, false); + uiLayout *col = uiLayoutColumn(layout, false); uiItemR(col, imaptr, "source", DEFAULT_FLAGS, "", ICON_NONE); - source = RNA_enum_get(imaptr, "source"); + const int source = RNA_enum_get(imaptr, "source"); if (source == IMA_SRC_SEQUENCE) { /* don't use iuser->framenr directly @@ -943,8 +927,8 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout, bNode *node = ptr->data; NodeShaderTexPointDensity *shader_point_density = node->storage; Object *ob = (Object *)node->id; - PointerRNA ob_ptr, obdata_ptr; + PointerRNA ob_ptr, obdata_ptr; RNA_id_pointer_create((ID *)ob, &ob_ptr); RNA_id_pointer_create(ob ? (ID *)ob->data : NULL, &obdata_ptr); @@ -1398,8 +1382,8 @@ static void node_buts_image_views(uiLayout *layout, static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; - PointerRNA imaptr, iuserptr; + PointerRNA iuserptr; RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr); uiLayoutSetContextPointer(layout, "image_user", &iuserptr); uiTemplateID(layout, @@ -1416,7 +1400,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * return; } - imaptr = RNA_pointer_get(ptr, "image"); + PointerRNA imaptr = RNA_pointer_get(ptr, "image"); node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr, true); @@ -1426,8 +1410,8 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; - PointerRNA iuserptr; + PointerRNA iuserptr; RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr); uiLayoutSetContextPointer(layout, "image_user", &iuserptr); uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 1); @@ -1437,11 +1421,6 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer { bNode *node = ptr->data; uiLayout *col, *row; - PointerRNA op_ptr; - PointerRNA scn_ptr; - PropertyRNA *prop; - const char *layer_name; - char scene_name[MAX_ID_NAME - 2]; uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); @@ -1453,15 +1432,19 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer row = uiLayoutRow(col, true); uiItemR(row, ptr, "layer", DEFAULT_FLAGS, "", ICON_NONE); - prop = RNA_struct_find_property(ptr, "layer"); + PropertyRNA *prop = RNA_struct_find_property(ptr, "layer"); + const char *layer_name; if (!(RNA_property_enum_identifier( C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name))) { return; } + PointerRNA scn_ptr; + char scene_name[MAX_ID_NAME - 2]; scn_ptr = RNA_pointer_get(ptr, "scene"); RNA_string_get(&scn_ptr, "name", scene_name); + PointerRNA op_ptr; uiItemFullO( row, "RENDER_OT_render", "", ICON_RENDER_STILL, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_string_set(&op_ptr, "layer", layer_name); @@ -1471,12 +1454,10 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *col, *row; - int reference; - int filter; col = uiLayoutColumn(layout, false); - filter = RNA_enum_get(ptr, "filter_type"); - reference = RNA_boolean_get(ptr, "use_variable_size"); + const int filter = RNA_enum_get(ptr, "filter_type"); + const int reference = RNA_boolean_get(ptr, "use_variable_size"); uiItemR(col, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE); if (filter != R_FILTER_FAST_GAUSS) { @@ -1925,9 +1906,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi Scene *scene = CTX_data_scene(C); PointerRNA imfptr = RNA_pointer_get(ptr, "format"); PointerRNA active_input_ptr, op_ptr; - wmOperatorType *ot; uiLayout *row, *col; - int active_index; const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER; const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; @@ -1947,7 +1926,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi row = uiLayoutRow(layout, false); col = uiLayoutColumn(row, true); - active_index = RNA_int_get(ptr, "active_input_index"); + const int active_index = RNA_int_get(ptr, "active_input_index"); /* using different collection properties if multilayer format is enabled */ if (multilayer) { uiTemplateList(col, @@ -1992,7 +1971,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi active_input_ptr.owner_id = ptr->owner_id; col = uiLayoutColumn(row, true); - ot = WM_operatortype_find("NODE_OT_output_file_move_active_socket", false); + wmOperatorType *ot = WM_operatortype_find("NODE_OT_output_file_move_active_socket", false); uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_enum_set(&op_ptr, "direction", 1); uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); @@ -3435,13 +3414,12 @@ static void node_file_output_socket_draw(bContext *C, bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocket *sock = ptr->data; uiLayout *row; - PointerRNA inputptr, imfptr; - int imtype; + PointerRNA inputptr; row = uiLayoutRow(layout, false); - imfptr = RNA_pointer_get(node_ptr, "format"); - imtype = RNA_enum_get(&imfptr, "file_format"); + PointerRNA imfptr = RNA_pointer_get(node_ptr, "format"); + int imtype = RNA_enum_get(&imfptr, "file_format"); if (imtype == R_IMF_IMTYPE_MULTILAYER) { NodeImageMultiFileSocket *input = sock->storage; @@ -3451,8 +3429,6 @@ static void node_file_output_socket_draw(bContext *C, } else { NodeImageMultiFileSocket *input = sock->storage; - PropertyRNA *imtype_prop; - const char *imtype_name; uiBlock *block; RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr); @@ -3462,7 +3438,8 @@ static void node_file_output_socket_draw(bContext *C, imfptr = RNA_pointer_get(&inputptr, "format"); } - imtype_prop = RNA_struct_find_property(&imfptr, "file_format"); + const char *imtype_name; + PropertyRNA *imtype_prop = RNA_struct_find_property(&imfptr, "file_format"); RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop, @@ -3611,9 +3588,6 @@ void draw_nodespace_back_pix(const bContext *C, bNodeInstanceKey active_viewer_key = (snode->nodetree ? snode->nodetree->active_viewer_key : NODE_INSTANCE_KEY_NONE); float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - Image *ima; - void *lock; - ImBuf *ibuf; GPU_matrix_push_projection(); GPU_matrix_push(); @@ -3631,19 +3605,18 @@ void draw_nodespace_back_pix(const bContext *C, return; } - ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + void *lock; + Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf) { - float x, y; - GPU_matrix_push_projection(); GPU_matrix_push(); /* somehow the offset has to be calculated inverse */ wmOrtho2_region_pixelspace(region); - x = (region->winx - snode->zoom * ibuf->x) / 2 + snode->xof; - y = (region->winy - snode->zoom * ibuf->y) / 2 + snode->yof; + const float x = (region->winx - snode->zoom * ibuf->x) / 2 + snode->xof; + const float y = (region->winy - snode->zoom * ibuf->y) / 2 + snode->yof; if (ibuf->rect || ibuf->rect_float) { uchar *display_buffer = NULL; @@ -3746,10 +3719,7 @@ static bool node_link_bezier_handles(View2D *v2d, bNodeLink *link, float vec[4][2]) { - float dist; - float deltax, deltay; float cursor[2] = {0.0f, 0.0f}; - int toreroute, fromreroute; /* this function can be called with snode null (via cut_links_intersect) */ /* XXX map snode->cursor back to view space */ @@ -3759,6 +3729,7 @@ static bool node_link_bezier_handles(View2D *v2d, } /* in v0 and v3 we put begin/end points */ + int toreroute, fromreroute; if (link->fromsock) { vec[0][0] = link->fromsock->locx; vec[0][1] = link->fromsock->locy; @@ -3794,9 +3765,9 @@ static bool node_link_bezier_handles(View2D *v2d, return true; } - dist = curving * 0.10f * fabsf(vec[0][0] - vec[3][0]); - deltax = vec[3][0] - vec[0][0]; - deltay = vec[3][1] - vec[0][1]; + const float dist = curving * 0.10f * fabsf(vec[0][0] - vec[3][0]); + const float deltax = vec[3][0] - vec[0][0]; + const float deltay = vec[3][1] - vec[0][1]; /* check direction later, for top sockets */ if (fromreroute) { if (fabsf(deltax) > fabsf(deltay)) { @@ -3850,9 +3821,9 @@ bool node_link_bezier_points( BKE_curve_forward_diff_bezier( vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0] + 1, resol, sizeof(float[2])); - return 1; + return true; } - return 0; + return false; } #define NODELINK_GROUP_SIZE 256 -- cgit v1.2.3 From acdea4e98bc7a909558a4f7efacf11a0b6d8e147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= Date: Tue, 8 Sep 2020 15:49:16 +0200 Subject: GLFrameBuffer: Fix mass renaming issue The context might be partialy freed, so use gpu::Context instead of GLcontext. --- source/blender/gpu/opengl/gl_framebuffer.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index 85fa973daff..14b7d78c2ff 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -78,8 +78,8 @@ GLFrameBuffer::~GLFrameBuffer() return; } - if (context_ == GLContext::get()) { - /* Context might be partially freed. This happens when destroying the window frame-buffers. */ + /* Context might be partially freed. This happens when destroying the window frame-buffers. */ + if (context_ == Context::get()) { glDeleteFramebuffers(1, &fbo_id_); } else { @@ -89,7 +89,7 @@ GLFrameBuffer::~GLFrameBuffer() if (context_->active_fb == this && context_->back_left != this) { /* If this assert triggers it means the frame-buffer is being freed while in use by another * context which, by the way, is TOTALLY UNSAFE!!! */ - BLI_assert(context_ == GLContext::get()); + BLI_assert(context_ == Context::get()); GPU_framebuffer_restore(); } } -- cgit v1.2.3 From 0fb9f22d8b37c73451123ff9035ff3c5506cc2e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= Date: Tue, 8 Sep 2020 16:04:31 +0200 Subject: GLContext: Fix clang warning about using override --- source/blender/gpu/opengl/gl_context.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index 63014903e0a..8e653a56cd6 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -98,8 +98,8 @@ class GLContext : public Context { void activate(void) override; void deactivate(void) override; - void flush(void); - void finish(void); + void flush(void) override; + void finish(void) override; void memory_statistics_get(int *total_mem, int *free_mem) override; -- cgit v1.2.3 From ab758c30d2ba46eabd9774951afaed52c8344855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= Date: Tue, 8 Sep 2020 16:05:36 +0200 Subject: GLBackend: Fix gl error inside the mip rendering workaround detection This was caused by an incorrect mipmap size. Also add debug checks for good mesure. --- source/blender/gpu/opengl/gl_backend.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 3dfe0e1e412..e55e07d5a0b 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -28,6 +28,8 @@ #include "glew-mx.h" +#include "gl_debug.hh" + #include "gl_backend.hh" namespace blender::gpu { @@ -151,6 +153,8 @@ static bool detect_mip_render_workaround(void) float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f}; float *source_pix = (float *)MEM_callocN(sizeof(float[4]) * cube_size * cube_size * 6, __func__); + /* NOTE: Debug layers are not yet enabled. Force use of glGetError. */ + debug::check_gl_error("Cubemap Workaround Start"); /* Not using GPU API since it is not yet fully initialized. */ GLuint tex, fb; /* Create cubemap with 2 mip level. */ @@ -158,8 +162,9 @@ static bool detect_mip_render_workaround(void) glBindTexture(GL_TEXTURE_CUBE_MAP, tex); for (int mip = 0; mip < 2; mip++) { for (int i = 0; i < 6; i++) { + const int width = cube_size / (1 << mip); GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; - glTexImage2D(target, mip, GL_RGBA16F, 2, 2, 0, GL_RGBA, GL_FLOAT, source_pix); + glTexImage2D(target, mip, GL_RGBA16F, width, width, 0, GL_RGBA, GL_FLOAT, source_pix); } } glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); @@ -182,6 +187,8 @@ static bool detect_mip_render_workaround(void) glDeleteFramebuffers(1, &fb); glDeleteTextures(1, &tex); + debug::check_gl_error("Cubemap Workaround End9"); + return enable_workaround; } -- cgit v1.2.3 From c0b4a93faedbbf53761fa86aafcc458f140700a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Sep 2020 14:14:04 +0200 Subject: Cleanup: Alembic export, split function into two Split the `ABCHierarchyIterator::create_data_writer()` function into two functions. This is to prepare for the creation of writers not just by object type, but also by goal, for example writers that reference other Alembic data instead of writing their own (i.e. instancing). No functional changes. --- .../io/alembic/exporter/abc_hierarchy_iterator.cc | 46 +++++++++++----------- .../io/alembic/exporter/abc_hierarchy_iterator.h | 4 ++ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc index 5b1b1b60b48..e8ca06d75fc 100644 --- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc +++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc @@ -171,34 +171,37 @@ AbstractHierarchyWriter *ABCHierarchyIterator::create_transform_writer( AbstractHierarchyWriter *ABCHierarchyIterator::create_data_writer(const HierarchyContext *context) { const ABCWriterConstructorArgs writer_args = writer_constructor_args(context); - ABCAbstractWriter *data_writer = nullptr; + ABCAbstractWriter *data_writer = create_data_writer_for_object_type(context, writer_args); + if (data_writer == nullptr || !data_writer->is_supported(context)) { + delete data_writer; + return nullptr; + } + + data_writer->create_alembic_objects(context); + return data_writer; +} + +ABCAbstractWriter *ABCHierarchyIterator::create_data_writer_for_object_type( + const HierarchyContext *context, const ABCWriterConstructorArgs &writer_args) +{ switch (context->object->type) { case OB_MESH: - data_writer = new ABCMeshWriter(writer_args); - break; + return new ABCMeshWriter(writer_args); case OB_CAMERA: - data_writer = new ABCCameraWriter(writer_args); - break; + return new ABCCameraWriter(writer_args); case OB_CURVE: if (params_.curves_as_mesh) { - data_writer = new ABCCurveMeshWriter(writer_args); + return new ABCCurveMeshWriter(writer_args); } - else { - data_writer = new ABCCurveWriter(writer_args); - } - break; + return new ABCCurveWriter(writer_args); case OB_SURF: if (params_.curves_as_mesh) { - data_writer = new ABCCurveMeshWriter(writer_args); - } - else { - data_writer = new ABCNurbsWriter(writer_args); + return new ABCCurveMeshWriter(writer_args); } - break; + return new ABCNurbsWriter(writer_args); case OB_MBALL: - data_writer = new ABCMetaballWriter(writer_args); - break; + return new ABCMetaballWriter(writer_args); case OB_EMPTY: case OB_LAMP: @@ -214,13 +217,8 @@ AbstractHierarchyWriter *ABCHierarchyIterator::create_data_writer(const Hierarch return nullptr; } - if (!data_writer->is_supported(context)) { - delete data_writer; - return nullptr; - } - - data_writer->create_alembic_objects(context); - return data_writer; + /* Just to please the compiler, all cases should be handled by the above switch. */ + return nullptr; } AbstractHierarchyWriter *ABCHierarchyIterator::create_hair_writer(const HierarchyContext *context) diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h index bd7e3f27c67..b8abfd74c4c 100644 --- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h +++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h @@ -36,6 +36,7 @@ namespace blender { namespace io { namespace alembic { +class ABCAbstractWriter; class ABCHierarchyIterator; struct ABCWriterConstructorArgs { @@ -85,6 +86,9 @@ class ABCHierarchyIterator : public AbstractHierarchyIterator { ABCWriterConstructorArgs writer_constructor_args(const HierarchyContext *context) const; void update_archive_bounding_box(); void update_bounding_box_recursive(Imath::Box3d &bounds, const HierarchyContext *context); + + ABCAbstractWriter *create_data_writer_for_object_type( + const HierarchyContext *context, const ABCWriterConstructorArgs &writer_args); }; } // namespace alembic -- cgit v1.2.3 From 9421d66a1b74f18b1eadbfdff4d8bfc08bd19913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Sep 2020 14:16:54 +0200 Subject: Cleanup: Alembic export, split `ABCHierarchyIterator::get_alembic_parent()` Split `ABCHierarchyIterator::get_alembic_parent()` into two functions: - For a given export path, find the Alembic object - Ensure that that object is usable as parent object (Alembic uses a specific 'top' object as parent to indicate "no parent"). The new function is `public` as it will be used in an upcoming feature, and is required to be public then. No functional changes. --- .../io/alembic/exporter/abc_hierarchy_iterator.cc | 24 +++++++++++++++------- .../io/alembic/exporter/abc_hierarchy_iterator.h | 2 ++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc index e8ca06d75fc..5fc5c47d4b9 100644 --- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc +++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc @@ -126,17 +126,27 @@ AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::determine context, dupli_object, dupli_parent_finder); } -Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent( - const HierarchyContext *context) const +Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_object( + const std::string &export_path) const { - Alembic::Abc::OObject parent; + if (export_path.empty()) { + return Alembic::Abc::OObject(); + } - if (!context->higher_up_export_path.empty()) { - AbstractHierarchyWriter *writer = get_writer(context->higher_up_export_path); - ABCAbstractWriter *abc_writer = static_cast(writer); - parent = abc_writer->get_alembic_object(); + AbstractHierarchyWriter *writer = get_writer(export_path); + if (writer == nullptr) { + return Alembic::Abc::OObject(); } + ABCAbstractWriter *abc_writer = static_cast(writer); + return abc_writer->get_alembic_object(); +} + +Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent( + const HierarchyContext *context) const +{ + Alembic::Abc::OObject parent = get_alembic_object(context->higher_up_export_path); + if (!parent.valid()) { /* An invalid parent object means "no parent", which should be translated to Alembic's top * archive object. */ diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h index b8abfd74c4c..5bc82564cdb 100644 --- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h +++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h @@ -62,6 +62,8 @@ class ABCHierarchyIterator : public AbstractHierarchyIterator { virtual void iterate_and_write() override; virtual std::string make_valid_name(const std::string &name) const override; + Alembic::Abc::OObject get_alembic_object(const std::string &export_path) const; + protected: virtual bool mark_as_weak_export(const Object *object) const override; -- cgit v1.2.3 From 8f4f9275cea6602e74eecf7e9a88c101f9cc5245 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 8 Sep 2020 16:30:09 +0200 Subject: UI: Aesthetic tweaks to Select All by Type operator * Match menu items with Add Menu (order and naming e.g. Font -> Text) * Use Icons * Remove ellipsis from the name (policy is to use `...` only when triggering a window/popup) No functional changes. Thanks @HooglyBoogly for the help! --- release/scripts/startup/bl_ui/space_view3d.py | 2 +- release/scripts/templates_py/ui_menu.py | 2 +- source/blender/editors/object/object_select.c | 2 +- source/blender/makesrna/intern/rna_object.c | 35 +++++++++++++++------------ 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 35b27940687..528eba06db1 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1369,7 +1369,7 @@ class VIEW3D_MT_select_object(Menu): layout.separator() - layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...") + layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type") layout.operator("object.select_camera", text="Select Active Camera") layout.operator("object.select_mirror", text="Mirror Selection") layout.operator("object.select_random", text="Select Random") diff --git a/release/scripts/templates_py/ui_menu.py b/release/scripts/templates_py/ui_menu.py index 36391a54f4e..7c19693485e 100644 --- a/release/scripts/templates_py/ui_menu.py +++ b/release/scripts/templates_py/ui_menu.py @@ -18,7 +18,7 @@ class CustomMenu(bpy.types.Menu): # use an operator enum property to populate a sub-menu layout.operator_menu_enum("object.select_by_type", property="type", - text="Select All by Type...", + text="Select All by Type", ) # call another menu diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index e20de5a92ff..5dfbaf583f6 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -440,7 +440,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op) void OBJECT_OT_select_by_type(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select By Type"; + ot->name = "Select by Type"; ot->description = "Select all visible objects that are of a type"; ot->idname = "OBJECT_OT_select_by_type"; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index e98fff13068..c7f625e2fa5 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -223,36 +223,39 @@ const EnumPropertyItem rna_enum_lightprobes_type_items[] = { /* used for 2 enums */ #define OBTYPE_CU_CURVE \ { \ - OB_CURVE, "CURVE", 0, "Curve", "" \ + OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve", "" \ } #define OBTYPE_CU_SURF \ { \ - OB_SURF, "SURFACE", 0, "Surface", "" \ + OB_SURF, "SURFACE", ICON_OUTLINER_OB_SURFACE, "Surface", "" \ } #define OBTYPE_CU_FONT \ { \ - OB_FONT, "FONT", 0, "Font", "" \ + OB_FONT, "FONT", ICON_OUTLINER_OB_FONT, "Text", "" \ } const EnumPropertyItem rna_enum_object_type_items[] = { - {OB_MESH, "MESH", 0, "Mesh", ""}, + {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh", ""}, OBTYPE_CU_CURVE, OBTYPE_CU_SURF, - {OB_MBALL, "META", 0, "Meta", ""}, + {OB_MBALL, "META", ICON_OUTLINER_OB_META, "Metaball", ""}, OBTYPE_CU_FONT, - {OB_HAIR, "HAIR", 0, "Hair", ""}, - {OB_POINTCLOUD, "POINTCLOUD", 0, "PointCloud", ""}, - {OB_VOLUME, "VOLUME", 0, "Volume", ""}, + {OB_HAIR, "HAIR", ICON_OUTLINER_OB_HAIR, "Hair", ""}, + {OB_POINTCLOUD, "POINTCLOUD", ICON_OUTLINER_OB_POINTCLOUD, "Point Cloud", ""}, + {OB_VOLUME, "VOLUME", ICON_OUTLINER_OB_VOLUME, "Volume", ""}, + {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil", ""}, {0, "", 0, NULL, NULL}, - {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, - {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, - {OB_EMPTY, "EMPTY", 0, "Empty", ""}, - {OB_GPENCIL, "GPENCIL", 0, "GPencil", ""}, + {OB_ARMATURE, "ARMATURE", ICON_OUTLINER_OB_ARMATURE, "Armature", ""}, + {OB_LATTICE, "LATTICE", ICON_OUTLINER_OB_LATTICE, "Lattice", ""}, {0, "", 0, NULL, NULL}, - {OB_CAMERA, "CAMERA", 0, "Camera", ""}, - {OB_LAMP, "LIGHT", 0, "Light", ""}, - {OB_SPEAKER, "SPEAKER", 0, "Speaker", ""}, - {OB_LIGHTPROBE, "LIGHT_PROBE", 0, "Probe", ""}, + {OB_EMPTY, "EMPTY", ICON_OUTLINER_OB_EMPTY, "Empty", ""}, + {0, "", 0, NULL, NULL}, + {OB_LAMP, "LIGHT", ICON_OUTLINER_OB_LIGHT, "Light", ""}, + {OB_LIGHTPROBE, "LIGHT_PROBE", ICON_OUTLINER_OB_LIGHTPROBE, "Light Probe", ""}, + {0, "", 0, NULL, NULL}, + {OB_CAMERA, "CAMERA", ICON_OUTLINER_OB_CAMERA, "Camera", ""}, + {0, "", 0, NULL, NULL}, + {OB_SPEAKER, "SPEAKER", ICON_OUTLINER_OB_SPEAKER, "Speaker", ""}, {0, NULL, 0, NULL, NULL}, }; -- cgit v1.2.3 From b3759cc0d67eeb8cec55314d3304db0bc02168af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 8 Sep 2020 16:15:49 +0200 Subject: Alembic Export: support instanced object data Add support for object data instancing. This is used when the objects are instances, for example when duplicated by a particle system, or instanced by the duplication system (collection-duplicating empties, vertex/face duplis, etc.) Since Alembic already deduplicates data, this doesn't make the resulting Alembic files any smaller. They will be faster to write, though, when there is a lot of instanced geometry, as the deduplication system won't have to do any comparisons. This instancing support is still limited, in the sense that only object data is instanced and all transforms are still written explicitly. A future improvement could be to support instancing entire collection hierarchies. Blender's Alembic importer has no understanding of these Alembic instances yet, and will thus happily duplicate the data on import. The USD Alembic plugin seems to have problems understanding the instancing. There might also be other software with similar issues. Because of this, instancing can be turned off in the exporter (it's on by default). --- source/blender/editors/io/io_alembic.c | 9 +++ source/blender/io/alembic/ABC_alembic.h | 1 + source/blender/io/alembic/CMakeLists.txt | 2 + .../io/alembic/exporter/abc_hierarchy_iterator.cc | 10 ++- .../io/alembic/exporter/abc_writer_instance.cc | 74 ++++++++++++++++++++++ .../io/alembic/exporter/abc_writer_instance.h | 48 ++++++++++++++ 6 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 source/blender/io/alembic/exporter/abc_writer_instance.cc create mode 100644 source/blender/io/alembic/exporter/abc_writer_instance.h diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index 22171d8be66..0c4064b5693 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -133,6 +133,7 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op) .use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"), .export_hair = RNA_boolean_get(op->ptr, "export_hair"), .export_particles = RNA_boolean_get(op->ptr, "export_particles"), + .use_instancing = RNA_boolean_get(op->ptr, "use_instancing"), .packuv = RNA_boolean_get(op->ptr, "packuv"), .triangulate = RNA_boolean_get(op->ptr, "triangulate"), .quad_method = RNA_enum_get(op->ptr, "quad_method"), @@ -189,6 +190,7 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr) uiItemS(col); uiItemR(col, imfptr, "flatten", 0, NULL, ICON_NONE); + uiItemR(sub, imfptr, "use_instancing", 0, IFACE_("Use Instancing"), ICON_NONE); sub = uiLayoutColumnWithHeading(col, true, IFACE_("Only")); uiItemR(sub, imfptr, "selected", 0, IFACE_("Selected Objects"), ICON_NONE); uiItemR(sub, imfptr, "renderable_only", 0, IFACE_("Renderable Objects"), ICON_NONE); @@ -401,6 +403,13 @@ void WM_OT_alembic_export(wmOperatorType *ot) "Curves as Mesh", "Export curves and NURBS surfaces as meshes"); + RNA_def_boolean(ot->srna, + "use_instancing", + true, + "Use Instancing", + "Export data of duplicated objects as Alembic instances; speeds up the export " + "and can be disabled for compatibility with other software"); + RNA_def_float( ot->srna, "global_scale", diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h index 28e3d0dd1f5..9a2c74c64a3 100644 --- a/source/blender/io/alembic/ABC_alembic.h +++ b/source/blender/io/alembic/ABC_alembic.h @@ -60,6 +60,7 @@ struct AlembicExportParams { bool triangulate; bool export_hair; bool export_particles; + bool use_instancing; /* See MOD_TRIANGULATE_NGON_xxx and MOD_TRIANGULATE_QUAD_xxx * in DNA_modifier_types.h */ diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt index de99a2c9d65..2b44146e475 100644 --- a/source/blender/io/alembic/CMakeLists.txt +++ b/source/blender/io/alembic/CMakeLists.txt @@ -63,6 +63,7 @@ set(SRC exporter/abc_writer_camera.cc exporter/abc_writer_curves.cc exporter/abc_writer_hair.cc + exporter/abc_writer_instance.cc exporter/abc_writer_mball.cc exporter/abc_writer_mesh.cc exporter/abc_writer_nurbs.cc @@ -89,6 +90,7 @@ set(SRC exporter/abc_writer_camera.h exporter/abc_writer_curves.h exporter/abc_writer_hair.h + exporter/abc_writer_instance.h exporter/abc_writer_mball.h exporter/abc_writer_mesh.h exporter/abc_writer_nurbs.h diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc index 5fc5c47d4b9..4cb6ca0c601 100644 --- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc +++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc @@ -22,6 +22,7 @@ #include "abc_writer_camera.h" #include "abc_writer_curves.h" #include "abc_writer_hair.h" +#include "abc_writer_instance.h" #include "abc_writer_mball.h" #include "abc_writer_mesh.h" #include "abc_writer_nurbs.h" @@ -181,7 +182,14 @@ AbstractHierarchyWriter *ABCHierarchyIterator::create_transform_writer( AbstractHierarchyWriter *ABCHierarchyIterator::create_data_writer(const HierarchyContext *context) { const ABCWriterConstructorArgs writer_args = writer_constructor_args(context); - ABCAbstractWriter *data_writer = create_data_writer_for_object_type(context, writer_args); + ABCAbstractWriter *data_writer = nullptr; + + if (params_.use_instancing && context->is_instance()) { + data_writer = new ABCInstanceWriter(writer_args); + } + else { + data_writer = create_data_writer_for_object_type(context, writer_args); + } if (data_writer == nullptr || !data_writer->is_supported(context)) { delete data_writer; diff --git a/source/blender/io/alembic/exporter/abc_writer_instance.cc b/source/blender/io/alembic/exporter/abc_writer_instance.cc new file mode 100644 index 00000000000..581d94ee961 --- /dev/null +++ b/source/blender/io/alembic/exporter/abc_writer_instance.cc @@ -0,0 +1,74 @@ +/* + * 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 balembic + */ + +#include "abc_writer_instance.h" +#include "abc_hierarchy_iterator.h" + +#include "BLI_assert.h" + +#include "CLG_log.h" +static CLG_LogRef LOG = {"io.alembic"}; + +namespace blender { +namespace io { +namespace alembic { + +using Alembic::Abc::OObject; + +ABCInstanceWriter::ABCInstanceWriter(const ABCWriterConstructorArgs &args) + : ABCAbstractWriter(args) +{ +} + +ABCInstanceWriter::~ABCInstanceWriter() +{ +} + +void ABCInstanceWriter::create_alembic_objects(const HierarchyContext *context) +{ + OObject original = args_.hierarchy_iterator->get_alembic_object(context->original_export_path); + OObject abc_parent = args_.abc_parent; + if (!abc_parent.addChildInstance(original, args_.abc_name)) { + CLOG_WARN(&LOG, "unable to export %s as instance", args_.abc_path.c_str()); + return; + } + CLOG_INFO(&LOG, 2, "exporting instance %s", args_.abc_path.c_str()); +} + +OObject ABCInstanceWriter::get_alembic_object() const +{ + /* There is no OObject for an instance. */ + BLI_assert(!"ABCInstanceWriter cannot return its Alembic OObject"); + return OObject(); +} + +bool ABCInstanceWriter::is_supported(const HierarchyContext *context) const +{ + return context->is_instance(); +} + +void ABCInstanceWriter::do_write(HierarchyContext & /*context*/) +{ + /* Instances don't have data to be written. Just creating them is enough. */ +} + +} // namespace alembic +} // namespace io +} // namespace blender diff --git a/source/blender/io/alembic/exporter/abc_writer_instance.h b/source/blender/io/alembic/exporter/abc_writer_instance.h new file mode 100644 index 00000000000..74379b9d6bd --- /dev/null +++ b/source/blender/io/alembic/exporter/abc_writer_instance.h @@ -0,0 +1,48 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#pragma once + +/** \file + * \ingroup balembic + */ + +#include "abc_writer_abstract.h" + +namespace blender { +namespace io { +namespace alembic { + +/* Writer for Alembic instances, i.e. data that references another Alembic object. + * + * Note that the Alembic object created by this writer cannot be used as a + * parent, because it already instantiates the entire hierarchy of the + * referenced object. */ +class ABCInstanceWriter : public ABCAbstractWriter { + public: + explicit ABCInstanceWriter(const ABCWriterConstructorArgs &args); + virtual ~ABCInstanceWriter(); + + virtual void create_alembic_objects(const HierarchyContext *context) override; + virtual Alembic::Abc::OObject get_alembic_object() const override; + + protected: + virtual bool is_supported(const HierarchyContext *context) const override; + virtual void do_write(HierarchyContext &context) override; +}; + +} // namespace alembic +} // namespace io +} // namespace blender -- cgit v1.2.3 From 4e104ce5b00bddea324029664a6e689182b35f12 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 8 Sep 2020 17:19:58 +0200 Subject: Cleanup: reduce variable scopes in node_draw.c --- source/blender/editors/space_node/node_draw.c | 110 ++++++++++++-------------- 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index ba6b164704f..fc4685929d3 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -175,7 +175,6 @@ void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree, bNode *node) static bool compare_nodes(const bNode *a, const bNode *b) { - bNode *parent; /* These tell if either the node or any of the parent nodes is selected. * A selected parent means an unselected node is also in foreground! */ @@ -185,7 +184,7 @@ static bool compare_nodes(const bNode *a, const bNode *b) /* if one is an ancestor of the other */ /* XXX there might be a better sorting algorithm for stable topological sort, * this is O(n^2) worst case */ - for (parent = a->parent; parent; parent = parent->parent) { + for (bNode *parent = a->parent; parent; parent = parent->parent) { /* if b is an ancestor, it is always behind a */ if (parent == b) { return true; @@ -198,7 +197,7 @@ static bool compare_nodes(const bNode *a, const bNode *b) a_select = 1; } } - for (parent = b->parent; parent; parent = parent->parent) { + for (bNode *parent = b->parent; parent; parent = parent->parent) { /* if a is an ancestor, it is always behind b */ if (parent == a) { return false; @@ -237,17 +236,16 @@ static bool compare_nodes(const bNode *a, const bNode *b) void ED_node_sort(bNodeTree *ntree) { /* merge sort is the algorithm of choice here */ - bNode *first_a, *first_b, *node_a, *node_b, *tmp; int totnodes = BLI_listbase_count(&ntree->nodes); - int k, a, b; - k = 1; + int k = 1; while (k < totnodes) { - first_a = first_b = ntree->nodes.first; + bNode *first_a = ntree->nodes.first; + bNode *first_b = first_a; do { /* setup first_b pointer */ - for (b = 0; b < k && first_b; b++) { + for (int b = 0; b < k && first_b; b++) { first_b = first_b->next; } /* all batches merged? */ @@ -256,16 +254,17 @@ void ED_node_sort(bNodeTree *ntree) } /* merge batches */ - node_a = first_a; - node_b = first_b; - a = b = 0; + bNode *node_a = first_a; + bNode *node_b = first_b; + int a = 0; + int b = 0; while (a < k && b < k && node_b) { if (compare_nodes(node_a, node_b) == 0) { node_a = node_a->next; a++; } else { - tmp = node_b; + bNode *tmp = node_b; node_b = node_b->next; b++; BLI_remlink(&ntree->nodes, tmp); @@ -301,13 +300,12 @@ static void do_node_internal_buttons(bContext *C, void *UNUSED(node_v), int even static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) { - bNode *node; - char uiblockstr[32]; /* add node uiBlocks in drawing order - prevents events going to overlapping nodes */ - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { /* ui block */ + char uiblockstr[32]; BLI_snprintf(uiblockstr, sizeof(uiblockstr), "node buttons %p", (void *)node); node->block = UI_block_begin(C, CTX_wm_region(C), uiblockstr, UI_EMBOSS); UI_block_func_handle_set(node->block, do_node_internal_buttons, node); @@ -345,17 +343,14 @@ void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry) static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) { uiLayout *layout, *row; - PointerRNA nodeptr, sockptr; - bNodeSocket *nsock; - float locx, locy; - float dy; - int buty; + PointerRNA nodeptr; RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); /* get "global" coords */ + float locx, locy; node_to_view(node, 0.0f, 0.0f, &locx, &locy); - dy = locy; + float dy = locy; /* header */ dy -= NODE_DY; @@ -368,11 +363,13 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* output sockets */ bool add_output_space = false; - for (nsock = node->outputs.first; nsock; nsock = nsock->next) { + int buty; + LISTBASE_FOREACH (bNodeSocket *, nsock, &node->outputs) { if (nodeSocketIsHidden(nsock)) { continue; } + PointerRNA sockptr; RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr); layout = UI_block_layout(node->block, @@ -495,11 +492,12 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) } /* input sockets */ - for (nsock = node->inputs.first; nsock; nsock = nsock->next) { + LISTBASE_FOREACH (bNodeSocket *, nsock, &node->inputs) { if (nodeSocketIsHidden(nsock)) { continue; } + PointerRNA sockptr; RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr); layout = UI_block_layout(node->block, @@ -564,27 +562,26 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* based on settings in node, sets drawing rect info. each redraw! */ static void node_update_hidden(bNode *node) { - bNodeSocket *nsock; - float locx, locy; - float rad, drad, hiddenrad = HIDDEN_RAD; - int totin = 0, totout = 0, tot; + int totin = 0, totout = 0; /* get "global" coords */ + float locx, locy; node_to_view(node, 0.0f, 0.0f, &locx, &locy); /* calculate minimal radius */ - for (nsock = node->inputs.first; nsock; nsock = nsock->next) { + LISTBASE_FOREACH (bNodeSocket *, nsock, &node->inputs) { if (!nodeSocketIsHidden(nsock)) { totin++; } } - for (nsock = node->outputs.first; nsock; nsock = nsock->next) { + LISTBASE_FOREACH (bNodeSocket *, nsock, &node->outputs) { if (!nodeSocketIsHidden(nsock)) { totout++; } } - tot = MAX2(totin, totout); + float hiddenrad = HIDDEN_RAD; + float tot = MAX2(totin, totout); if (tot > 4) { hiddenrad += 5.0f * (float)(tot - 4); } @@ -595,9 +592,10 @@ static void node_update_hidden(bNode *node) node->totr.ymin = node->totr.ymax - 2 * hiddenrad; /* output sockets */ - rad = drad = (float)M_PI / (1.0f + (float)totout); + float rad = (float)M_PI / (1.0f + (float)totout); + float drad = rad; - for (nsock = node->outputs.first; nsock; nsock = nsock->next) { + LISTBASE_FOREACH (bNodeSocket *, nsock, &node->outputs) { if (!nodeSocketIsHidden(nsock)) { nsock->locx = node->totr.xmax - hiddenrad + sinf(rad) * hiddenrad; nsock->locy = node->totr.ymin + hiddenrad + cosf(rad) * hiddenrad; @@ -608,7 +606,7 @@ static void node_update_hidden(bNode *node) /* input sockets */ rad = drad = -(float)M_PI / (1.0f + (float)totin); - for (nsock = node->inputs.first; nsock; nsock = nsock->next) { + LISTBASE_FOREACH (bNodeSocket *, nsock, &node->inputs) { if (!nodeSocketIsHidden(nsock)) { nsock->locx = node->totr.xmin + hiddenrad + sinf(rad) * hiddenrad; nsock->locy = node->totr.ymin + hiddenrad + cosf(rad) * hiddenrad; @@ -689,11 +687,9 @@ int node_get_colorid(bNode *node) /* note: in node_edit.c is similar code, for untangle node */ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) { - bNodeLink *link; - GPU_blend(GPU_BLEND_ALPHA); - for (link = node->internal_links.first; link; link = link->next) { + LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) { node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1); } @@ -892,10 +888,9 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) float xscale = xrect / ((float)preview->xsize); float yscale = yrect / ((float)preview->ysize); float scale; - rctf draw_rect; /* uniform scale and offset */ - draw_rect = *prv; + rctf draw_rect = *prv; if (xscale < yscale) { float offset = 0.5f * (yrect - ((float)preview->ysize) * xscale); draw_rect.ymin += offset; @@ -1127,14 +1122,9 @@ static void node_draw_basis(const bContext *C, bNode *node, bNodeInstanceKey key) { - bNodeInstanceHash *previews = CTX_data_pointer_get(C, "node_previews").data; - rctf *rct = &node->totr; - float iconofs; /* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */ float iconbutw = 0.8f * UI_UNIT_X; - int color_id = node_get_colorid(node); - float color[4]; - char showname[128]; /* 128 used below */ + View2D *v2d = ®ion->v2d; /* skip if out of view */ @@ -1147,6 +1137,8 @@ static void node_draw_basis(const bContext *C, /* shadow */ node_draw_shadow(snode, node, BASIS_RAD, 1.0f); + float color[4]; + int color_id = node_get_colorid(node); if (node->flag & NODE_MUTED) { /* Muted nodes are semi-transparent and colorless. */ UI_GetThemeColor3fv(TH_NODE, color); @@ -1160,12 +1152,13 @@ static void node_draw_basis(const bContext *C, GPU_line_width(1.0f); + rctf *rct = &node->totr; UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); UI_draw_roundbox_aa( true, rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD, color); /* show/hide icons */ - iconofs = rct->xmax - 0.35f * U.widget_unit; + float iconofs = rct->xmax - 0.35f * U.widget_unit; /* preview */ if (node->typeinfo->flag & NODE_PREVIEW) { @@ -1273,6 +1266,7 @@ static void node_draw_basis(const bContext *C, UI_draw_icon_tri(rct->xmin + 0.65f * U.widget_unit, rct->ymax - NODE_DY / 2.2f, 'v', color); } + char showname[128]; /* 128 used below */ nodeLabel(ntree, node, showname, sizeof(showname)); uiBut *but = uiDefBut(node->block, @@ -1334,6 +1328,7 @@ static void node_draw_basis(const bContext *C, node_draw_sockets(v2d, C, ntree, node, true, false); /* preview */ + bNodeInstanceHash *previews = CTX_data_pointer_get(C, "node_previews").data; if (node->flag & NODE_PREVIEW && previews) { bNodePreview *preview = BKE_node_instance_hash_lookup(previews, key); if (preview && (preview->xsize && preview->ysize)) { @@ -1356,20 +1351,20 @@ static void node_draw_hidden(const bContext *C, bNodeInstanceKey UNUSED(key)) { rctf *rct = &node->totr; - float dx, centy = BLI_rctf_cent_y(rct); + float centy = BLI_rctf_cent_y(rct); float hiddenrad = BLI_rctf_size_y(rct) / 2.0f; - int color_id = node_get_colorid(node); - float color[4]; - char showname[128]; /* 128 is used below */ + View2D *v2d = ®ion->v2d; - float scale; + float scale; UI_view2d_scale_get(v2d, &scale, NULL); /* shadow */ node_draw_shadow(snode, node, hiddenrad, 1.0f); /* body */ + float color[4]; + int color_id = node_get_colorid(node); if (node->flag & NODE_MUTED) { /* Muted nodes are semi-transparent and colorless. */ UI_GetThemeColor4fv(TH_NODE, color); @@ -1448,6 +1443,7 @@ static void node_draw_hidden(const bContext *C, node_draw_mute_line(®ion->v2d, snode, node); } + char showname[128]; /* 128 is used below */ nodeLabel(ntree, node, showname, sizeof(showname)); /* XXX - don't print into self! */ @@ -1477,7 +1473,7 @@ static void node_draw_hidden(const bContext *C, immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShade(color_id, -10); - dx = 10.0f; + float dx = 10.0f; immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, rct->xmax - dx, centy - 4.0f); @@ -1573,13 +1569,11 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) void node_update_nodetree(const bContext *C, bNodeTree *ntree) { - bNode *node; - /* make sure socket "used" tags are correct, for displaying value buttons */ ntreeTagUsedSockets(ntree); /* update nodes front to back, so children sizes get updated before parents */ - for (node = ntree->nodes.last; node; node = node->prev) { + LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree->nodes) { node_update(C, ntree, node); } } @@ -1604,10 +1598,6 @@ void node_draw_nodetree(const bContext *C, bNodeTree *ntree, bNodeInstanceKey parent_key) { - bNode *node; - bNodeLink *link; - int a; - if (ntree == NULL) { return; /* groups... */ } @@ -1619,6 +1609,8 @@ void node_draw_nodetree(const bContext *C, #endif /* draw background nodes, last nodes in front */ + int a; + bNode *node; for (a = 0, node = ntree->nodes.first; node; node = node->next, a++) { bNodeInstanceKey key; @@ -1640,7 +1632,7 @@ void node_draw_nodetree(const bContext *C, /* node lines */ GPU_blend(GPU_BLEND_ALPHA); nodelink_batch_start(snode); - for (link = ntree->links.first; link; link = link->next) { + LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { if (!nodeLinkIsHidden(link)) { node_draw_link(®ion->v2d, snode, link); } -- cgit v1.2.3 From 7ca42545d166b3d966c2a67fd94b5291903f10a2 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Tue, 8 Sep 2020 16:30:01 +0200 Subject: Hide tools with missing icons under experimental This removes from the UI all tools with missing icons and hides them under a "Tools with missing icons" experimental option. We agree on not making available by default tools in master without icons. Having this experimental flag will allow to commit new tools as soon as the technical design and implementation is finished so development can continue, without adding broken icons to the UI. Reviewed By: Severin Differential Revision: https://developer.blender.org/D8831 --- .../startup/bl_ui/space_toolsystem_toolbar.py | 56 +++++++++++++++++----- release/scripts/startup/bl_ui/space_userpref.py | 1 + source/blender/makesdna/DNA_userdef_types.h | 3 +- source/blender/makesrna/intern/rna_userdef.c | 4 ++ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index ab7ac007257..d729180843e 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1200,11 +1200,13 @@ class _defs_sculpt: @staticmethod def generate_from_brushes(context): - if bpy.context.preferences.experimental.use_sculpt_vertex_colors: - exclude_filter = {} - else: + exclude_filter = {} + if not bpy.context.preferences.experimental.use_sculpt_vertex_colors: exclude_filter = {'PAINT', 'SMEAR'} + if not bpy.context.preferences.experimental.use_tools_missing_icons: + exclude_filter = {'PAINT', 'SMEAR', 'BOUNDARY', 'DISPLACEMENT_ERASER'} + return generate_from_enum_ex( context, idname_prefix="builtin_brush.", @@ -2647,14 +2649,34 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_sculpt.mask_border, _defs_sculpt.mask_lasso, ), - ( - _defs_sculpt.face_set_box, - _defs_sculpt.face_set_lasso, - ), _defs_sculpt.hide_border, - ( - _defs_sculpt.trim_box, - _defs_sculpt.trim_lasso, + lambda context: ( + (_defs_sculpt.face_set_box,) + if context is None or ( + context.preferences.view.show_developer_ui and + context.preferences.experimental.use_tools_missing_icons) + else () + ), + lambda context: ( + (_defs_sculpt.face_set_lasso,) + if context is None or ( + context.preferences.view.show_developer_ui and + context.preferences.experimental.use_tools_missing_icons) + else () + ), + lambda context: ( + (_defs_sculpt.trim_box,) + if context is None or ( + context.preferences.view.show_developer_ui and + context.preferences.experimental.use_tools_missing_icons) + else () + ), + lambda context: ( + (_defs_sculpt.trim_lasso,) + if context is None or ( + context.preferences.view.show_developer_ui and + context.preferences.experimental.use_tools_missing_icons) + else () ), None, _defs_sculpt.mesh_filter, @@ -2663,7 +2685,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): (_defs_sculpt.color_filter,) if context is None or ( context.preferences.view.show_developer_ui and - context.preferences.experimental.use_sculpt_vertex_colors) + context.preferences.experimental.use_sculpt_vertex_colors and + context.preferences.experimental.use_tools_missing_icons) else () ), None, @@ -2671,11 +2694,18 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): (_defs_sculpt.mask_by_color,) if context is None or ( context.preferences.view.show_developer_ui and - context.preferences.experimental.use_sculpt_vertex_colors) + context.preferences.experimental.use_sculpt_vertex_colors and + context.preferences.experimental.use_tools_missing_icons) else () ), None, - _defs_sculpt.face_set_edit, + lambda context: ( + (_defs_sculpt.face_set_edit,) + if context is None or ( + context.preferences.view.show_developer_ui and + context.preferences.experimental.use_tools_missing_icons) + else () + ), None, _defs_transform.translate, _defs_transform.rotate, diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 9548de20752..506849fbee5 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -2164,6 +2164,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel): context, ( ({"property": "use_new_particle_system"}, "T73324"), ({"property": "use_sculpt_vertex_colors"}, "T71947"), + ({"property": "use_tools_missing_icons"}, "T80331"), ), ) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index ec46d2680ca..589077ea67b 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -620,8 +620,9 @@ typedef struct UserDef_Experimental { char use_new_hair_type; char use_cycles_debug; char use_sculpt_vertex_colors; + char use_tools_missing_icons; /** `makesdna` does not allow empty structs. */ - char _pad[3]; + char _pad[2]; } UserDef_Experimental; #define USER_EXPERIMENTAL_TEST(userdef, member) \ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7b777aa642a..10e3f9c86ee 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6117,6 +6117,10 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) prop = RNA_def_property(srna, "use_sculpt_vertex_colors", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_vertex_colors", 1); RNA_def_property_ui_text(prop, "Sculpt Vertex Colors", "Use the new Vertex Painting system"); + + prop = RNA_def_property(srna, "use_tools_missing_icons", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_tools_missing_icons", 1); + RNA_def_property_ui_text(prop, "Tools with Missing Icons", "Show tools with missing icons"); } static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop) -- cgit v1.2.3 From 637699e78ab6aae0856ee4d75689762eac1772ce Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 8 Sep 2020 11:52:27 -0400 Subject: UI: 3D View: Move Live Unwrap to toolbar The menus should be for operators, tool settings belong in the toolbar --- release/scripts/startup/bl_ui/space_view3d.py | 3 --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 528eba06db1..28b66119fc6 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1073,10 +1073,7 @@ class VIEW3D_MT_uv_map(Menu): def draw(self, context): layout = self.layout - tool_settings = context.tool_settings - layout.operator("uv.unwrap") - layout.prop(tool_settings, "use_edge_path_live_unwrap") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 09744e44f35..6359426128f 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -212,6 +212,9 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): row.active = tool_settings.use_transform_correct_face_attributes row.prop(tool_settings, "use_transform_correct_keep_connected") + row = layout.row(align=True, heading="UVs") + row.prop(tool_settings, "use_edge_path_live_unwrap") + row = layout.row(heading="Mirror") sub = row.row(align=True) sub.prop(mesh, "use_mirror_x", text="X", toggle=True) -- cgit v1.2.3 From e9e208d995fb25002d3916ccfb692e5e4f812097 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 8 Sep 2020 11:54:23 -0400 Subject: UI: Tooltip grammar fix --- source/blender/makesrna/intern/rna_scene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ab4ffda8888..ebec5e3bff8 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3489,7 +3489,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "use_edge_path_live_unwrap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "edge_mode_live_unwrap", 1); - RNA_def_property_ui_text(prop, "Live Unwrap", "Changing edges seam recalculates UV unwrap"); + RNA_def_property_ui_text(prop, "Live Unwrap", "Changing edge seams recalculates UV unwrap"); prop = RNA_def_property(srna, "normal_vector", PROP_FLOAT, PROP_XYZ); RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply"); -- cgit v1.2.3 From f14d24729ff32edffd71b646712e59b640fcddd9 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 8 Sep 2020 11:57:19 -0400 Subject: RNA Manual Mapping: Update Mappings --- release/scripts/modules/rna_manual_reference.py | 72 +++++++++++++++++++++---- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index f8562241ef9..a8c8b212ecf 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -40,8 +40,10 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"), ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), + ("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), + ("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"), ("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"), ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), @@ -59,8 +61,8 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), - ("bpy.types.rendersettings_simplify_gpencil_remove_lines*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-remove-lines"), - ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-pivot-point-align"), + ("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"), + ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"), ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), ("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"), ("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"), @@ -87,6 +89,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"), ("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-overlap-strokes"), ("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"), + ("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"), ("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"), ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), @@ -100,6 +103,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), + ("bpy.types.view3doverlay.vertex_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-vertex-paint-mode-opacity"), ("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"), ("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"), ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), @@ -119,11 +123,13 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"), ("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/parameter_editor/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"), ("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"), + ("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"), ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), ("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"), ("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"), - ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-data-origin"), + ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"), ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/hide_mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), + ("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-indirect-only-clear"), ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), ("bpy.types.fluiddomainsettings.axis_slice_method*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-axis-slice-method"), ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), @@ -141,7 +147,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), ("bpy.types.linestylegeometrymodifier_beziercurve*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/bezier_curve.html#bpy-types-linestylegeometrymodifier-beziercurve"), ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), - ("bpy.types.rendersettings_simplify_gpencil_blend*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-blend"), + ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), @@ -149,6 +155,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"), ("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"), ("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"), + ("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/layers.html#bpy-ops-outliner-collection-indirect-only-set"), ("bpy.ops.sequencer.deinterlace_selected_movies*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-deinterlace-selected-movies"), ("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"), ("bpy.types.brush.use_multiplane_scrape_dynamic*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-use-multiplane-scrape-dynamic"), @@ -227,9 +234,12 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"), ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-stroke"), ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), + ("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"), ("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"), ("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"), ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), + ("bpy.ops.outliner.collection_exclude_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-exclude-clear"), + ("bpy.ops.outliner.collection_holdout_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-holdout-clear"), ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-change-visibility"), ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-randomize-colors"), ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), @@ -261,6 +271,8 @@ url_manual_mapping = ( ("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"), ("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"), ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), + ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), + ("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"), ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-uv-random"), ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), @@ -286,9 +298,13 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"), ("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"), ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), + ("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"), ("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"), ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), + ("bpy.ops.outliner.collection_exclude_set*", "render/layers/layers.html#bpy-ops-outliner-collection-exclude-set"), + ("bpy.ops.outliner.collection_holdout_set*", "render/layers/layers.html#bpy-ops-outliner-collection-holdout-set"), + ("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"), ("bpy.types.animdata.action_extrapolation*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-extrapolation"), ("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"), ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), @@ -304,7 +320,10 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), + ("bpy.types.layercollection.hide_viewport*", "editors/outliner.html#bpy-types-layercollection-hide-viewport"), + ("bpy.types.layercollection.indirect_only*", "editors/outliner.html#bpy-types-layercollection-indirect-only"), ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), + ("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"), ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), @@ -329,6 +348,8 @@ url_manual_mapping = ( ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/view_tab.html#bpy-types-spaceimageeditor-show-repeat"), + ("bpy.types.spacepreferences.filter_text*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-text"), + ("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"), ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), @@ -352,6 +373,9 @@ url_manual_mapping = ( ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), ("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"), ("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"), + ("bpy.types.rigidbodyconstraint.enabled*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-enabled"), + ("bpy.types.rigidbodyconstraint.object1*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object1"), + ("bpy.types.rigidbodyconstraint.object2*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object2"), ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), ("bpy.types.sequenceeditor.show_overlay*", "video_editing/preview/properties.html#bpy-types-sequenceeditor-show-overlay"), @@ -401,6 +425,7 @@ url_manual_mapping = ( ("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"), ("bpy.ops.sequencer.view_ghost_border*", "video_editing/preview/properties.html#bpy-ops-sequencer-view-ghost-border"), ("bpy.types.animdata.action_influence*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-influence"), + ("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"), ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), @@ -420,6 +445,7 @@ url_manual_mapping = ( ("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"), ("bpy.types.regionview3d.use_box_clip*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-use-box-clip"), ("bpy.types.rendersettings.use_border*", "render/output/settings.html#bpy-types-rendersettings-use-border"), + ("bpy.types.rigidbodyconstraint.limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-limit"), ("bpy.types.scene.audio_doppler_speed*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-speed"), ("bpy.types.sceneeevee.bokeh_max_size*", "render/eevee/render_settings/depth_of_field.html#bpy-types-sceneeevee-bokeh-max-size"), ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.html#bpy-types-shadernodebsdfanisotropic"), @@ -447,6 +473,7 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_remove*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove"), ("bpy.ops.object.vertex_group_smooth*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-smooth"), ("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"), + ("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"), ("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"), ("bpy.ops.sequencer.crossfade_sounds*", "video_editing/sequencer/strips/transitions/cross.html#bpy-ops-sequencer-crossfade-sounds"), ("bpy.ops.sequencer.export_subtitles*", "video_editing/preview/introduction.html#bpy-ops-sequencer-export-subtitles"), @@ -493,11 +520,13 @@ url_manual_mapping = ( ("bpy.ops.mesh.shortest_path_select*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-shortest-path-select"), ("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"), ("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"), + ("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"), ("bpy.ops.render.play-rendered-anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"), ("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-set-pivot-position"), ("bpy.ops.sequencer.reassign_inputs*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reassign-inputs"), ("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"), ("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"), + ("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"), ("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"), ("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"), ("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"), @@ -519,6 +548,7 @@ url_manual_mapping = ( ("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"), ("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"), ("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"), + ("bpy.types.layercollection.holdout*", "editors/outliner.html#bpy-types-layercollection-holdout"), ("bpy.types.limitdistanceconstraint*", "animation/constraints/transform/limit_distance.html#bpy-types-limitdistanceconstraint"), ("bpy.types.limitlocationconstraint*", "animation/constraints/transform/limit_location.html#bpy-types-limitlocationconstraint"), ("bpy.types.limitrotationconstraint*", "animation/constraints/transform/limit_rotation.html#bpy-types-limitrotationconstraint"), @@ -534,6 +564,7 @@ url_manual_mapping = ( ("bpy.types.toolsettings.annotation*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), ("bpy.types.viewlayer.use_freestyle*", "render/freestyle/view_layer.html#bpy-types-viewlayer-use-freestyle"), + ("bpy.ops.armature.armature_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-armature-layers"), ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), @@ -553,6 +584,7 @@ url_manual_mapping = ( ("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"), ("bpy.ops.sequencer.duplicate_move*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-duplicate-move"), ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), + ("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"), ("bpy.types.brightcontrastmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-brightcontrastmodifier"), ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), ("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"), @@ -560,6 +592,7 @@ url_manual_mapping = ( ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), ("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"), + ("bpy.types.collection.hide_select*", "editors/outliner.html#bpy-types-collection-hide-select"), ("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"), ("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"), ("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"), @@ -614,12 +647,15 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"), ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), + ("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"), + ("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"), ("bpy.ops.scene.view_layer_remove*", "render/layers/layers.html#bpy-ops-scene-view-layer-remove"), ("bpy.ops.screen.screen_full_area*", "interface/window_system/areas.html#bpy-ops-screen-screen-full-area"), ("bpy.ops.sculpt.face_sets_create*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-create"), ("bpy.ops.transform.rotate_normal*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-transform-rotate-normal"), ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), ("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"), + ("bpy.ops.uv.shortest_path_select*", "editors/uv/selecting.html#bpy-ops-uv-shortest-path-select"), ("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"), ("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"), ("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"), @@ -748,6 +784,8 @@ url_manual_mapping = ( ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask-flood-fill"), ("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"), ("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"), + ("bpy.ops.preferences.copy_prev*", "editors/preferences/introduction.html#bpy-ops-preferences-copy-prev"), + ("bpy.ops.preferences.keyconfig*", "editors/preferences/keymap.html#bpy-ops-preferences-keyconfig"), ("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"), ("bpy.ops.sculpt.face_sets_init*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-init"), ("bpy.ops.sequencer.change_path*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-change-path"), @@ -810,6 +848,7 @@ url_manual_mapping = ( ("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"), ("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"), ("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"), + ("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"), ("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"), ("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), @@ -831,6 +870,7 @@ url_manual_mapping = ( ("bpy.ops.object.select_mirror*", "scene_layout/object/selecting.html#bpy-ops-object-select-mirror"), ("bpy.ops.object.select_random*", "scene_layout/object/selecting.html#bpy-ops-object-select-random"), ("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"), + ("bpy.ops.preferences.autoexec*", "editors/preferences/save_load.html#bpy-ops-preferences-autoexec"), ("bpy.ops.scene.view_layer_add*", "render/layers/layers.html#bpy-ops-scene-view-layer-add"), ("bpy.ops.sculpt.face_set_edit*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-edit"), ("bpy.ops.sequencer.gap_insert*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-gap-insert"), @@ -868,6 +908,7 @@ url_manual_mapping = ( ("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"), ("bpy.types.normaleditmodifier*", "modeling/modifiers/modify/normal_edit.html#bpy-types-normaleditmodifier"), ("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"), + ("bpy.types.object.hide_render*", "editors/outliner.html#bpy-types-object-hide-render"), ("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"), ("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"), ("bpy.types.shadernodebsdfhair*", "render/shader_nodes/shader/hair.html#bpy-types-shadernodebsdfhair"), @@ -914,17 +955,21 @@ url_manual_mapping = ( ("bpy.ops.mesh.remove_doubles*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-remove-doubles"), ("bpy.ops.mesh.select_similar*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar"), ("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"), + ("bpy.ops.nla.action_pushdown*", "editors/nla/tracks.html#bpy-ops-nla-action-pushdown"), ("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"), ("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"), ("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"), ("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"), ("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"), + ("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"), + ("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"), + ("bpy.ops.preferences.keyitem*", "editors/preferences/keymap.html#bpy-ops-preferences-keyitem"), ("bpy.ops.sequencer.swap_data*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-swap-data"), ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/mesh/transform/push_pull.html#bpy-ops-transform-push-pull"), ("bpy.ops.transform.seq_slide*", "video_editing/sequencer/editing.html#bpy-ops-transform-seq-slide"), - ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-trackball"), + ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-trackball"), ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/align_transform_orientation.html#bpy-ops-transform-transform"), - ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-translate"), + ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/move.html#bpy-ops-transform-translate"), ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"), ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"), ("bpy.types.alphaoversequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"), @@ -1002,6 +1047,7 @@ url_manual_mapping = ( ("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"), ("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"), ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), + ("bpy.ops.poselib.apply_pose*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-apply-pose"), ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-expand"), ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-filter"), @@ -1009,6 +1055,7 @@ url_manual_mapping = ( ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), + ("bpy.opsuv.select_edge_ring*", "editors/uv/selecting.html#bpy-opsuv-select-edge-ring"), ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), ("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"), @@ -1044,7 +1091,7 @@ url_manual_mapping = ( ("bpy.types.shadernodetexies*", "render/shader_nodes/textures/ies.html#bpy-types-shadernodetexies"), ("bpy.types.shadernodetexsky*", "render/shader_nodes/textures/sky.html#bpy-types-shadernodetexsky"), ("bpy.types.softbodymodifier*", "physics/soft_body/index.html#bpy-types-softbodymodifier"), - ("bpy.types.softbodysettings*", "physics/soft_body/settings.html#bpy-types-softbodysettings"), + ("bpy.types.softbodysettings*", "physics/soft_body/settings/index.html#bpy-types-softbodysettings"), ("bpy.types.solidifymodifier*", "modeling/modifiers/generate/solidify.html#bpy-types-solidifymodifier"), ("bpy.types.spacegrapheditor*", "editors/graph_editor/index.html#bpy-types-spacegrapheditor"), ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), @@ -1078,6 +1125,7 @@ url_manual_mapping = ( ("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"), ("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"), ("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"), + ("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"), ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), ("bpy.ops.screen.area_dupli*", "interface/window_system/areas.html#bpy-ops-screen-area-dupli"), @@ -1086,6 +1134,7 @@ url_manual_mapping = ( ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), ("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"), + ("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"), ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), @@ -1135,14 +1184,15 @@ url_manual_mapping = ( ("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"), ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), ("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"), + ("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"), ("bpy.ops.scene.view_layer*", "render/layers/layers.html#bpy-ops-scene-view-layer"), ("bpy.ops.sequencer.delete*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-delete"), ("bpy.ops.sequencer.reload*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reload"), ("bpy.ops.sequencer.unlock*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-unlock"), ("bpy.ops.sequencer.unmute*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-unmute"), ("bpy.ops.transform.mirror*", "scene_layout/object/editing/mirror.html#bpy-ops-transform-mirror"), - ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-resize"), - ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-rotate"), + ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/scale.html#bpy-ops-transform-resize"), + ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-rotate"), ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv.html#bpy-ops-uv-lightmap-pack"), ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-smart-project"), ("bpy.ops.uv.snap_selected*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-selected"), @@ -1326,6 +1376,7 @@ url_manual_mapping = ( ("bpy.ops.nla.move_down*", "editors/nla/editing.html#bpy-ops-nla-move-down"), ("bpy.ops.object.*clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-clear"), ("bpy.ops.object.delete*", "scene_layout/object/editing/delete.html#bpy-ops-object-delete"), + ("bpy.ops.render.opengl*", "editors/3dview/viewport_render.html#bpy-ops-render-opengl"), ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), @@ -1389,6 +1440,7 @@ url_manual_mapping = ( ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), + ("bpy.ops.preferences*", "editors/preferences/index.html#bpy-ops-preferences"), ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), @@ -1494,7 +1546,7 @@ url_manual_mapping = ( ("bpy.ops.ed.undo*", "interface/undo_redo.html#bpy-ops-ed-undo"), ("bpy.ops.gpencil*", "grease_pencil/index.html#bpy-ops-gpencil"), ("bpy.ops.lattice*", "animation/lattice.html#bpy-ops-lattice"), - ("bpy.ops.poselib*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib"), + ("bpy.ops.poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib"), ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), -- cgit v1.2.3 From 637a5c964a01f5e8733e972cb8a30341eb91058e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 18:29:00 +0200 Subject: BKE: Fix compiling with clang-tidy and readability-non-const-parameter --- source/blender/blenkernel/BKE_volume_render.h | 2 +- source/blender/blenkernel/intern/volume_render.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h index a42f24a5312..ac69b615c3f 100644 --- a/source/blender/blenkernel/BKE_volume_render.h +++ b/source/blender/blenkernel/BKE_volume_render.h @@ -46,7 +46,7 @@ void BKE_volume_grid_dense_voxels(const struct Volume *volume, struct VolumeGrid *volume_grid, const int64_t min[3], const int64_t max[3], - float *voxels); + const float *voxels); /* Wireframe */ diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc index 98d3617c822..ab9242ad24a 100644 --- a/source/blender/blenkernel/intern/volume_render.cc +++ b/source/blender/blenkernel/intern/volume_render.cc @@ -94,7 +94,7 @@ void BKE_volume_grid_dense_voxels(const Volume *volume, VolumeGrid *volume_grid, const int64_t min[3], const int64_t max[3], - float *voxels) + const float *voxels) { #ifdef WITH_OPENVDB openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid); -- cgit v1.2.3 From f27d5e4f76f7d660235eef6b2c15bd66f33628c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 19:54:30 +0200 Subject: Fix T79538 Grease Pencil: Fill texture doesn't tile anymore This was caused by rBe749643793809248dfc6ffd078be04aec3eeab82 which removed the texture repeat from Image texture. --- source/blender/blenkernel/intern/image_gpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c index 8b6bd47a0db..d4a1c1e2c46 100644 --- a/source/blender/blenkernel/intern/image_gpu.c +++ b/source/blender/blenkernel/intern/image_gpu.c @@ -320,6 +320,8 @@ static GPUTexture *image_get_gpu_texture(Image *ima, *tex = IMB_create_gpu_texture( ima->id.name + 2, ibuf_intern, use_high_bitdepth, store_premultiplied); + GPU_texture_wrap_mode(*tex, true, false); + if (GPU_mipmap_enabled()) { GPU_texture_generate_mipmap(*tex); if (ima) { -- cgit v1.2.3 From dd04cba943931c77b5bb4956ff6d02ca32e6cac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 19:55:53 +0200 Subject: GLSamplers: Add debug object label This makes it easier to see what each sampler is supposed to be. --- source/blender/gpu/opengl/gl_texture.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index ae3923b960f..e649f73d1c4 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -513,6 +513,25 @@ void GLTexture::samplers_init(void) * - GL_TEXTURE_MAX_LOD is 1000. * - GL_TEXTURE_LOD_BIAS is 0.0f. **/ + +#ifndef __APPLE__ + if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + char sampler_name[128]; + SNPRINTF(sampler_name, + "Sampler%s%s%s%s%s%s%s%s%s%s", + (state == GPU_SAMPLER_DEFAULT) ? "_default" : "", + (state & GPU_SAMPLER_FILTER) ? "_filter" : "", + (state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "", + (state & GPU_SAMPLER_REPEAT) ? "_repeat-" : "", + (state & GPU_SAMPLER_REPEAT_S) ? "S" : "", + (state & GPU_SAMPLER_REPEAT_T) ? "T" : "", + (state & GPU_SAMPLER_REPEAT_R) ? "R" : "", + (state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "", + (state & GPU_SAMPLER_COMPARE) ? "_compare" : "", + (state & GPU_SAMPLER_ANISO) ? "_aniso" : ""); + glObjectLabel(GL_SAMPLER, samplers_[i], -1, sampler_name); + } +#endif } samplers_update(); @@ -521,6 +540,12 @@ void GLTexture::samplers_init(void) glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f); + +#ifndef __APPLE__ + if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + glObjectLabel(GL_SAMPLER, icon_sampler, -1, "Sampler-icons"); + } +#endif } void GLTexture::samplers_update(void) -- cgit v1.2.3 From de5930333bcd85ede44d6cd1e117b00e5051b728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 19:56:09 +0200 Subject: Revert "RNA Manual Mapping: Update Mappings" This reverts commit f14d24729ff32edffd71b646712e59b640fcddd9. I commited the previous commit because I wasn't building with openvdb. Compiling with openvdb fix the clang-tidy errror. --- release/scripts/modules/rna_manual_reference.py | 72 ++++--------------------- 1 file changed, 10 insertions(+), 62 deletions(-) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index a8c8b212ecf..f8562241ef9 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -40,10 +40,8 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"), ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), - ("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), - ("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"), ("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"), ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), @@ -61,8 +59,8 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), - ("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"), - ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"), + ("bpy.types.rendersettings_simplify_gpencil_remove_lines*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-remove-lines"), + ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-pivot-point-align"), ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), ("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"), ("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"), @@ -89,7 +87,6 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"), ("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-overlap-strokes"), ("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"), - ("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"), ("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"), ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), @@ -103,7 +100,6 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), - ("bpy.types.view3doverlay.vertex_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-vertex-paint-mode-opacity"), ("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"), ("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"), ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), @@ -123,13 +119,11 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"), ("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/parameter_editor/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"), ("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"), - ("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"), ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), ("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"), ("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"), - ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"), + ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-data-origin"), ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/hide_mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), - ("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-indirect-only-clear"), ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), ("bpy.types.fluiddomainsettings.axis_slice_method*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-axis-slice-method"), ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), @@ -147,7 +141,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), ("bpy.types.linestylegeometrymodifier_beziercurve*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/bezier_curve.html#bpy-types-linestylegeometrymodifier-beziercurve"), ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), - ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), + ("bpy.types.rendersettings_simplify_gpencil_blend*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-blend"), ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), @@ -155,7 +149,6 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"), ("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"), ("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"), - ("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/layers.html#bpy-ops-outliner-collection-indirect-only-set"), ("bpy.ops.sequencer.deinterlace_selected_movies*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-deinterlace-selected-movies"), ("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"), ("bpy.types.brush.use_multiplane_scrape_dynamic*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-use-multiplane-scrape-dynamic"), @@ -234,12 +227,9 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"), ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-stroke"), ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), - ("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"), ("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"), ("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"), ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), - ("bpy.ops.outliner.collection_exclude_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-exclude-clear"), - ("bpy.ops.outliner.collection_holdout_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-holdout-clear"), ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-change-visibility"), ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-randomize-colors"), ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), @@ -271,8 +261,6 @@ url_manual_mapping = ( ("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"), ("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"), ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), - ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), - ("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"), ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-uv-random"), ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), @@ -298,13 +286,9 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"), ("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"), ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), - ("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"), ("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"), ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), - ("bpy.ops.outliner.collection_exclude_set*", "render/layers/layers.html#bpy-ops-outliner-collection-exclude-set"), - ("bpy.ops.outliner.collection_holdout_set*", "render/layers/layers.html#bpy-ops-outliner-collection-holdout-set"), - ("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"), ("bpy.types.animdata.action_extrapolation*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-extrapolation"), ("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"), ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), @@ -320,10 +304,7 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), - ("bpy.types.layercollection.hide_viewport*", "editors/outliner.html#bpy-types-layercollection-hide-viewport"), - ("bpy.types.layercollection.indirect_only*", "editors/outliner.html#bpy-types-layercollection-indirect-only"), ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), - ("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"), ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), @@ -348,8 +329,6 @@ url_manual_mapping = ( ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/view_tab.html#bpy-types-spaceimageeditor-show-repeat"), - ("bpy.types.spacepreferences.filter_text*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-text"), - ("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"), ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), @@ -373,9 +352,6 @@ url_manual_mapping = ( ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), ("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"), ("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"), - ("bpy.types.rigidbodyconstraint.enabled*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-enabled"), - ("bpy.types.rigidbodyconstraint.object1*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object1"), - ("bpy.types.rigidbodyconstraint.object2*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object2"), ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), ("bpy.types.sequenceeditor.show_overlay*", "video_editing/preview/properties.html#bpy-types-sequenceeditor-show-overlay"), @@ -425,7 +401,6 @@ url_manual_mapping = ( ("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"), ("bpy.ops.sequencer.view_ghost_border*", "video_editing/preview/properties.html#bpy-ops-sequencer-view-ghost-border"), ("bpy.types.animdata.action_influence*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-influence"), - ("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"), ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), @@ -445,7 +420,6 @@ url_manual_mapping = ( ("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"), ("bpy.types.regionview3d.use_box_clip*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-use-box-clip"), ("bpy.types.rendersettings.use_border*", "render/output/settings.html#bpy-types-rendersettings-use-border"), - ("bpy.types.rigidbodyconstraint.limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-limit"), ("bpy.types.scene.audio_doppler_speed*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-speed"), ("bpy.types.sceneeevee.bokeh_max_size*", "render/eevee/render_settings/depth_of_field.html#bpy-types-sceneeevee-bokeh-max-size"), ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.html#bpy-types-shadernodebsdfanisotropic"), @@ -473,7 +447,6 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_remove*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove"), ("bpy.ops.object.vertex_group_smooth*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-smooth"), ("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"), - ("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"), ("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"), ("bpy.ops.sequencer.crossfade_sounds*", "video_editing/sequencer/strips/transitions/cross.html#bpy-ops-sequencer-crossfade-sounds"), ("bpy.ops.sequencer.export_subtitles*", "video_editing/preview/introduction.html#bpy-ops-sequencer-export-subtitles"), @@ -520,13 +493,11 @@ url_manual_mapping = ( ("bpy.ops.mesh.shortest_path_select*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-shortest-path-select"), ("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"), ("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"), - ("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"), ("bpy.ops.render.play-rendered-anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"), ("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-set-pivot-position"), ("bpy.ops.sequencer.reassign_inputs*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reassign-inputs"), ("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"), ("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"), - ("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"), ("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"), ("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"), ("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"), @@ -548,7 +519,6 @@ url_manual_mapping = ( ("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"), ("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"), ("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"), - ("bpy.types.layercollection.holdout*", "editors/outliner.html#bpy-types-layercollection-holdout"), ("bpy.types.limitdistanceconstraint*", "animation/constraints/transform/limit_distance.html#bpy-types-limitdistanceconstraint"), ("bpy.types.limitlocationconstraint*", "animation/constraints/transform/limit_location.html#bpy-types-limitlocationconstraint"), ("bpy.types.limitrotationconstraint*", "animation/constraints/transform/limit_rotation.html#bpy-types-limitrotationconstraint"), @@ -564,7 +534,6 @@ url_manual_mapping = ( ("bpy.types.toolsettings.annotation*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), ("bpy.types.viewlayer.use_freestyle*", "render/freestyle/view_layer.html#bpy-types-viewlayer-use-freestyle"), - ("bpy.ops.armature.armature_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-armature-layers"), ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), @@ -584,7 +553,6 @@ url_manual_mapping = ( ("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"), ("bpy.ops.sequencer.duplicate_move*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-duplicate-move"), ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), - ("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"), ("bpy.types.brightcontrastmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-brightcontrastmodifier"), ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), ("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"), @@ -592,7 +560,6 @@ url_manual_mapping = ( ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), ("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"), - ("bpy.types.collection.hide_select*", "editors/outliner.html#bpy-types-collection-hide-select"), ("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"), ("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"), ("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"), @@ -647,15 +614,12 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"), ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), - ("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"), - ("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"), ("bpy.ops.scene.view_layer_remove*", "render/layers/layers.html#bpy-ops-scene-view-layer-remove"), ("bpy.ops.screen.screen_full_area*", "interface/window_system/areas.html#bpy-ops-screen-screen-full-area"), ("bpy.ops.sculpt.face_sets_create*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-create"), ("bpy.ops.transform.rotate_normal*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-transform-rotate-normal"), ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), ("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"), - ("bpy.ops.uv.shortest_path_select*", "editors/uv/selecting.html#bpy-ops-uv-shortest-path-select"), ("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"), ("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"), ("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"), @@ -784,8 +748,6 @@ url_manual_mapping = ( ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask-flood-fill"), ("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"), ("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"), - ("bpy.ops.preferences.copy_prev*", "editors/preferences/introduction.html#bpy-ops-preferences-copy-prev"), - ("bpy.ops.preferences.keyconfig*", "editors/preferences/keymap.html#bpy-ops-preferences-keyconfig"), ("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"), ("bpy.ops.sculpt.face_sets_init*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-init"), ("bpy.ops.sequencer.change_path*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-change-path"), @@ -848,7 +810,6 @@ url_manual_mapping = ( ("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"), ("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"), ("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"), - ("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"), ("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"), ("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), @@ -870,7 +831,6 @@ url_manual_mapping = ( ("bpy.ops.object.select_mirror*", "scene_layout/object/selecting.html#bpy-ops-object-select-mirror"), ("bpy.ops.object.select_random*", "scene_layout/object/selecting.html#bpy-ops-object-select-random"), ("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"), - ("bpy.ops.preferences.autoexec*", "editors/preferences/save_load.html#bpy-ops-preferences-autoexec"), ("bpy.ops.scene.view_layer_add*", "render/layers/layers.html#bpy-ops-scene-view-layer-add"), ("bpy.ops.sculpt.face_set_edit*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-edit"), ("bpy.ops.sequencer.gap_insert*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-gap-insert"), @@ -908,7 +868,6 @@ url_manual_mapping = ( ("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"), ("bpy.types.normaleditmodifier*", "modeling/modifiers/modify/normal_edit.html#bpy-types-normaleditmodifier"), ("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"), - ("bpy.types.object.hide_render*", "editors/outliner.html#bpy-types-object-hide-render"), ("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"), ("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"), ("bpy.types.shadernodebsdfhair*", "render/shader_nodes/shader/hair.html#bpy-types-shadernodebsdfhair"), @@ -955,21 +914,17 @@ url_manual_mapping = ( ("bpy.ops.mesh.remove_doubles*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-remove-doubles"), ("bpy.ops.mesh.select_similar*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar"), ("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"), - ("bpy.ops.nla.action_pushdown*", "editors/nla/tracks.html#bpy-ops-nla-action-pushdown"), ("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"), ("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"), ("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"), ("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"), ("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"), - ("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"), - ("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"), - ("bpy.ops.preferences.keyitem*", "editors/preferences/keymap.html#bpy-ops-preferences-keyitem"), ("bpy.ops.sequencer.swap_data*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-swap-data"), ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/mesh/transform/push_pull.html#bpy-ops-transform-push-pull"), ("bpy.ops.transform.seq_slide*", "video_editing/sequencer/editing.html#bpy-ops-transform-seq-slide"), - ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-trackball"), + ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-trackball"), ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/align_transform_orientation.html#bpy-ops-transform-transform"), - ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/move.html#bpy-ops-transform-translate"), + ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-translate"), ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"), ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"), ("bpy.types.alphaoversequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"), @@ -1047,7 +1002,6 @@ url_manual_mapping = ( ("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"), ("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"), ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), - ("bpy.ops.poselib.apply_pose*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-apply-pose"), ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-expand"), ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-filter"), @@ -1055,7 +1009,6 @@ url_manual_mapping = ( ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), - ("bpy.opsuv.select_edge_ring*", "editors/uv/selecting.html#bpy-opsuv-select-edge-ring"), ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), ("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"), @@ -1091,7 +1044,7 @@ url_manual_mapping = ( ("bpy.types.shadernodetexies*", "render/shader_nodes/textures/ies.html#bpy-types-shadernodetexies"), ("bpy.types.shadernodetexsky*", "render/shader_nodes/textures/sky.html#bpy-types-shadernodetexsky"), ("bpy.types.softbodymodifier*", "physics/soft_body/index.html#bpy-types-softbodymodifier"), - ("bpy.types.softbodysettings*", "physics/soft_body/settings/index.html#bpy-types-softbodysettings"), + ("bpy.types.softbodysettings*", "physics/soft_body/settings.html#bpy-types-softbodysettings"), ("bpy.types.solidifymodifier*", "modeling/modifiers/generate/solidify.html#bpy-types-solidifymodifier"), ("bpy.types.spacegrapheditor*", "editors/graph_editor/index.html#bpy-types-spacegrapheditor"), ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), @@ -1125,7 +1078,6 @@ url_manual_mapping = ( ("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"), ("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"), ("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"), - ("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"), ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), ("bpy.ops.screen.area_dupli*", "interface/window_system/areas.html#bpy-ops-screen-area-dupli"), @@ -1134,7 +1086,6 @@ url_manual_mapping = ( ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), ("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"), - ("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"), ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), @@ -1184,15 +1135,14 @@ url_manual_mapping = ( ("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"), ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), ("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"), - ("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"), ("bpy.ops.scene.view_layer*", "render/layers/layers.html#bpy-ops-scene-view-layer"), ("bpy.ops.sequencer.delete*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-delete"), ("bpy.ops.sequencer.reload*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reload"), ("bpy.ops.sequencer.unlock*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-unlock"), ("bpy.ops.sequencer.unmute*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-unmute"), ("bpy.ops.transform.mirror*", "scene_layout/object/editing/mirror.html#bpy-ops-transform-mirror"), - ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/scale.html#bpy-ops-transform-resize"), - ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-rotate"), + ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-resize"), + ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-rotate"), ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv.html#bpy-ops-uv-lightmap-pack"), ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-smart-project"), ("bpy.ops.uv.snap_selected*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-selected"), @@ -1376,7 +1326,6 @@ url_manual_mapping = ( ("bpy.ops.nla.move_down*", "editors/nla/editing.html#bpy-ops-nla-move-down"), ("bpy.ops.object.*clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-clear"), ("bpy.ops.object.delete*", "scene_layout/object/editing/delete.html#bpy-ops-object-delete"), - ("bpy.ops.render.opengl*", "editors/3dview/viewport_render.html#bpy-ops-render-opengl"), ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), @@ -1440,7 +1389,6 @@ url_manual_mapping = ( ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), - ("bpy.ops.preferences*", "editors/preferences/index.html#bpy-ops-preferences"), ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), @@ -1546,7 +1494,7 @@ url_manual_mapping = ( ("bpy.ops.ed.undo*", "interface/undo_redo.html#bpy-ops-ed-undo"), ("bpy.ops.gpencil*", "grease_pencil/index.html#bpy-ops-gpencil"), ("bpy.ops.lattice*", "animation/lattice.html#bpy-ops-lattice"), - ("bpy.ops.poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib"), + ("bpy.ops.poselib*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib"), ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), -- cgit v1.2.3 From 9eba40b848bec0ba3f537ad9cadaa94aef6d955c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 20:15:59 +0200 Subject: Revert "Revert "RNA Manual Mapping: Update Mappings"" This reverts commit de5930333bcd85ede44d6cd1e117b00e5051b728. --- release/scripts/modules/rna_manual_reference.py | 72 +++++++++++++++++++++---- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index f8562241ef9..a8c8b212ecf 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -40,8 +40,10 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"), ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), + ("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), + ("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"), ("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"), ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), @@ -59,8 +61,8 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), - ("bpy.types.rendersettings_simplify_gpencil_remove_lines*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-remove-lines"), - ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-pivot-point-align"), + ("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"), + ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"), ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), ("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"), ("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"), @@ -87,6 +89,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"), ("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-overlap-strokes"), ("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"), + ("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"), ("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"), ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), @@ -100,6 +103,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), + ("bpy.types.view3doverlay.vertex_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-vertex-paint-mode-opacity"), ("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"), ("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"), ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), @@ -119,11 +123,13 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"), ("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/parameter_editor/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"), ("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"), + ("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"), ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), ("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"), ("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"), - ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/editing/transform/control/options.html#bpy-types-toolsettings-use-transform-data-origin"), + ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"), ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/hide_mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), + ("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-indirect-only-clear"), ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), ("bpy.types.fluiddomainsettings.axis_slice_method*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-axis-slice-method"), ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), @@ -141,7 +147,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), ("bpy.types.linestylegeometrymodifier_beziercurve*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/bezier_curve.html#bpy-types-linestylegeometrymodifier-beziercurve"), ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), - ("bpy.types.rendersettings_simplify_gpencil_blend*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-blend"), + ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), @@ -149,6 +155,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"), ("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"), ("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"), + ("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/layers.html#bpy-ops-outliner-collection-indirect-only-set"), ("bpy.ops.sequencer.deinterlace_selected_movies*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-deinterlace-selected-movies"), ("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"), ("bpy.types.brush.use_multiplane_scrape_dynamic*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-use-multiplane-scrape-dynamic"), @@ -227,9 +234,12 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"), ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-stroke"), ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), + ("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"), ("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"), ("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"), ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), + ("bpy.ops.outliner.collection_exclude_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-exclude-clear"), + ("bpy.ops.outliner.collection_holdout_clear*", "render/layers/layers.html#bpy-ops-outliner-collection-holdout-clear"), ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-change-visibility"), ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-randomize-colors"), ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), @@ -261,6 +271,8 @@ url_manual_mapping = ( ("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"), ("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"), ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), + ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), + ("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"), ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-uv-random"), ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), @@ -286,9 +298,13 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"), ("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"), ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), + ("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"), ("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"), ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), + ("bpy.ops.outliner.collection_exclude_set*", "render/layers/layers.html#bpy-ops-outliner-collection-exclude-set"), + ("bpy.ops.outliner.collection_holdout_set*", "render/layers/layers.html#bpy-ops-outliner-collection-holdout-set"), + ("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"), ("bpy.types.animdata.action_extrapolation*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-extrapolation"), ("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"), ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), @@ -304,7 +320,10 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), + ("bpy.types.layercollection.hide_viewport*", "editors/outliner.html#bpy-types-layercollection-hide-viewport"), + ("bpy.types.layercollection.indirect_only*", "editors/outliner.html#bpy-types-layercollection-indirect-only"), ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), + ("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"), ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), @@ -329,6 +348,8 @@ url_manual_mapping = ( ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/view_tab.html#bpy-types-spaceimageeditor-show-repeat"), + ("bpy.types.spacepreferences.filter_text*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-text"), + ("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"), ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), @@ -352,6 +373,9 @@ url_manual_mapping = ( ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), ("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"), ("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"), + ("bpy.types.rigidbodyconstraint.enabled*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-enabled"), + ("bpy.types.rigidbodyconstraint.object1*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object1"), + ("bpy.types.rigidbodyconstraint.object2*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object2"), ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), ("bpy.types.sequenceeditor.show_overlay*", "video_editing/preview/properties.html#bpy-types-sequenceeditor-show-overlay"), @@ -401,6 +425,7 @@ url_manual_mapping = ( ("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"), ("bpy.ops.sequencer.view_ghost_border*", "video_editing/preview/properties.html#bpy-ops-sequencer-view-ghost-border"), ("bpy.types.animdata.action_influence*", "editors/nla/properties_modifiers.html#bpy-types-animdata-action-influence"), + ("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"), ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), @@ -420,6 +445,7 @@ url_manual_mapping = ( ("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"), ("bpy.types.regionview3d.use_box_clip*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-use-box-clip"), ("bpy.types.rendersettings.use_border*", "render/output/settings.html#bpy-types-rendersettings-use-border"), + ("bpy.types.rigidbodyconstraint.limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-limit"), ("bpy.types.scene.audio_doppler_speed*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-speed"), ("bpy.types.sceneeevee.bokeh_max_size*", "render/eevee/render_settings/depth_of_field.html#bpy-types-sceneeevee-bokeh-max-size"), ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.html#bpy-types-shadernodebsdfanisotropic"), @@ -447,6 +473,7 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_remove*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove"), ("bpy.ops.object.vertex_group_smooth*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-smooth"), ("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"), + ("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"), ("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"), ("bpy.ops.sequencer.crossfade_sounds*", "video_editing/sequencer/strips/transitions/cross.html#bpy-ops-sequencer-crossfade-sounds"), ("bpy.ops.sequencer.export_subtitles*", "video_editing/preview/introduction.html#bpy-ops-sequencer-export-subtitles"), @@ -493,11 +520,13 @@ url_manual_mapping = ( ("bpy.ops.mesh.shortest_path_select*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-shortest-path-select"), ("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"), ("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"), + ("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"), ("bpy.ops.render.play-rendered-anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"), ("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-set-pivot-position"), ("bpy.ops.sequencer.reassign_inputs*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reassign-inputs"), ("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"), ("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"), + ("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"), ("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"), ("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"), ("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"), @@ -519,6 +548,7 @@ url_manual_mapping = ( ("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"), ("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"), ("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"), + ("bpy.types.layercollection.holdout*", "editors/outliner.html#bpy-types-layercollection-holdout"), ("bpy.types.limitdistanceconstraint*", "animation/constraints/transform/limit_distance.html#bpy-types-limitdistanceconstraint"), ("bpy.types.limitlocationconstraint*", "animation/constraints/transform/limit_location.html#bpy-types-limitlocationconstraint"), ("bpy.types.limitrotationconstraint*", "animation/constraints/transform/limit_rotation.html#bpy-types-limitrotationconstraint"), @@ -534,6 +564,7 @@ url_manual_mapping = ( ("bpy.types.toolsettings.annotation*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), ("bpy.types.viewlayer.use_freestyle*", "render/freestyle/view_layer.html#bpy-types-viewlayer-use-freestyle"), + ("bpy.ops.armature.armature_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-armature-layers"), ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), @@ -553,6 +584,7 @@ url_manual_mapping = ( ("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"), ("bpy.ops.sequencer.duplicate_move*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-duplicate-move"), ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), + ("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"), ("bpy.types.brightcontrastmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-brightcontrastmodifier"), ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), ("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"), @@ -560,6 +592,7 @@ url_manual_mapping = ( ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), ("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"), + ("bpy.types.collection.hide_select*", "editors/outliner.html#bpy-types-collection-hide-select"), ("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"), ("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"), ("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"), @@ -614,12 +647,15 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"), ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), + ("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"), + ("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"), ("bpy.ops.scene.view_layer_remove*", "render/layers/layers.html#bpy-ops-scene-view-layer-remove"), ("bpy.ops.screen.screen_full_area*", "interface/window_system/areas.html#bpy-ops-screen-screen-full-area"), ("bpy.ops.sculpt.face_sets_create*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-create"), ("bpy.ops.transform.rotate_normal*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-transform-rotate-normal"), ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), ("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"), + ("bpy.ops.uv.shortest_path_select*", "editors/uv/selecting.html#bpy-ops-uv-shortest-path-select"), ("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"), ("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"), ("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"), @@ -748,6 +784,8 @@ url_manual_mapping = ( ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask-flood-fill"), ("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"), ("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"), + ("bpy.ops.preferences.copy_prev*", "editors/preferences/introduction.html#bpy-ops-preferences-copy-prev"), + ("bpy.ops.preferences.keyconfig*", "editors/preferences/keymap.html#bpy-ops-preferences-keyconfig"), ("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"), ("bpy.ops.sculpt.face_sets_init*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-init"), ("bpy.ops.sequencer.change_path*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-change-path"), @@ -810,6 +848,7 @@ url_manual_mapping = ( ("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"), ("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"), ("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"), + ("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"), ("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"), ("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), @@ -831,6 +870,7 @@ url_manual_mapping = ( ("bpy.ops.object.select_mirror*", "scene_layout/object/selecting.html#bpy-ops-object-select-mirror"), ("bpy.ops.object.select_random*", "scene_layout/object/selecting.html#bpy-ops-object-select-random"), ("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"), + ("bpy.ops.preferences.autoexec*", "editors/preferences/save_load.html#bpy-ops-preferences-autoexec"), ("bpy.ops.scene.view_layer_add*", "render/layers/layers.html#bpy-ops-scene-view-layer-add"), ("bpy.ops.sculpt.face_set_edit*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-edit"), ("bpy.ops.sequencer.gap_insert*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-gap-insert"), @@ -868,6 +908,7 @@ url_manual_mapping = ( ("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"), ("bpy.types.normaleditmodifier*", "modeling/modifiers/modify/normal_edit.html#bpy-types-normaleditmodifier"), ("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"), + ("bpy.types.object.hide_render*", "editors/outliner.html#bpy-types-object-hide-render"), ("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"), ("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"), ("bpy.types.shadernodebsdfhair*", "render/shader_nodes/shader/hair.html#bpy-types-shadernodebsdfhair"), @@ -914,17 +955,21 @@ url_manual_mapping = ( ("bpy.ops.mesh.remove_doubles*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-remove-doubles"), ("bpy.ops.mesh.select_similar*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar"), ("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"), + ("bpy.ops.nla.action_pushdown*", "editors/nla/tracks.html#bpy-ops-nla-action-pushdown"), ("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"), ("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"), ("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"), ("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"), ("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"), + ("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"), + ("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"), + ("bpy.ops.preferences.keyitem*", "editors/preferences/keymap.html#bpy-ops-preferences-keyitem"), ("bpy.ops.sequencer.swap_data*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-swap-data"), ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/mesh/transform/push_pull.html#bpy-ops-transform-push-pull"), ("bpy.ops.transform.seq_slide*", "video_editing/sequencer/editing.html#bpy-ops-transform-seq-slide"), - ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-trackball"), + ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-trackball"), ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/align_transform_orientation.html#bpy-ops-transform-transform"), - ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-translate"), + ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/move.html#bpy-ops-transform-translate"), ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"), ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"), ("bpy.types.alphaoversequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"), @@ -1002,6 +1047,7 @@ url_manual_mapping = ( ("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"), ("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"), ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), + ("bpy.ops.poselib.apply_pose*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-apply-pose"), ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-expand"), ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-sculpt-mask-filter"), @@ -1009,6 +1055,7 @@ url_manual_mapping = ( ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), + ("bpy.opsuv.select_edge_ring*", "editors/uv/selecting.html#bpy-opsuv-select-edge-ring"), ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), ("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"), @@ -1044,7 +1091,7 @@ url_manual_mapping = ( ("bpy.types.shadernodetexies*", "render/shader_nodes/textures/ies.html#bpy-types-shadernodetexies"), ("bpy.types.shadernodetexsky*", "render/shader_nodes/textures/sky.html#bpy-types-shadernodetexsky"), ("bpy.types.softbodymodifier*", "physics/soft_body/index.html#bpy-types-softbodymodifier"), - ("bpy.types.softbodysettings*", "physics/soft_body/settings.html#bpy-types-softbodysettings"), + ("bpy.types.softbodysettings*", "physics/soft_body/settings/index.html#bpy-types-softbodysettings"), ("bpy.types.solidifymodifier*", "modeling/modifiers/generate/solidify.html#bpy-types-solidifymodifier"), ("bpy.types.spacegrapheditor*", "editors/graph_editor/index.html#bpy-types-spacegrapheditor"), ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), @@ -1078,6 +1125,7 @@ url_manual_mapping = ( ("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"), ("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"), ("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"), + ("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"), ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), ("bpy.ops.screen.area_dupli*", "interface/window_system/areas.html#bpy-ops-screen-area-dupli"), @@ -1086,6 +1134,7 @@ url_manual_mapping = ( ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), ("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"), + ("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"), ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), @@ -1135,14 +1184,15 @@ url_manual_mapping = ( ("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"), ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), ("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"), + ("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"), ("bpy.ops.scene.view_layer*", "render/layers/layers.html#bpy-ops-scene-view-layer"), ("bpy.ops.sequencer.delete*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-delete"), ("bpy.ops.sequencer.reload*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reload"), ("bpy.ops.sequencer.unlock*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-unlock"), ("bpy.ops.sequencer.unmute*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-unmute"), ("bpy.ops.transform.mirror*", "scene_layout/object/editing/mirror.html#bpy-ops-transform-mirror"), - ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-resize"), - ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/basics.html#bpy-ops-transform-rotate"), + ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/scale.html#bpy-ops-transform-resize"), + ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-rotate"), ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv.html#bpy-ops-uv-lightmap-pack"), ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-smart-project"), ("bpy.ops.uv.snap_selected*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-selected"), @@ -1326,6 +1376,7 @@ url_manual_mapping = ( ("bpy.ops.nla.move_down*", "editors/nla/editing.html#bpy-ops-nla-move-down"), ("bpy.ops.object.*clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-clear"), ("bpy.ops.object.delete*", "scene_layout/object/editing/delete.html#bpy-ops-object-delete"), + ("bpy.ops.render.opengl*", "editors/3dview/viewport_render.html#bpy-ops-render-opengl"), ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), @@ -1389,6 +1440,7 @@ url_manual_mapping = ( ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), + ("bpy.ops.preferences*", "editors/preferences/index.html#bpy-ops-preferences"), ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), @@ -1494,7 +1546,7 @@ url_manual_mapping = ( ("bpy.ops.ed.undo*", "interface/undo_redo.html#bpy-ops-ed-undo"), ("bpy.ops.gpencil*", "grease_pencil/index.html#bpy-ops-gpencil"), ("bpy.ops.lattice*", "animation/lattice.html#bpy-ops-lattice"), - ("bpy.ops.poselib*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib"), + ("bpy.ops.poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib"), ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), -- cgit v1.2.3 From 0006f78cb6eec3f0c17d2b071f0648edf3c2cbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 8 Sep 2020 20:17:20 +0200 Subject: Revert "BKE: Fix compiling with clang-tidy and readability-non-const-parameter" This reverts commit 637a5c964a01f5e8733e972cb8a30341eb91058e. I commited the previous commit because I wasn't building with openvdb. Compiling with openvdb fix the clang-tidy errror. --- source/blender/blenkernel/BKE_volume_render.h | 2 +- source/blender/blenkernel/intern/volume_render.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h index ac69b615c3f..a42f24a5312 100644 --- a/source/blender/blenkernel/BKE_volume_render.h +++ b/source/blender/blenkernel/BKE_volume_render.h @@ -46,7 +46,7 @@ void BKE_volume_grid_dense_voxels(const struct Volume *volume, struct VolumeGrid *volume_grid, const int64_t min[3], const int64_t max[3], - const float *voxels); + float *voxels); /* Wireframe */ diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc index ab9242ad24a..98d3617c822 100644 --- a/source/blender/blenkernel/intern/volume_render.cc +++ b/source/blender/blenkernel/intern/volume_render.cc @@ -94,7 +94,7 @@ void BKE_volume_grid_dense_voxels(const Volume *volume, VolumeGrid *volume_grid, const int64_t min[3], const int64_t max[3], - const float *voxels) + float *voxels) { #ifdef WITH_OPENVDB openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid); -- cgit v1.2.3 From 25380802d702e65bc232efb5cd7768d6ace165d4 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 8 Sep 2020 13:54:39 -0500 Subject: Cleanup: Use bool instead of int --- source/blender/editors/screen/screen_ops.c | 177 ++++++++++++++--------------- 1 file changed, 88 insertions(+), 89 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b79447273d6..32b91dbd327 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -105,55 +105,55 @@ bool ED_operator_regionactive(bContext *C) { if (CTX_wm_window(C) == NULL) { - return 0; + return false; } if (CTX_wm_screen(C) == NULL) { - return 0; + return false; } if (CTX_wm_region(C) == NULL) { - return 0; + return false; } - return 1; + return true; } bool ED_operator_areaactive(bContext *C) { if (CTX_wm_window(C) == NULL) { - return 0; + return false; } if (CTX_wm_screen(C) == NULL) { - return 0; + return false; } if (CTX_wm_area(C) == NULL) { - return 0; + return false; } - return 1; + return true; } bool ED_operator_screenactive(bContext *C) { if (CTX_wm_window(C) == NULL) { - return 0; + return false; } if (CTX_wm_screen(C) == NULL) { - return 0; + return false; } - return 1; + return true; } /* XXX added this to prevent anim state to change during renders */ static bool ED_operator_screenactive_norender(bContext *C) { if (G.is_rendering) { - return 0; + return false; } if (CTX_wm_window(C) == NULL) { - return 0; + return false; } if (CTX_wm_screen(C) == NULL) { - return 0; + return false; } - return 1; + return true; } /* when mouse is over area-edge */ @@ -161,25 +161,25 @@ bool ED_operator_screen_mainwinactive(bContext *C) { bScreen *screen; if (CTX_wm_window(C) == NULL) { - return 0; + return false; } screen = CTX_wm_screen(C); if (screen == NULL) { - return 0; + return false; } if (screen->active_region != NULL) { - return 0; + return false; } - return 1; + return true; } bool ED_operator_scene(bContext *C) { Scene *scene = CTX_data_scene(C); if (scene) { - return 1; + return true; } - return 0; + return false; } bool ED_operator_scene_editable(bContext *C) @@ -197,18 +197,18 @@ bool ED_operator_objectmode(bContext *C) Object *obact = CTX_data_active_object(C); if (scene == NULL || ID_IS_LINKED(scene)) { - return 0; + return false; } if (CTX_data_edit_object(C)) { - return 0; + return false; } /* add a check for ob->mode too? */ if (obact && (obact->mode != OB_MODE_OBJECT)) { - return 0; + return false; } - return 1; + return true; } static bool ed_spacetype_test(bContext *C, int type) @@ -217,7 +217,7 @@ static bool ed_spacetype_test(bContext *C, int type) SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C); return sl && (sl->spacetype == type); } - return 0; + return false; } bool ED_operator_view3d_active(bContext *C) @@ -246,7 +246,7 @@ bool ED_operator_animview_active(bContext *C) } CTX_wm_operator_poll_msg_set(C, "expected a timeline/animation area to be active"); - return 0; + return false; } bool ED_operator_outliner_active(bContext *C) @@ -260,11 +260,11 @@ bool ED_operator_outliner_active_no_editobject(bContext *C) Object *ob = ED_object_active_context(C); Object *obedit = CTX_data_edit_object(C); if (ob && ob == obedit) { - return 0; + return false; } - return 1; + return true; } - return 0; + return false; } bool ED_operator_file_active(bContext *C) @@ -287,10 +287,10 @@ bool ED_operator_node_active(bContext *C) SpaceNode *snode = CTX_wm_space_node(C); if (snode && snode->edittree) { - return 1; + return true; } - return 0; + return false; } bool ED_operator_node_editable(bContext *C) @@ -298,10 +298,10 @@ bool ED_operator_node_editable(bContext *C) SpaceNode *snode = CTX_wm_space_node(C); if (snode && snode->edittree && !ID_IS_LINKED(snode->edittree)) { - return 1; + return true; } - return 0; + return false; } bool ED_operator_graphedit_active(bContext *C) @@ -400,7 +400,7 @@ bool ED_operator_editmesh(bContext *C) if (obedit && obedit->type == OB_MESH) { return NULL != BKE_editmesh_from_object(obedit); } - return 0; + return false; } bool ED_operator_editmesh_view3d(bContext *C) @@ -411,11 +411,11 @@ bool ED_operator_editmesh_view3d(bContext *C) bool ED_operator_editmesh_region_view3d(bContext *C) { if (ED_operator_editmesh(C) && CTX_wm_region_view3d(C)) { - return 1; + return true; } CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editmesh"); - return 0; + return false; } bool ED_operator_editmesh_auto_smooth(bContext *C) @@ -424,7 +424,7 @@ bool ED_operator_editmesh_auto_smooth(bContext *C) if (obedit && obedit->type == OB_MESH && (((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH)) { return NULL != BKE_editmesh_from_object(obedit); } - return 0; + return false; } bool ED_operator_editarmature(bContext *C) @@ -433,7 +433,7 @@ bool ED_operator_editarmature(bContext *C) if (obedit && obedit->type == OB_ARMATURE) { return NULL != ((bArmature *)obedit->data)->edbo; } - return 0; + return false; } /** @@ -451,12 +451,12 @@ bool ED_operator_posemode_exclusive(bContext *C) Object *obpose; if ((obpose = BKE_object_pose_armature_get(obact))) { if (obact == obpose) { - return 1; + return true; } } } - return 0; + return false; } /* allows for pinned pose objects to be used in the object buttons @@ -467,11 +467,11 @@ bool ED_operator_posemode_context(bContext *C) if (obpose && !(obpose->mode & OB_MODE_EDIT)) { if (BKE_object_pose_context_check(obpose)) { - return 1; + return true; } } - return 0; + return false; } bool ED_operator_posemode(bContext *C) @@ -482,12 +482,12 @@ bool ED_operator_posemode(bContext *C) Object *obpose; if ((obpose = BKE_object_pose_armature_get(obact))) { if ((obact == obpose) || (obact->mode & OB_MODE_ALL_WEIGHT_PAINT)) { - return 1; + return true; } } } - return 0; + return false; } bool ED_operator_posemode_local(bContext *C) @@ -537,17 +537,17 @@ bool ED_operator_editsurfcurve(bContext *C) if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) { return NULL != ((Curve *)obedit->data)->editnurb; } - return 0; + return false; } bool ED_operator_editsurfcurve_region_view3d(bContext *C) { if (ED_operator_editsurfcurve(C) && CTX_wm_region_view3d(C)) { - return 1; + return true; } CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editcurve"); - return 0; + return false; } bool ED_operator_editcurve(bContext *C) @@ -556,7 +556,7 @@ bool ED_operator_editcurve(bContext *C) if (obedit && obedit->type == OB_CURVE) { return NULL != ((Curve *)obedit->data)->editnurb; } - return 0; + return false; } bool ED_operator_editcurve_3d(bContext *C) @@ -567,7 +567,7 @@ bool ED_operator_editcurve_3d(bContext *C) return (cu->flag & CU_3D) && (NULL != cu->editnurb); } - return 0; + return false; } bool ED_operator_editsurf(bContext *C) @@ -576,7 +576,7 @@ bool ED_operator_editsurf(bContext *C) if (obedit && obedit->type == OB_SURF) { return NULL != ((Curve *)obedit->data)->editnurb; } - return 0; + return false; } bool ED_operator_editfont(bContext *C) @@ -585,7 +585,7 @@ bool ED_operator_editfont(bContext *C) if (obedit && obedit->type == OB_FONT) { return NULL != ((Curve *)obedit->data)->editfont; } - return 0; + return false; } bool ED_operator_editlattice(bContext *C) @@ -594,7 +594,7 @@ bool ED_operator_editlattice(bContext *C) if (obedit && obedit->type == OB_LATTICE) { return NULL != ((Lattice *)obedit->data)->editlatt; } - return 0; + return false; } bool ED_operator_editmball(bContext *C) @@ -603,7 +603,7 @@ bool ED_operator_editmball(bContext *C) if (obedit && obedit->type == OB_MBALL) { return NULL != ((MetaBall *)obedit->data)->editelems; } - return 0; + return false; } bool ED_operator_mask(bContext *C) @@ -649,11 +649,11 @@ static bool screen_active_editable(bContext *C) if (ED_operator_screenactive(C)) { /* no full window splitting allowed */ if (CTX_wm_screen(C)->state != SCREENNORMAL) { - return 0; + return false; } - return 1; + return true; } - return 0; + return false; } /** \} */ @@ -702,12 +702,12 @@ static bool actionzone_area_poll(bContext *C) LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (AZone *, az, &area->actionzones) { if (BLI_rcti_isect_pt_v(&az->rect, xy)) { - return 1; + return true; } } } } - return 0; + return false; } /* the debug drawing of the click_rect is in area_draw_azone_fullscreen, keep both in sync */ @@ -901,7 +901,7 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b ED_region_tag_redraw_no_rebuild(az->region); } else { - BLI_assert(0); + BLI_assert(false); } } } @@ -1213,13 +1213,13 @@ typedef struct sAreaSwapData { ScrArea *sa1, *sa2; } sAreaSwapData; -static int area_swap_init(wmOperator *op, const wmEvent *event) +static bool area_swap_init(wmOperator *op, const wmEvent *event) { sAreaSwapData *sd = NULL; sActionzoneData *sad = event->customdata; if (sad == NULL || sad->sa1 == NULL) { - return 0; + return false; } sd = MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData"); @@ -1227,7 +1227,7 @@ static int area_swap_init(wmOperator *op, const wmEvent *event) sd->sa2 = sad->sa2; op->customdata = sd; - return 1; + return true; } static void area_swap_exit(bContext *C, wmOperator *op) @@ -1246,7 +1246,6 @@ static void area_swap_cancel(bContext *C, wmOperator *op) static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (!area_swap_init(op, event)) { return OPERATOR_PASS_THROUGH; } @@ -1573,8 +1572,8 @@ static void area_move_set_limits(wmWindow *win, } /* validate selection inside screen, set variables OK */ -/* return 0: init failed */ -static int area_move_init(bContext *C, wmOperator *op) +/* return false: init failed */ +static bool area_move_init(bContext *C, wmOperator *op) { bScreen *screen = CTX_wm_screen(C); wmWindow *win = CTX_wm_window(C); @@ -1589,7 +1588,7 @@ static int area_move_init(bContext *C, wmOperator *op) /* setup */ actedge = screen_geom_find_active_scredge(win, screen, x, y); if (actedge == NULL) { - return 0; + return false; } md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData"); @@ -1615,7 +1614,7 @@ static int area_move_init(bContext *C, wmOperator *op) md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID; - return 1; + return true; } static int area_snap_calc_location(const bScreen *screen, @@ -1985,7 +1984,7 @@ static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdat } /* generic init, menu case, doesn't need active area */ -static int area_split_menu_init(bContext *C, wmOperator *op) +static bool area_split_menu_init(bContext *C, wmOperator *op) { sAreaSplitData *sd; @@ -1995,11 +1994,11 @@ static int area_split_menu_init(bContext *C, wmOperator *op) sd->sarea = CTX_wm_area(C); - return 1; + return true; } /* generic init, no UI stuff here, assumes active area */ -static int area_split_init(bContext *C, wmOperator *op) +static bool area_split_init(bContext *C, wmOperator *op) { ScrArea *area = CTX_wm_area(C); sAreaSplitData *sd; @@ -2008,7 +2007,7 @@ static int area_split_init(bContext *C, wmOperator *op) /* required context */ if (area == NULL) { - return 0; + return false; } /* required properties */ @@ -2016,10 +2015,10 @@ static int area_split_init(bContext *C, wmOperator *op) /* minimal size */ if (dir == 'v' && area->winx < 2 * AREAMINX) { - return 0; + return false; } if (dir == 'h' && area->winy < 2 * areaminy) { - return 0; + return false; } /* custom data */ @@ -2036,7 +2035,7 @@ static int area_split_init(bContext *C, wmOperator *op) sd->origsize = area->v2->vec.y - sd->origmin; } - return 1; + return true; } /* with area as center, sb is located at: 0=W, 1=N, 2=E, 3=S */ @@ -2069,7 +2068,7 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *area, ScrArea *sb) } /* do the split, return success */ -static int area_split_apply(bContext *C, wmOperator *op) +static bool area_split_apply(bContext *C, wmOperator *op) { const wmWindow *win = CTX_wm_window(C); bScreen *screen = CTX_wm_screen(C); @@ -2108,10 +2107,10 @@ static int area_split_apply(bContext *C, wmOperator *op) /* Update preview thumbnail */ BKE_icon_changed(screen->id.icon_id); - return 1; + return true; } - return 0; + return false; } static void area_split_exit(bContext *C, wmOperator *op) @@ -3277,8 +3276,8 @@ static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata } /* validate selection inside screen, set variables OK */ -/* return 0: init failed */ -static int area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa2) +/* return false: init failed */ +static bool area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa2) { if (sa1 == NULL || sa2 == NULL) { /* Get areas from cursor location if not specified. */ @@ -3287,7 +3286,7 @@ static int area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa screen_area_edge_from_cursor(C, cursor, &sa1, &sa2); } if (sa1 == NULL || sa2 == NULL) { - return 0; + return false; } sAreaJoinData *jd = MEM_callocN(sizeof(sAreaJoinData), "op_area_join"); @@ -3299,26 +3298,26 @@ static int area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa jd->draw_callback = WM_draw_cb_activate(CTX_wm_window(C), area_join_draw_cb, op); - return 1; + return true; } /* apply the join of the areas (space types) */ -static int area_join_apply(bContext *C, wmOperator *op) +static bool area_join_apply(bContext *C, wmOperator *op) { sAreaJoinData *jd = (sAreaJoinData *)op->customdata; if (!jd) { - return 0; + return false; } if (!screen_area_join(C, CTX_wm_screen(C), jd->sa1, jd->sa2)) { - return 0; + return false; } if (CTX_wm_area(C) == jd->sa2) { CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); } - return 1; + return true; } /* finish operation */ @@ -4006,7 +4005,7 @@ static bool region_toggle_poll(bContext *C) /* Don't flip anything around in top-bar. */ if (area && area->spacetype == SPACE_TOPBAR) { CTX_wm_operator_poll_msg_set(C, "Toggling regions in the Top-bar is not allowed"); - return 0; + return false; } return ED_operator_areaactive(C); @@ -5593,10 +5592,10 @@ static bool blend_file_drop_poll(bContext *UNUSED(C), { if (drag->type == WM_DRAG_PATH) { if (drag->icon == ICON_FILE_BLEND) { - return 1; + return true; } } - return 0; + return false; } static void blend_file_drop_copy(wmDrag *drag, wmDropBox *drop) -- cgit v1.2.3 From f7fab77f85734e49414ea7d063532dbac6c5b6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 9 Sep 2020 00:23:48 +0200 Subject: Cleanup: GPU: Replace multiple checks by GLContext::debug_layer_support --- source/blender/gpu/opengl/gl_backend.cc | 7 +++++++ source/blender/gpu/opengl/gl_context.hh | 1 + source/blender/gpu/opengl/gl_debug.cc | 2 +- source/blender/gpu/opengl/gl_framebuffer.cc | 8 ++------ source/blender/gpu/opengl/gl_immediate.cc | 4 +--- source/blender/gpu/opengl/gl_shader.cc | 8 ++------ source/blender/gpu/opengl/gl_texture.cc | 16 ++++------------ source/blender/gpu/opengl/gl_uniform_buffer.cc | 4 +--- 8 files changed, 19 insertions(+), 31 deletions(-) diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index e55e07d5a0b..c8d57a20a38 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -330,6 +330,7 @@ GLint GLContext::max_ubo_size; GLint GLContext::max_ubo_binds; /** Extensions. */ bool GLContext::base_instance_support = false; +bool GLContext::debug_layer_support = false; bool GLContext::texture_cube_map_array_support = false; /** Workarounds. */ bool GLContext::texture_copy_workaround = false; @@ -354,6 +355,12 @@ void GLBackend::capabilities_init(void) glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GLContext::max_ubo_size); GLContext::base_instance_support = GLEW_ARB_base_instance; GLContext::texture_cube_map_array_support = GLEW_ARB_texture_cube_map_array; + GLContext::debug_layer_support = (GLEW_VERSION_4_3 || GLEW_KHR_debug); + + if ((G.debug & G_DEBUG_GPU) == 0) { + /* Disable this feature entierly when not debugging. */ + GLContext::debug_layer_support = false; + } detect_workarounds(); } diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index 8e653a56cd6..10ae396d138 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -62,6 +62,7 @@ class GLContext : public Context { static GLint max_ubo_binds; /** Extensions. */ static bool base_instance_support; + static bool debug_layer_support; static bool texture_cube_map_array_support; /** Workarounds. */ static bool texture_copy_workaround; diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc index 53a71516018..468d1514d60 100644 --- a/source/blender/gpu/opengl/gl_debug.cc +++ b/source/blender/gpu/opengl/gl_debug.cc @@ -122,7 +122,7 @@ void init_gl_callbacks(void) char msg[256] = ""; const char format[] = "Successfully hooked OpenGL debug callback using %s"; - if (GLEW_VERSION_4_3 || GLEW_KHR_debug) { + if (GLContext::debug_layer_support) { SNPRINTF(msg, format, GLEW_VERSION_4_3 ? "OpenGL 4.3" : "KHR_debug extension"); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index 14b7d78c2ff..bfc8a2f74eb 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -63,13 +63,11 @@ GLFrameBuffer::GLFrameBuffer( viewport_[2] = scissor_[2] = w; viewport_[3] = scissor_[3] = h; -#ifndef __APPLE__ - if (fbo_id_ && (G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (fbo_id_ && GLContext::debug_layer_support) { char sh_name[32]; SNPRINTF(sh_name, "FrameBuffer-%s", name); glObjectLabel(GL_FRAMEBUFFER, fbo_id_, -1, sh_name); } -#endif } GLFrameBuffer::~GLFrameBuffer() @@ -100,15 +98,13 @@ void GLFrameBuffer::init(void) state_manager_ = static_cast(context_->state_manager); glGenFramebuffers(1, &fbo_id_); -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sh_name[64]; SNPRINTF(sh_name, "FrameBuffer-%s", name_); /* Binding before setting the label is needed on some drivers. */ glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); glObjectLabel(GL_FRAMEBUFFER, fbo_id_, -1, sh_name); } -#endif } /** \} */ diff --git a/source/blender/gpu/opengl/gl_immediate.cc b/source/blender/gpu/opengl/gl_immediate.cc index 26b1df88b64..7afbbf9965c 100644 --- a/source/blender/gpu/opengl/gl_immediate.cc +++ b/source/blender/gpu/opengl/gl_immediate.cc @@ -60,13 +60,11 @@ GLImmediate::GLImmediate() glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { glObjectLabel(GL_VERTEX_ARRAY, vao_id_, -1, "VAO-Immediate"); glObjectLabel(GL_BUFFER, buffer.vbo_id, -1, "VBO-ImmediateBuffer"); glObjectLabel(GL_BUFFER, buffer_strict.vbo_id, -1, "VBO-ImmediateBufferStrict"); } -#endif } GLImmediate::~GLImmediate() diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index ca38efe37b5..4314ecfa6be 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -48,13 +48,11 @@ GLShader::GLShader(const char *name) : Shader(name) #endif shader_program_ = glCreateProgram(); -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sh_name[64]; SNPRINTF(sh_name, "ShaderProgram-%s", name); glObjectLabel(GL_PROGRAM, shader_program_, -1, sh_name); } -#endif } GLShader::~GLShader(void) @@ -165,8 +163,7 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan return 0; } -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sh_name[64]; switch (gl_stage) { case GL_VERTEX_SHADER: @@ -181,7 +178,6 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan } glObjectLabel(GL_SHADER, shader, -1, sh_name); } -#endif glAttachShader(shader_program_, shader); return shader; diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index e649f73d1c4..ec08b736af2 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -96,14 +96,12 @@ bool GLTexture::init_internal(void) glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sh_name[64]; SNPRINTF(sh_name, "Texture-%s", name_); /* Binding before setting the label is needed on some drivers. */ glObjectLabel(GL_TEXTURE, tex_id_, -1, sh_name); } -#endif GL_CHECK_ERROR("Post-texture creation"); return true; @@ -127,14 +125,12 @@ bool GLTexture::init_internal(GPUVertBuf *vbo) glTexBuffer(target_, internal_format, gl_vbo->vbo_id_); } -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sh_name[64]; SNPRINTF(sh_name, "Texture-%s", name_); /* Binding before setting the label is needed on some drivers. */ glObjectLabel(GL_TEXTURE, tex_id_, -1, sh_name); } -#endif GL_CHECK_ERROR("Post-texture buffer creation"); return true; @@ -514,8 +510,7 @@ void GLTexture::samplers_init(void) * - GL_TEXTURE_LOD_BIAS is 0.0f. **/ -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sampler_name[128]; SNPRINTF(sampler_name, "Sampler%s%s%s%s%s%s%s%s%s%s", @@ -531,7 +526,6 @@ void GLTexture::samplers_init(void) (state & GPU_SAMPLER_ANISO) ? "_aniso" : ""); glObjectLabel(GL_SAMPLER, samplers_[i], -1, sampler_name); } -#endif } samplers_update(); @@ -541,11 +535,9 @@ void GLTexture::samplers_init(void) glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f); -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { glObjectLabel(GL_SAMPLER, icon_sampler, -1, "Sampler-icons"); } -#endif } void GLTexture::samplers_update(void) diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc index 62c590d289f..74453a08bfe 100644 --- a/source/blender/gpu/opengl/gl_uniform_buffer.cc +++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc @@ -62,13 +62,11 @@ void GLUniformBuf::init(void) glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_); glBufferData(GL_UNIFORM_BUFFER, size_in_bytes_, NULL, GL_DYNAMIC_DRAW); -#ifndef __APPLE__ - if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + if (GLContext::debug_layer_support) { char sh_name[64]; SNPRINTF(sh_name, "UBO-%s", name_); glObjectLabel(GL_BUFFER, ubo_id_, -1, sh_name); } -#endif } void GLUniformBuf::update(const void *data) -- cgit v1.2.3 From b8840c105a4e44c3dd8be2fa90dc610e4ef25cd5 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 8 Sep 2020 19:12:57 -0400 Subject: UI: Rename "VCol" to "Vertex Colors" --- source/blender/editors/object/object_data_transfer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 8bec200cb40..da00a88ab65 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -85,7 +85,7 @@ static const EnumPropertyItem DT_layer_items[] = { "Transfer Freestyle edge mark"}, {0, "", 0, "Face Corner Data", ""}, {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"}, - {DT_TYPE_VCOL, "VCOL", 0, "VCol", "Vertex (face corners) colors"}, + {DT_TYPE_VCOL, "VCOL", 0, "Vertex Colors", "Vertex (face corners) colors"}, {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"}, {0, "", 0, "Face Data", ""}, {DT_TYPE_SHARP_FACE, "SMOOTH", 0, "Smooth", "Transfer flat/smooth mark"}, -- cgit v1.2.3 From 1f75be8a40041e94711c5d17507d88d8e64c1977 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2020 12:48:29 +1000 Subject: Fix T80604: BLI_polyfill_calc exceeds stack size allocating points On systems with 512kb stack this happened at around 13k points. This happened at times with grease-pencil, although callers that frequently use complex polygons should be using BLI_polyfill_calc_arena. --- source/blender/blenlib/intern/polyfill_2d.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c index d1e2bd58909..eb7e5ca6658 100644 --- a/source/blender/blenlib/intern/polyfill_2d.c +++ b/source/blender/blenlib/intern/polyfill_2d.c @@ -907,6 +907,19 @@ void BLI_polyfill_calc(const float (*coords)[2], const int coords_sign, uint (*r_tris)[3]) { + /* Fallback to heap memory for large allocations. + * Avoid running out of stack memory on systems with 512kb stack (macOS). + * This happens at around 13,000 points, use a much lower value to be safe. */ + if (UNLIKELY(coords_tot > 8192)) { + /* The buffer size only accounts for the index allocation, + * worst case we do two allocations when concave, while we should try to be efficient, + * any caller that relies on this frequently should use #BLI_polyfill_calc_arena directly. */ + MemArena *arena = BLI_memarena_new(sizeof(PolyIndex) * coords_tot, __func__); + BLI_polyfill_calc_arena(coords, coords_tot, coords_sign, r_tris, arena); + BLI_memarena_free(arena); + return; + } + PolyFill pf; PolyIndex *indices = BLI_array_alloca(indices, coords_tot); -- cgit v1.2.3 From 23f1dea4408fa87db5193b88b4315d8de15804b2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2020 13:19:50 +1000 Subject: Cleanup: spelling --- intern/cycles/kernel/closure/bsdf_hair_principled.h | 4 ++-- source/blender/depsgraph/intern/eval/deg_eval.cc | 2 +- source/blender/depsgraph/intern/eval/deg_eval.h | 2 +- source/blender/editors/space_text/text_format.h | 2 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 2 +- .../freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp | 2 +- .../freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp | 2 +- .../intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp | 2 +- source/blender/freestyle/intern/stroke/Predicates1D.h | 4 ++-- source/blender/freestyle/intern/view_map/Silhouette.h | 2 +- source/blender/io/collada/TransformWriter.cpp | 2 +- source/blender/io/usd/intern/usd_writer_abstract.h | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index 389bd62ba68..f12661b3095 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -124,8 +124,8 @@ ccl_device_inline float bessel_I0(float x) ccl_device_inline float log_bessel_I0(float x) { if (x > 12.0f) { - /* log(1/x) == -log(x) iff x > 0. - * This is only used with positive cosines */ + /* log(1/x) == -log(x) if x > 0. + * This is only used with positive cosines. */ return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x)); } else { diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 2e0487bfca1..2c4b7f03db5 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -20,7 +20,7 @@ /** \file * \ingroup depsgraph * - * Evaluation engine entrypoints for Depsgraph Engine. + * Evaluation engine entry-points for Depsgraph Engine. */ #include "intern/eval/deg_eval.h" diff --git a/source/blender/depsgraph/intern/eval/deg_eval.h b/source/blender/depsgraph/intern/eval/deg_eval.h index 49690f15412..7a23c0f8613 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.h +++ b/source/blender/depsgraph/intern/eval/deg_eval.h @@ -20,7 +20,7 @@ /** \file * \ingroup depsgraph * - * Evaluation engine entrypoints for Depsgraph Engine. + * Evaluation engine entry-points for Depsgraph Engine. */ #pragma once diff --git a/source/blender/editors/space_text/text_format.h b/source/blender/editors/space_text/text_format.h index bb9574ee55e..833f40730ad 100644 --- a/source/blender/editors/space_text/text_format.h +++ b/source/blender/editors/space_text/text_format.h @@ -61,7 +61,7 @@ typedef struct TextFormatType { char (*format_identifier)(const char *string); /* Formats the specified line. If do_next is set, the process will move on to - * the succeeding line if it is affected (eg. multiline strings). Format strings + * the succeeding line if it is affected (eg. multi-line strings). Format strings * may contain any of the following characters: * * It is terminated with a null-terminator '\0' followed by a continuation diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 49f11cd6a74..f043dc92624 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -261,7 +261,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, key = (ParamKey)face_index; /* let parametrizer split the ngon, it can make better decisions - * about which split is best for unwrapping than scanfill */ + * about which split is best for unwrapping than poly-fill. */ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp index 5db75c84608..c329a3badd5 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp @@ -36,7 +36,7 @@ PyDoc_STRVAR(FEdgeSharp_doc, "\n" "Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial\n" "edge of the input mesh. It can be a silhouette, a crease or a border.\n" - "If it is a crease edge, then it is borded by two faces of the mesh.\n" + "If it is a crease edge, then it is bordered by two faces of the mesh.\n" "Face a lies on its right whereas Face b lies on its left. If it is a\n" "border edge, then it doesn't have any face on its right, and thus Face\n" "a is None.\n" diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp index 21bd371935a..734aa5a0e84 100644 --- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp @@ -34,7 +34,7 @@ static char ContourUP1D___doc__[] = ".. method:: __call__(inter)\n" "\n" " Returns true if the Interface1D is a contour. An Interface1D is a\n" - " contour if it is borded by a different shape on each of its sides.\n" + " contour if it is bordered by a different shape on each of its sides.\n" "\n" " :arg inter: An Interface1D object.\n" " :type inter: :class:`freestyle.types.Interface1D`\n" diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp index ea034dfad1e..3ddadcf2d4f 100644 --- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp @@ -34,7 +34,7 @@ static char ExternalContourUP1D___doc__[] = ".. method:: __call__(inter)\n" "\n" " Returns true if the Interface1D is an external contour. An\n" - " Interface1D is an external contour if it is borded by no shape on\n" + " Interface1D is an external contour if it is bordered by no shape on\n" " one of its sides.\n" "\n" " :arg inter: An Interface1D object.\n" diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h index a3953950d86..c174162b214 100644 --- a/source/blender/freestyle/intern/stroke/Predicates1D.h +++ b/source/blender/freestyle/intern/stroke/Predicates1D.h @@ -218,7 +218,7 @@ class QuantitativeInvisibilityUP1D : public UnaryPredicate1D { // ContourUP1D /*! Returns true if the Interface1D is a contour. - * An Interface1D is a contour if it is borded by a different shape on each of its sides. + * An Interface1D is a contour if it is bordered by a different shape on each of its sides. */ class ContourUP1D : public UnaryPredicate1D { private: @@ -253,7 +253,7 @@ class ContourUP1D : public UnaryPredicate1D { // ExternalContourUP1D /*! Returns true if the Interface1D is an external contour. - * An Interface1D is an external contour if it is borded by no shape on one of its sides. + * An Interface1D is an external contour if it is bordered by no shape on one of its sides. */ class ExternalContourUP1D : public UnaryPredicate1D { private: diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h index c27d6b633b4..5a59f488b51 100644 --- a/source/blender/freestyle/intern/view_map/Silhouette.h +++ b/source/blender/freestyle/intern/view_map/Silhouette.h @@ -1139,7 +1139,7 @@ Interface0DIterator FEdge::pointsEnd(float /*t*/) } /*! Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial edge of the input mesh. - * It can be a silhouette, a crease or a border. If it is a crease edge, then it is borded + * It can be a silhouette, a crease or a border. If it is a crease edge, then it is bordered * by two faces of the mesh. Face a lies on its right whereas Face b lies on its left. * If it is a border edge, then it doesn't have any face on its right, and thus Face a = 0. */ diff --git a/source/blender/io/collada/TransformWriter.cpp b/source/blender/io/collada/TransformWriter.cpp index 0311f22fe11..7c9d26e4fde 100644 --- a/source/blender/io/collada/TransformWriter.cpp +++ b/source/blender/io/collada/TransformWriter.cpp @@ -66,7 +66,7 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node &node, bool limit_precision = export_settings.get_limit_precision(); /* Export the local Matrix (relative to the object parent, - * be it an object, bone or vertex(-tices)). */ + * be it an object, bone or vertices (one or more)). */ Matrix f_obmat; BKE_object_matrix_local_get(ob, f_obmat); diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index 88df7cb1cc6..6cf7c79c5fa 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -78,7 +78,7 @@ class USDAbstractWriter : public AbstractHierarchyWriter { pxr::UsdGeomImageable &usd_geometry); /* Turn `prim` into an instance referencing `context.original_export_path`. - * Return true when the instancing was succesful, false otherwise. */ + * Return true when the instancing was successful, false otherwise. */ virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim); }; -- cgit v1.2.3 From 3e8b1550dc429b35aef8ad599ac94f913ab0d436 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2020 14:39:54 +1000 Subject: Fix "Select" option being ignored when linking collection instances Also check 'BASE_SELECTABLE' before selecting which was only done for collections. --- source/blender/blenloader/intern/readfile.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 195bb1e7f9f..18d563cb365 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10312,7 +10312,7 @@ static void add_loose_objects_to_scene(Main *mainvar, base->local_view_bits |= v3d->local_view_uuid; } - if (flag & FILE_AUTOSELECT) { + if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) { /* Do NOT make base active here! screws up GUI stuff, * if you want it do it at the editor level. */ base->flag |= BASE_SELECTED; @@ -10370,7 +10370,7 @@ static void add_loose_object_data_to_scene(Main *mainvar, base->local_view_bits |= v3d->local_view_uuid; } - if (flag & FILE_AUTOSELECT) { + if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) { /* Do NOT make base active here! screws up GUI stuff, * if you want it do it at the editor level. */ base->flag |= BASE_SELECTED; @@ -10416,13 +10416,16 @@ static void add_collections_to_scene(Main *mainvar, base->local_view_bits |= v3d->local_view_uuid; } - if (base->flag & BASE_SELECTABLE) { + if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) { base->flag |= BASE_SELECTED; } BKE_scene_object_base_flag_sync_from_base(base); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); - view_layer->basact = base; + + if (flag & FILE_AUTOSELECT) { + view_layer->basact = base; + } /* Assign the collection. */ ob->instance_collection = collection; -- cgit v1.2.3 From 092bea06da38fb292540f75de12cb28780b5d919 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2020 15:26:46 +1000 Subject: Cleanup: access context argument instead of bpy.context --- release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index d729180843e..4f4bb3cf2cd 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1201,10 +1201,10 @@ class _defs_sculpt: @staticmethod def generate_from_brushes(context): exclude_filter = {} - if not bpy.context.preferences.experimental.use_sculpt_vertex_colors: + if not context.preferences.experimental.use_sculpt_vertex_colors: exclude_filter = {'PAINT', 'SMEAR'} - if not bpy.context.preferences.experimental.use_tools_missing_icons: + if not context.preferences.experimental.use_tools_missing_icons: exclude_filter = {'PAINT', 'SMEAR', 'BOUNDARY', 'DISPLACEMENT_ERASER'} return generate_from_enum_ex( -- cgit v1.2.3 From 0b311eeca5486b763d43f0d9dadc5553a693e3e8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2020 15:34:53 +1000 Subject: Correct error in last commit --- release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 4f4bb3cf2cd..75dfd60b1d4 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1201,10 +1201,12 @@ class _defs_sculpt: @staticmethod def generate_from_brushes(context): exclude_filter = {} - if not context.preferences.experimental.use_sculpt_vertex_colors: + # Use 'bpy.context' instead of 'context' since it can be None. + prefs = bpy.context.preferences + if not prefs.experimental.use_sculpt_vertex_colors: exclude_filter = {'PAINT', 'SMEAR'} - if not context.preferences.experimental.use_tools_missing_icons: + if not prefs.experimental.use_tools_missing_icons: exclude_filter = {'PAINT', 'SMEAR', 'BOUNDARY', 'DISPLACEMENT_ERASER'} return generate_from_enum_ex( -- cgit v1.2.3 From 095142eae65820c8daf246def0866ac6accc9c87 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Sep 2020 10:37:42 +0200 Subject: Cleanup: use bool instead of int --- source/blender/blenkernel/intern/boids.c | 130 ++++++++++++++++--------------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index a7324ffe738..78ce70a8448 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -68,18 +68,18 @@ typedef struct BoidValues { float personal_space, jump_speed; } BoidValues; -static int apply_boid_rule( +static bool apply_boid_rule( BoidBrainData *bbd, BoidRule *rule, BoidValues *val, ParticleData *pa, float fuzziness); -static int rule_none(BoidRule *UNUSED(rule), - BoidBrainData *UNUSED(data), - BoidValues *UNUSED(val), - ParticleData *UNUSED(pa)) +static bool rule_none(BoidRule *UNUSED(rule), + BoidBrainData *UNUSED(data), + BoidValues *UNUSED(val), + ParticleData *UNUSED(pa)) { - return 0; + return false; } -static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa) +static bool rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa) { BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule; BoidSettings *boids = bbd->part->boids; @@ -91,7 +91,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, EffectorData efd, cur_efd; float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0); float priority = 0.0f, len = 0.0f; - int ret = 0; + bool ret = false; int p = 0; efd.index = cur_efd.index = &p; @@ -207,16 +207,16 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, } } - ret = 1; + ret = true; } return ret; } -static int rule_avoid_collision(BoidRule *rule, - BoidBrainData *bbd, - BoidValues *val, - ParticleData *pa) +static bool rule_avoid_collision(BoidRule *rule, + BoidBrainData *bbd, + BoidValues *val, + ParticleData *pa) { const int raycast_flag = BVH_RAYCAST_DEFAULT & ~BVH_RAYCAST_WATERTIGHT; BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision *)rule; @@ -228,7 +228,7 @@ static int rule_avoid_collision(BoidRule *rule, float co1[3], vel1[3], co2[3], vel2[3]; float len, t, inp, t_min = 2.0f; int n, neighbors = 0, nearest = 0; - int ret = 0; + bool ret = 0; // check deflector objects first if (acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) { @@ -288,7 +288,7 @@ static int rule_avoid_collision(BoidRule *rule, bbd->wanted_speed = sqrtf(t) * len_v3(pa->prev_state.vel); bbd->wanted_speed = MAX2(bbd->wanted_speed, val->min_speed); - return 1; + return true; } } @@ -413,10 +413,10 @@ static int rule_avoid_collision(BoidRule *rule, return ret; } -static int rule_separate(BoidRule *UNUSED(rule), - BoidBrainData *bbd, - BoidValues *val, - ParticleData *pa) +static bool rule_separate(BoidRule *UNUSED(rule), + BoidBrainData *bbd, + BoidValues *val, + ParticleData *pa) { KDTreeNearest_3d *ptn = NULL; ParticleTarget *pt; @@ -424,7 +424,7 @@ static int rule_separate(BoidRule *UNUSED(rule), float vec[3] = {0.0f, 0.0f, 0.0f}; int neighbors = BLI_kdtree_3d_range_search( bbd->sim->psys->tree, pa->prev_state.co, &ptn, 2.0f * val->personal_space * pa->size); - int ret = 0; + bool ret = false; if (neighbors > 1 && ptn[1].dist != 0.0f) { sub_v3_v3v3(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co); @@ -453,7 +453,7 @@ static int rule_separate(BoidRule *UNUSED(rule), add_v3_v3(bbd->wanted_co, vec); bbd->wanted_speed = val->max_speed; len = ptn[0].dist; - ret = 1; + ret = true; } if (ptn) { @@ -464,10 +464,10 @@ static int rule_separate(BoidRule *UNUSED(rule), } return ret; } -static int rule_flock(BoidRule *UNUSED(rule), - BoidBrainData *bbd, - BoidValues *UNUSED(val), - ParticleData *pa) +static bool rule_flock(BoidRule *UNUSED(rule), + BoidBrainData *bbd, + BoidValues *UNUSED(val), + ParticleData *pa) { KDTreeNearest_3d ptn[11]; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; @@ -479,7 +479,7 @@ static int rule_flock(BoidRule *UNUSED(rule), len_squared_v3v3_with_normal_bias, pa->prev_state.ave); int n; - int ret = 0; + bool ret = false; if (neighbors > 1) { for (n = 1; n < neighbors; n++) { @@ -497,20 +497,21 @@ static int rule_flock(BoidRule *UNUSED(rule), add_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = len_v3(bbd->wanted_co); - ret = 1; + ret = true; } return ret; } -static int rule_follow_leader(BoidRule *rule, - BoidBrainData *bbd, - BoidValues *val, - ParticleData *pa) +static bool rule_follow_leader(BoidRule *rule, + BoidBrainData *bbd, + BoidValues *val, + ParticleData *pa) { BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float mul, len; int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size; - int i, ret = 0, p = pa - bbd->sim->psys->particles; + int i, p = pa - bbd->sim->psys->particles; + bool ret = false; if (flbr->ob) { float vec2[3], t; @@ -530,7 +531,7 @@ static int rule_follow_leader(BoidRule *rule, if (len < 2.0f * val->personal_space * pa->size) { copy_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = val->max_speed; - return 1; + return true; } } else { @@ -548,7 +549,7 @@ static int rule_follow_leader(BoidRule *rule, if (len < 2.0f * val->personal_space * pa->size) { copy_v3_v3(bbd->wanted_co, vec2); bbd->wanted_speed = val->max_speed * (3.0f - t) / 3.0f; - return 1; + return true; } } } @@ -570,7 +571,7 @@ static int rule_follow_leader(BoidRule *rule, sub_v3_v3v3(bbd->wanted_co, loc, pa->prev_state.co); bbd->wanted_speed = len_v3(bbd->wanted_co); - ret = 1; + ret = true; } else if (p % n) { float vec2[3], t, t_min = 3.0f; @@ -590,7 +591,7 @@ static int rule_follow_leader(BoidRule *rule, if (len < 2.0f * val->personal_space * pa->size) { copy_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = val->max_speed; - return 1; + return true; } } else { @@ -609,14 +610,14 @@ static int rule_follow_leader(BoidRule *rule, t_min = t; copy_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = val->max_speed * (3.0f - t) / 3.0f; - ret = 1; + ret = true; } } } } if (ret) { - return 1; + return true; } /* not blocking so try to follow leader */ @@ -635,15 +636,15 @@ static int rule_follow_leader(BoidRule *rule, sub_v3_v3v3(bbd->wanted_co, loc, pa->prev_state.co); bbd->wanted_speed = len_v3(bbd->wanted_co); - ret = 1; + ret = true; } return ret; } -static int rule_average_speed(BoidRule *rule, - BoidBrainData *bbd, - BoidValues *val, - ParticleData *pa) +static bool rule_average_speed(BoidRule *rule, + BoidBrainData *bbd, + BoidValues *val, + ParticleData *pa) { BoidParticle *bpa = pa->boid; BoidRuleAverageSpeed *asbr = (BoidRuleAverageSpeed *)rule; @@ -693,9 +694,9 @@ static int rule_average_speed(BoidRule *rule, } bbd->wanted_speed = asbr->speed * val->max_speed; - return 1; + return true; } -static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa) +static bool rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa) { BoidRuleFight *fbr = (BoidRuleFight *)rule; KDTreeNearest_3d *ptn = NULL; @@ -708,7 +709,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti float closest_dist = fbr->distance + 1.0f; float f_strength = 0.0f, e_strength = 0.0f; float health = 0.0f; - int n, ret = 0; + int n; + bool ret = false; /* calculate own group strength */ int neighbors = BLI_kdtree_3d_range_search( @@ -799,16 +801,16 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti } } - ret = 1; + ret = true; } return ret; } -typedef int (*boid_rule_cb)(BoidRule *rule, - BoidBrainData *data, - BoidValues *val, - ParticleData *pa); +typedef bool (*boid_rule_cb)(BoidRule *rule, + BoidBrainData *data, + BoidValues *val, + ParticleData *pa); static boid_rule_cb boid_rules[] = { rule_none, @@ -957,24 +959,24 @@ static Object *boid_find_ground(BoidBrainData *bbd, ground_nor[2] = 1.0f; return NULL; } -static int boid_rule_applies(ParticleData *pa, BoidSettings *UNUSED(boids), BoidRule *rule) +static bool boid_rule_applies(ParticleData *pa, BoidSettings *UNUSED(boids), BoidRule *rule) { BoidParticle *bpa = pa->boid; if (rule == NULL) { - return 0; + return false; } if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND) { - return 1; + return true; } if (bpa->data.mode == eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR) { - return 1; + return true; } - return 0; + return false; } void boids_precalc_rules(ParticleSettings *part, float cfra) { @@ -1025,27 +1027,27 @@ static float boid_goal_signed_dist(float *boid_co, float *goal_co, float *goal_n return dot_v3v3(vec, goal_nor); } /* wanted_co is relative to boid location */ -static int apply_boid_rule( +static bool apply_boid_rule( BoidBrainData *bbd, BoidRule *rule, BoidValues *val, ParticleData *pa, float fuzziness) { if (rule == NULL) { - return 0; + return false; } - if (boid_rule_applies(pa, bbd->part->boids, rule) == 0) { - return 0; + if (!boid_rule_applies(pa, bbd->part->boids, rule)) { + return false; } - if (boid_rules[rule->type](rule, bbd, val, pa) == 0) { - return 0; + if (!boid_rules[rule->type](rule, bbd, val, pa)) { + return false; } if (fuzziness < 0.0f || compare_len_v3v3(bbd->wanted_co, pa->prev_state.vel, fuzziness * len_v3(pa->prev_state.vel)) == 0) { - return 1; + return true; } - return 0; + return false; } static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa) { -- cgit v1.2.3 From 916497627ce07318bb9bc82aabcb42af9561c560 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Sep 2020 10:44:46 +0200 Subject: Cleanup: use bool instead of int --- source/blender/blenkernel/BKE_armature.h | 2 +- source/blender/blenkernel/intern/CCGSubSurf_inline.h | 6 +++--- source/blender/blenkernel/intern/CCGSubSurf_legacy.c | 6 +++--- source/blender/blenkernel/intern/armature.c | 8 ++++---- source/blender/blenkernel/intern/blendfile.c | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 7c5d0011465..8164d34f32b 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -83,7 +83,7 @@ struct BoundBox *BKE_armature_boundbox_get(struct Object *ob); bool BKE_pose_minmax( struct Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select); -int bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail); +bool bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail); struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name); diff --git a/source/blender/blenkernel/intern/CCGSubSurf_inline.h b/source/blender/blenkernel/intern/CCGSubSurf_inline.h index 8aa1fede57d..91a7129b433 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_inline.h +++ b/source/blender/blenkernel/intern/CCGSubSurf_inline.h @@ -213,15 +213,15 @@ BLI_INLINE void Normalize(float no[3]) /* Data layers mathematics. */ -BLI_INLINE int VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss) +BLI_INLINE bool VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss) { int i; for (i = 0; i < ss->meshIFC.numLayers; i++) { if (a[i] != b[i]) { - return 0; + return false; } } - return 1; + return true; } BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss) diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c index 8fc9afd58f1..b723d39ca08 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c @@ -47,15 +47,15 @@ static int _edge_isBoundary(const CCGEdge *e) return e->numFaces < 2; } -static int _vert_isBoundary(const CCGVert *v) +static bool _vert_isBoundary(const CCGVert *v) { int i; for (i = 0; i < v->numEdges; i++) { if (_edge_isBoundary(v->edges[i])) { - return 1; + return true; } } - return 0; + return false; } static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 3b73702cf0f..a653087f961 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -565,7 +565,7 @@ void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmatu * unique names afterwards) strip_number: removes number extensions (TODO: not used) * axis: the axis to name on * head/tail: the head/tail co-ordinate of the bone on the specified axis */ -int bone_autoside_name( +bool bone_autoside_name( char name[MAXBONENAME], int UNUSED(strip_number), short axis, float head, float tail) { unsigned int len; @@ -574,7 +574,7 @@ int bone_autoside_name( len = strlen(name); if (len == 0) { - return 0; + return false; } BLI_strncpy(basename, name, sizeof(basename)); @@ -689,9 +689,9 @@ int bone_autoside_name( BLI_snprintf(name, MAXBONENAME, "%s.%s", basename, extension); - return 1; + return true; } - return 0; + return false; } /** \} */ diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index ee60bf79611..4ea8ae555e3 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -413,7 +413,7 @@ static void setup_app_blend_file_data(bContext *C, } } -static int handle_subversion_warning(Main *main, ReportList *reports) +static bool handle_subversion_warning(Main *main, ReportList *reports) { if (main->minversionfile > BLENDER_FILE_VERSION || (main->minversionfile == BLENDER_FILE_VERSION && @@ -425,7 +425,7 @@ static int handle_subversion_warning(Main *main, ReportList *reports) main->minsubversionfile); } - return 1; + return true; } int BKE_blendfile_read(bContext *C, @@ -443,7 +443,7 @@ int BKE_blendfile_read(bContext *C, bfd = BLO_read_from_file(filepath, params->skip_flags, reports); if (bfd) { - if (0 == handle_subversion_warning(bfd->main, reports)) { + if (!handle_subversion_warning(bfd->main, reports)) { BKE_main_free(bfd->main); MEM_freeN(bfd); bfd = NULL; -- cgit v1.2.3 From 377a1e3d7b7f108c5feff24dc2adb5ef7c402989 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Sep 2020 11:10:38 +0200 Subject: Cleanup: use bool instead of int --- source/blender/blenkernel/intern/dynamicpaint.c | 4 +-- source/blender/blenkernel/intern/seqprefetch.c | 2 +- .../blender/editors/gpencil/editaction_gpencil.c | 34 +++++++++++----------- source/blender/editors/include/ED_gpencil.h | 2 +- source/blender/editors/include/ED_mask.h | 4 +-- source/blender/editors/mask/mask_editaction.c | 18 ++++++------ source/blender/editors/mesh/meshtools.c | 9 +++--- source/blender/python/intern/bpy_rna_gizmo.c | 4 +-- source/blender/python/intern/bpy_rna_gizmo.h | 2 +- 9 files changed, 40 insertions(+), 39 deletions(-) diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index dff7dca4d76..50c9ce4fb75 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -306,12 +306,12 @@ static Mesh *dynamicPaint_brush_mesh_get(DynamicPaintBrushSettings *brush) /***************************** General Utils ******************************/ /* Set canvas error string to display at the bake report */ -static int setError(DynamicPaintCanvasSettings *canvas, const char *string) +static bool setError(DynamicPaintCanvasSettings *canvas, const char *string) { /* Add error to canvas ui info label */ BLI_strncpy(canvas->error, string, sizeof(canvas->error)); CLOG_STR_ERROR(&LOG, string); - return 0; + return false; } /* Get number of surface points for cached types */ diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c index 3a7e4af490a..013abb716d4 100644 --- a/source/blender/blenkernel/intern/seqprefetch.c +++ b/source/blender/blenkernel/intern/seqprefetch.c @@ -483,7 +483,7 @@ static void *seq_prefetch_frames(void *job) pfjob->running = false; pfjob->scene_eval->ed->prefetch_job = NULL; - return 0; + return NULL; } static PrefetchJob *seq_prefetch_start(const SeqRenderData *context, float cfra) diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index 752b8a74f4f..897a6e9653d 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -58,7 +58,7 @@ /* Loops over the gp-frames for a gp-layer, and applies the given callback */ bool ED_gpencil_layer_frames_looper(bGPDlayer *gpl, Scene *scene, - short (*gpf_cb)(bGPDframe *, Scene *)) + bool (*gpf_cb)(bGPDframe *, Scene *)) { /* error checker */ if (gpl == NULL) { @@ -511,40 +511,40 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode) /* -------------------------------------- */ /* Snap Tools */ -static short gpencil_frame_snap_nearest(bGPDframe *UNUSED(gpf), Scene *UNUSED(scene)) +static bool gpencil_frame_snap_nearest(bGPDframe *UNUSED(gpf), Scene *UNUSED(scene)) { #if 0 /* note: gpf->framenum is already an int! */ if (gpf->flag & GP_FRAME_SELECT) { gpf->framenum = (int)(floor(gpf->framenum + 0.5)); } #endif - return 0; + return false; } -static short gpencil_frame_snap_nearestsec(bGPDframe *gpf, Scene *scene) +static bool gpencil_frame_snap_nearestsec(bGPDframe *gpf, Scene *scene) { float secf = (float)FPS; if (gpf->flag & GP_FRAME_SELECT) { gpf->framenum = (int)(floorf(gpf->framenum / secf + 0.5f) * secf); } - return 0; + return false; } -static short gpencil_frame_snap_cframe(bGPDframe *gpf, Scene *scene) +static bool gpencil_frame_snap_cframe(bGPDframe *gpf, Scene *scene) { if (gpf->flag & GP_FRAME_SELECT) { gpf->framenum = (int)CFRA; } - return 0; + return false; } -static short gpencil_frame_snap_nearmarker(bGPDframe *gpf, Scene *scene) +static bool gpencil_frame_snap_nearmarker(bGPDframe *gpf, Scene *scene) { if (gpf->flag & GP_FRAME_SELECT) { gpf->framenum = (int)ED_markers_find_nearest_marker_time(&scene->markers, (float)gpf->framenum); } - return 0; + return false; } /* snap selected frames to ... */ @@ -571,7 +571,7 @@ void ED_gpencil_layer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode) /* -------------------------------------- */ /* Mirror Tools */ -static short gpencil_frame_mirror_cframe(bGPDframe *gpf, Scene *scene) +static bool gpencil_frame_mirror_cframe(bGPDframe *gpf, Scene *scene) { int diff; @@ -580,10 +580,10 @@ static short gpencil_frame_mirror_cframe(bGPDframe *gpf, Scene *scene) gpf->framenum = CFRA + diff; } - return 0; + return false; } -static short gpencil_frame_mirror_yaxis(bGPDframe *gpf, Scene *UNUSED(scene)) +static bool gpencil_frame_mirror_yaxis(bGPDframe *gpf, Scene *UNUSED(scene)) { int diff; @@ -592,10 +592,10 @@ static short gpencil_frame_mirror_yaxis(bGPDframe *gpf, Scene *UNUSED(scene)) gpf->framenum = diff; } - return 0; + return false; } -static short gpencil_frame_mirror_xaxis(bGPDframe *gpf, Scene *UNUSED(scene)) +static bool gpencil_frame_mirror_xaxis(bGPDframe *gpf, Scene *UNUSED(scene)) { int diff; @@ -605,10 +605,10 @@ static short gpencil_frame_mirror_xaxis(bGPDframe *gpf, Scene *UNUSED(scene)) gpf->framenum = diff; } - return 0; + return false; } -static short gpencil_frame_mirror_marker(bGPDframe *gpf, Scene *scene) +static bool gpencil_frame_mirror_marker(bGPDframe *gpf, Scene *scene) { static TimeMarker *marker; static short initialized = 0; @@ -645,7 +645,7 @@ static short gpencil_frame_mirror_marker(bGPDframe *gpf, Scene *scene) } } - return 0; + return false; } /* mirror selected gp-frames on... */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 06839276027..398a1630cf6 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -176,7 +176,7 @@ void ED_annotation_draw_ex(struct Scene *scene, /* ----------- Grease-Pencil AnimEdit API ------------------ */ bool ED_gpencil_layer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, - short (*gpf_cb)(struct bGPDframe *, struct Scene *)); + bool (*gpf_cb)(struct bGPDframe *, struct Scene *)); void ED_gpencil_layer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, bool onlysel); bool ED_gpencil_layer_frame_select_check(struct bGPDlayer *gpl); diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 80510d3afa1..f683495608a 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -91,8 +91,8 @@ bool ED_mask_layer_shape_auto_key_select(struct Mask *mask, const int frame); /* ----------- Mask AnimEdit API ------------------ */ bool ED_masklayer_frames_looper(struct MaskLayer *mask_layer, struct Scene *scene, - short (*mask_layer_shape_cb)(struct MaskLayerShape *, - struct Scene *)); + bool (*mask_layer_shape_cb)(struct MaskLayerShape *, + struct Scene *)); void ED_masklayer_make_cfra_list(struct MaskLayer *mask_layer, ListBase *elems, bool onlysel); bool ED_masklayer_frame_select_check(struct MaskLayer *mask_layer); diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c index af99df4c5d8..1792f0e13bc 100644 --- a/source/blender/editors/mask/mask_editaction.c +++ b/source/blender/editors/mask/mask_editaction.c @@ -55,7 +55,7 @@ /* Loops over the mask-frames for a mask-layer, and applies the given callback */ bool ED_masklayer_frames_looper(MaskLayer *mask_layer, Scene *scene, - short (*mask_layer_shape_cb)(MaskLayerShape *, Scene *)) + bool (*mask_layer_shape_cb)(MaskLayerShape *, Scene *)) { MaskLayerShape *mask_layer_shape; @@ -310,38 +310,38 @@ void ED_masklayer_frames_duplicate(MaskLayer *mask_layer) /* -------------------------------------- */ /* Snap Tools */ -static short snap_mask_layer_nearest(MaskLayerShape *mask_layer_shape, Scene *UNUSED(scene)) +static bool snap_mask_layer_nearest(MaskLayerShape *mask_layer_shape, Scene *UNUSED(scene)) { if (mask_layer_shape->flag & MASK_SHAPE_SELECT) { mask_layer_shape->frame = (int)(floor(mask_layer_shape->frame + 0.5)); } - return 0; + return false; } -static short snap_mask_layer_nearestsec(MaskLayerShape *mask_layer_shape, Scene *scene) +static bool snap_mask_layer_nearestsec(MaskLayerShape *mask_layer_shape, Scene *scene) { float secf = (float)FPS; if (mask_layer_shape->flag & MASK_SHAPE_SELECT) { mask_layer_shape->frame = (int)(floorf(mask_layer_shape->frame / secf + 0.5f) * secf); } - return 0; + return false; } -static short snap_mask_layer_cframe(MaskLayerShape *mask_layer_shape, Scene *scene) +static bool snap_mask_layer_cframe(MaskLayerShape *mask_layer_shape, Scene *scene) { if (mask_layer_shape->flag & MASK_SHAPE_SELECT) { mask_layer_shape->frame = (int)CFRA; } - return 0; + return false; } -static short snap_mask_layer_nearmarker(MaskLayerShape *mask_layer_shape, Scene *scene) +static bool snap_mask_layer_nearmarker(MaskLayerShape *mask_layer_shape, Scene *scene) { if (mask_layer_shape->flag & MASK_SHAPE_SELECT) { mask_layer_shape->frame = (int)ED_markers_find_nearest_marker_time( &scene->markers, (float)mask_layer_shape->frame); } - return 0; + return false; } /* snap selected frames to ... */ diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index bd14919d1d7..471d4847af6 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -891,7 +891,8 @@ void ED_mesh_mirror_topo_table_end(Object *UNUSED(ob)) ED_mesh_mirrtopo_free(&mesh_topo_store); } -static int ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval) +/* Returns true on success. */ +static bool ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval) { Mesh *me_mirror; BMEditMesh *em_mirror; @@ -900,7 +901,7 @@ static int ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval) if (ED_mesh_mirrtopo_recalc_check(em_mirror, me_mirror, &mesh_topo_store)) { ED_mesh_mirror_topo_table_begin(ob, me_eval); } - return 0; + return true; } /** \} */ @@ -921,7 +922,7 @@ static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *me_eval, int index) static int mesh_get_x_mirror_vert_topo(Object *ob, Mesh *mesh, int index) { - if (ed_mesh_mirror_topo_table_update(ob, mesh) == -1) { + if (!ed_mesh_mirror_topo_table_update(ob, mesh)) { return -1; } @@ -963,7 +964,7 @@ static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob, int index) { intptr_t poinval; - if (ed_mesh_mirror_topo_table_update(ob, NULL) == -1) { + if (!ed_mesh_mirror_topo_table_update(ob, NULL)) { return NULL; } diff --git a/source/blender/python/intern/bpy_rna_gizmo.c b/source/blender/python/intern/bpy_rna_gizmo.c index 575824e8a86..542d014f8b2 100644 --- a/source/blender/python/intern/bpy_rna_gizmo.c +++ b/source/blender/python/intern/bpy_rna_gizmo.c @@ -507,7 +507,7 @@ fail: /** \} */ -int BPY_rna_gizmo_module(PyObject *mod_par) +bool BPY_rna_gizmo_module(PyObject *mod_par) { static PyMethodDef method_def_array[] = { /* Gizmo Target Property Define API */ @@ -541,5 +541,5 @@ int BPY_rna_gizmo_module(PyObject *mod_par) PyModule_AddObject(mod_par, name_prefix, func_inst); } - return 0; + return false; } diff --git a/source/blender/python/intern/bpy_rna_gizmo.h b/source/blender/python/intern/bpy_rna_gizmo.h index 307b694338c..e4ac43bfe6c 100644 --- a/source/blender/python/intern/bpy_rna_gizmo.h +++ b/source/blender/python/intern/bpy_rna_gizmo.h @@ -24,7 +24,7 @@ extern "C" { #endif -int BPY_rna_gizmo_module(PyObject *); +bool BPY_rna_gizmo_module(PyObject *); #ifdef __cplusplus } -- cgit v1.2.3 From d51c8f78ff8a210675dae44048156c23e3793508 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Wed, 9 Sep 2020 11:46:40 +0200 Subject: Fix T80596: Convert to Curve from Mesh crashes Blender The point cache code needs a non NULL rbw pointer. This could have been avoided if there was a sanity check in the convert function, so added a check there as well. --- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/blenkernel/intern/rigidbody.c | 14 +++++++------- source/blender/editors/object/object_add.c | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 8c5915d3768..6b433e5edaa 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1848,7 +1848,7 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r memset(pid, 0, sizeof(PTCacheID)); - pid->owner_id = &ob->id; + pid->owner_id = ob != NULL ? &ob->id : NULL; pid->calldata = rbw; pid->type = PTCACHE_TYPE_RIGIDBODY; pid->cache = rbw->shared->pointcache; diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 7eab716d805..0a31af032d3 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1554,18 +1554,18 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bo BKE_collection_object_add(bmain, scene->master_collection, ob); } BKE_collection_object_remove(bmain, rbw->group, ob, free_us); + + /* flag cache as outdated */ + BKE_rigidbody_cache_reset(rbw); + /* Reset cache as the object order probably changed after freeing the object. */ + PTCacheID pid; + BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw); + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); } /* remove object's settings */ BKE_rigidbody_free_object(ob, rbw); - /* flag cache as outdated */ - BKE_rigidbody_cache_reset(rbw); - /* Reset cache as the object order probably changed after freeing the object. */ - PTCacheID pid; - BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw); - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - /* Dependency graph update */ DEG_relations_tag_update(bmain); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index bfb13fb99bf..482ae4019c3 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2572,7 +2572,9 @@ static int object_convert_exec(bContext *C, wmOperator *op) if (newob->type == OB_CURVE) { BKE_object_free_modifiers(newob, 0); /* after derivedmesh calls! */ - ED_rigidbody_object_remove(bmain, scene, newob); + if (newob->rigidbody_object != NULL) { + ED_rigidbody_object_remove(bmain, scene, newob); + } } } else if (ob->type == OB_MESH && target == OB_GPENCIL) { -- cgit v1.2.3 From dbec51109bbd3a6143bc45c6faa3908142f9da46 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Sep 2020 12:06:11 +0200 Subject: Fix T80613: Assert in UI_but_number_precision_set -1 is a valid value to pass as RNA float precision. We let the UI code figure out an appropriate precision then. So don't fail the assert if -1 is passed. --- source/blender/editors/interface/interface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index bbe097b5c79..ea64fb9cfcd 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -6762,7 +6762,8 @@ void UI_but_number_precision_set(uiBut *but, float precision) BLI_assert(but->type == UI_BTYPE_NUM); but_number->precision = precision; - BLI_assert(precision > -1); + /* -1 is a valid value, UI code figures out an appropriate precision then. */ + BLI_assert(precision > -2); } /** -- cgit v1.2.3 From 4ccd5bf5c6581c3dd93e684cacfb87c103339572 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2020 20:38:33 +1000 Subject: Fix T80626: Crash adding custom-data layers after reloading the file Regression in a48d78ce07f4f which caused the meshes CustomData to be written before it's layer values were updated for writing. --- source/blender/blenkernel/BKE_customdata.h | 11 ++++--- source/blender/blenkernel/intern/customdata.c | 27 ++++++++-------- source/blender/blenkernel/intern/mesh.c | 44 ++++++++++++++++++++++++--- source/blender/blenloader/intern/writefile.c | 34 ++++++++++++++++++--- 4 files changed, 88 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 25360d4b3fa..d21fe5afa7e 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -414,11 +414,6 @@ void CustomData_from_bmesh_block(const struct CustomData *source, void *src_block, int dest_index); -void CustomData_file_write_prepare(struct CustomData *data, - struct CustomDataLayer **r_write_layers, - struct CustomDataLayer *write_layers_buff, - size_t write_layers_size); - /* query info over types */ void CustomData_file_write_info(int type, const char **r_struct_name, int *r_struct_num); int CustomData_sizeof(int type); @@ -574,8 +569,14 @@ void CustomData_data_transfer(const struct MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap); /* .blend file I/O */ +void CustomData_blend_write_prepare(struct CustomData *data, + struct CustomDataLayer **r_write_layers, + struct CustomDataLayer *write_layers_buff, + size_t write_layers_size); + void CustomData_blend_write(struct BlendWriter *writer, struct CustomData *data, + CustomDataLayer *layers, int count, CustomDataMask cddata_mask, struct ID *id); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 5a5fb7a36df..e2adaabca33 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -4342,10 +4342,10 @@ void CustomData_file_write_info(int type, const char **r_struct_name, int *r_str * This means written typemap does not match written layers (as returned by \a r_write_layers). * Trivial to fix is ever needed. */ -void CustomData_file_write_prepare(CustomData *data, - CustomDataLayer **r_write_layers, - CustomDataLayer *write_layers_buff, - size_t write_layers_size) +void CustomData_blend_write_prepare(CustomData *data, + CustomDataLayer **r_write_layers, + CustomDataLayer *write_layers_buff, + size_t write_layers_size) { CustomDataLayer *write_layers = write_layers_buff; const size_t chunk_size = (write_layers_size > 0) ? write_layers_size : CD_TEMP_CHUNK_SIZE; @@ -5193,13 +5193,16 @@ static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask } } -void CustomData_blend_write( - BlendWriter *writer, CustomData *data, int count, CustomDataMask cddata_mask, ID *id) +/** + * \param layers: The layers argument assigned by #CustomData_blend_write_prepare. + */ +void CustomData_blend_write(BlendWriter *writer, + CustomData *data, + CustomDataLayer *layers, + int count, + CustomDataMask cddata_mask, + ID *id) { - CustomDataLayer *layers = NULL; - CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE]; - CustomData_file_write_prepare(data, &layers, layers_buff, ARRAY_SIZE(layers_buff)); - /* write external customdata (not for undo) */ if (data->external && !BLO_write_is_undo(writer)) { CustomData_external_write(data, id, cddata_mask, count, 0); @@ -5252,10 +5255,6 @@ void CustomData_blend_write( if (data->external) { BLO_write_struct(writer, CustomDataExternal, data->external); } - - if (!ELEM(layers, NULL, layers_buff)) { - MEM_freeN(layers); - } } static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index a7568bcd6ea..0e6ef50f491 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -180,6 +180,18 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address memset(&mesh->fdata, 0, sizeof(mesh->fdata)); memset(&mesh->runtime, 0, sizeof(mesh->runtime)); + CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *llayers = NULL, llayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; + + CustomData_blend_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); + CustomData_blend_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); + flayers = flayers_buff; + CustomData_blend_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); + CustomData_blend_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); + BLO_write_id_struct(writer, Mesh, id_address, &mesh->id); BKE_id_blend_write(writer, &mesh->id); @@ -191,12 +203,34 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address BLO_write_pointer_array(writer, mesh->totcol, mesh->mat); BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect); - CustomData_blend_write(writer, &mesh->vdata, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id); - CustomData_blend_write(writer, &mesh->edata, mesh->totedge, CD_MASK_MESH.emask, &mesh->id); + CustomData_blend_write( + writer, &mesh->vdata, vlayers, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id); + CustomData_blend_write( + writer, &mesh->edata, elayers, mesh->totedge, CD_MASK_MESH.emask, &mesh->id); /* fdata is really a dummy - written so slots align */ - CustomData_blend_write(writer, &mesh->fdata, mesh->totface, CD_MASK_MESH.fmask, &mesh->id); - CustomData_blend_write(writer, &mesh->ldata, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id); - CustomData_blend_write(writer, &mesh->pdata, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id); + CustomData_blend_write( + writer, &mesh->fdata, flayers, mesh->totface, CD_MASK_MESH.fmask, &mesh->id); + CustomData_blend_write( + writer, &mesh->ldata, llayers, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id); + CustomData_blend_write( + writer, &mesh->pdata, players, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id); + + /* Free temporary data */ + +/* Free custom-data layers, when not assigned a buffer value. */ +#define CD_LAYERS_FREE(id) \ + if (id && id != id##_buff) { \ + MEM_freeN(id); \ + } \ + ((void)0) + + CD_LAYERS_FREE(vlayers); + CD_LAYERS_FREE(elayers); + /* CD_LAYER_FREE(flayers); */ /* Never allocated. */ + CD_LAYERS_FREE(llayers); + CD_LAYERS_FREE(players); + +#undef CD_LAYERS_FREE } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index a9c92719a33..7b089ec0f8f 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -3263,17 +3263,31 @@ static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const voi static void write_hair(BlendWriter *writer, Hair *hair, const void *id_address) { if (hair->id.us > 0 || BLO_write_is_undo(writer)) { + CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomData_blend_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); + CustomData_blend_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff)); + /* Write LibData */ BLO_write_id_struct(writer, Hair, id_address, &hair->id); BKE_id_blend_write(writer, &hair->id); /* Direct data */ - CustomData_blend_write(writer, &hair->pdata, hair->totpoint, CD_MASK_ALL, &hair->id); - CustomData_blend_write(writer, &hair->cdata, hair->totcurve, CD_MASK_ALL, &hair->id); + CustomData_blend_write(writer, &hair->pdata, players, hair->totpoint, CD_MASK_ALL, &hair->id); + CustomData_blend_write(writer, &hair->cdata, clayers, hair->totcurve, CD_MASK_ALL, &hair->id); + BLO_write_pointer_array(writer, hair->totcol, hair->mat); if (hair->adt) { BKE_animdata_blend_write(writer, hair->adt); } + + /* Remove temporary data. */ + if (players && players != players_buff) { + MEM_freeN(players); + } + if (clayers && clayers != clayers_buff) { + MEM_freeN(clayers); + } } } @@ -3281,7 +3295,7 @@ static void write_pointcloud(BlendWriter *writer, PointCloud *pointcloud, const { if (pointcloud->id.us > 0 || BLO_write_is_undo(writer)) { CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; - CustomData_file_write_prepare( + CustomData_blend_write_prepare( &pointcloud->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); /* Write LibData */ @@ -3290,7 +3304,8 @@ static void write_pointcloud(BlendWriter *writer, PointCloud *pointcloud, const /* Direct data */ CustomData_blend_write( - writer, &pointcloud->pdata, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id); + writer, &pointcloud->pdata, players, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id); + BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat); if (pointcloud->adt) { BKE_animdata_blend_write(writer, pointcloud->adt); @@ -3349,13 +3364,24 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const /* TODO: Decentralize this part. */ if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) { ParticleSimulationState *particle_state = (ParticleSimulationState *)state; + + CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; + CustomData_blend_write_prepare( + &particle_state->attributes, &players, players_buff, ARRAY_SIZE(players_buff)); + BLO_write_struct(writer, ParticleSimulationState, particle_state); CustomData_blend_write(writer, &particle_state->attributes, + players, particle_state->tot_particles, CD_MASK_ALL, &simulation->id); + + /* Remove temporary data. */ + if (players && players != players_buff) { + MEM_freeN(players); + } } else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) { ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *) -- cgit v1.2.3 From 45bd8fdc2b086e994fa3e907a64e587013112603 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Sep 2020 13:40:14 +0200 Subject: BLI: new string search api that supports fuzzy and prefix matching This adds a generic string search library in `BLI_string_search.h`. The library has a simple to use C api that allows it's users to filter and sort a set of possible search results based on some query string. Reviewers: Severin Differential Revision: https://developer.blender.org/D8825 --- source/blender/blenlib/BLI_string_search.h | 51 +++ source/blender/blenlib/CMakeLists.txt | 3 + source/blender/blenlib/intern/string_search.cc | 475 +++++++++++++++++++++ .../blenlib/tests/BLI_string_search_test.cc | 50 +++ 4 files changed, 579 insertions(+) create mode 100644 source/blender/blenlib/BLI_string_search.h create mode 100644 source/blender/blenlib/intern/string_search.cc create mode 100644 source/blender/blenlib/tests/BLI_string_search_test.cc diff --git a/source/blender/blenlib/BLI_string_search.h b/source/blender/blenlib/BLI_string_search.h new file mode 100644 index 00000000000..8057e5b75cb --- /dev/null +++ b/source/blender/blenlib/BLI_string_search.h @@ -0,0 +1,51 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct StringSearch StringSearch; + +StringSearch *BLI_string_search_new(void); +void BLI_string_search_add(StringSearch *search, const char *str, void *user_data); +int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data); +void BLI_string_search_free(StringSearch *search); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +# include "BLI_linear_allocator.hh" +# include "BLI_span.hh" +# include "BLI_string_ref.hh" +# include "BLI_vector.hh" + +namespace blender::string_search { + +int damerau_levenshtein_distance(StringRef a, StringRef b); +int get_fuzzy_match_errors(StringRef query, StringRef full); +void extract_normalized_words(StringRef str, + LinearAllocator<> &allocator, + Vector &r_words); + +} // namespace blender::string_search + +#endif diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index a0569ad3dd4..e01459ac80e 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -124,6 +124,7 @@ set(SRC intern/storage.c intern/string.c intern/string_cursor_utf8.c + intern/string_search.cc intern/string_utf8.c intern/string_utils.c intern/system.c @@ -267,6 +268,7 @@ set(SRC BLI_strict_flags.h BLI_string.h BLI_string_cursor_utf8.h + BLI_string_search.h BLI_string_ref.hh BLI_string_utf8.h BLI_string_utils.h @@ -411,6 +413,7 @@ if(WITH_GTESTS) tests/BLI_span_test.cc tests/BLI_stack_cxx_test.cc tests/BLI_stack_test.cc + tests/BLI_string_search_test.cc tests/BLI_string_ref_test.cc tests/BLI_string_test.cc tests/BLI_string_utf8_test.cc diff --git a/source/blender/blenlib/intern/string_search.cc b/source/blender/blenlib/intern/string_search.cc new file mode 100644 index 00000000000..17da3b9f493 --- /dev/null +++ b/source/blender/blenlib/intern/string_search.cc @@ -0,0 +1,475 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "BLI_array.hh" +#include "BLI_linear_allocator.hh" +#include "BLI_multi_value_map.hh" +#include "BLI_span.hh" +#include "BLI_string.h" +#include "BLI_string_ref.hh" +#include "BLI_string_search.h" +#include "BLI_string_utf8.h" +#include "BLI_timeit.hh" + +namespace blender::string_search { + +static int64_t count_utf8_code_points(StringRef str) +{ + return static_cast(BLI_strnlen_utf8(str.data(), static_cast(str.size()))); +} + +/** + * Computes the cost of transforming string a into b. The cost/distance is the minimal number of + * operations that need to be executed. Valid operations are deletion, insertion, substitution and + * transposition. + * + * This function is utf8 aware in the sense that it works at the level of individual code points + * (1-4 bytes long) instead of on individual bytes. + */ +int damerau_levenshtein_distance(StringRef a, StringRef b) +{ + constexpr int deletion_cost = 1; + constexpr int insertion_cost = 1; + constexpr int substitution_cost = 1; + constexpr int transposition_cost = 1; + + const int size_a = count_utf8_code_points(a); + const int size_b = count_utf8_code_points(b); + + /* Instead of keeping the entire table in memory, only keep three rows. The algorithm only + * accesses these rows and nothing older. + * All three rows are usually allocated on the stack. At most a single heap allocation is done, + * if the reserved stack space is too small. */ + const int row_length = size_b + 1; + Array rows(row_length * 3); + + /* Store rows as spans so that it is cheap to swap them. */ + MutableSpan v0{rows.data() + row_length * 0, row_length}; + MutableSpan v1{rows.data() + row_length * 1, row_length}; + MutableSpan v2{rows.data() + row_length * 2, row_length}; + + /* Only v1 needs to be initialized. */ + for (const int i : IndexRange(row_length)) { + v1[i] = i * insertion_cost; + } + + uint32_t prev_unicode_a; + size_t offset_a = 0; + for (const int i : IndexRange(size_a)) { + v2[0] = (i + 1) * deletion_cost; + + const uint32_t unicode_a = BLI_str_utf8_as_unicode_and_size(a.data() + offset_a, &offset_a); + + uint32_t prev_unicode_b; + size_t offset_b = 0; + for (const int j : IndexRange(size_b)) { + const uint32_t unicode_b = BLI_str_utf8_as_unicode_and_size(b.data() + offset_b, &offset_b); + + /* Check how costly the different operations would be and pick the cheapest - the one with + * minimal cost. */ + int new_cost = std::min({v1[j + 1] + deletion_cost, + v2[j] + insertion_cost, + v1[j] + (unicode_a != unicode_b) * substitution_cost}); + if (i > 0 && j > 0) { + if (unicode_a == prev_unicode_b && prev_unicode_a == unicode_b) { + new_cost = std::min(new_cost, v0[j - 1] + transposition_cost); + } + } + + v2[j + 1] = new_cost; + prev_unicode_b = unicode_b; + } + + /* Swap the three rows, so that the next row can be computed. */ + std::tie(v0, v1, v2) = std::tuple, MutableSpan, MutableSpan>( + v1, v2, v0); + prev_unicode_a = unicode_a; + } + + return v1.last(); +} + +/** + * Returns -1 when this is no reasonably good match. + * Otherwise returns the number of errors in the match. + */ +int get_fuzzy_match_errors(StringRef query, StringRef full) +{ + /* If it is a perfect partial match, return immediatly. */ + if (full.find(query) != StringRef::not_found) { + return 0; + } + + const int query_size = count_utf8_code_points(query); + const int full_size = count_utf8_code_points(full); + + /* If there is only a single character which is not in the full string, this is not a match. */ + if (query_size == 1) { + return -1; + } + BLI_assert(query.size() >= 2); + + /* Allow more errors when the size grows larger. */ + const int max_errors = query_size <= 1 ? 0 : query_size / 8 + 1; + + /* If the query is too large, this cannot be a match. */ + if (query_size - full_size > max_errors) { + return -1; + } + + const uint32_t query_first_unicode = BLI_str_utf8_as_unicode(query.data()); + const uint32_t query_second_unicode = BLI_str_utf8_as_unicode(query.data() + + BLI_str_utf8_size(query.data())); + + const char *full_begin = full.begin(); + const char *full_end = full.end(); + + const char *window_begin = full_begin; + const char *window_end = window_begin; + const int window_size = std::min(query_size + max_errors, full_size); + const int extra_chars = window_size - query_size; + const int max_acceptable_distance = max_errors + extra_chars; + + for (int i = 0; i < window_size; i++) { + window_end += BLI_str_utf8_size(window_end); + } + + while (true) { + StringRef window{window_begin, window_end}; + const uint32_t window_begin_unicode = BLI_str_utf8_as_unicode(window_begin); + int distance = 0; + /* Expect that the first or second character of the query is correct. This helps to avoid + * computing the more expensive distance function. */ + if (ELEM(window_begin_unicode, query_first_unicode, query_second_unicode)) { + distance = damerau_levenshtein_distance(query, window); + if (distance <= max_acceptable_distance) { + return distance; + } + } + if (window_end == full_end) { + return -1; + } + + /* When the distance is way too large, we can skip a couple of code points, because the + * distance can't possibly become as short as required. */ + const int window_offset = std::max(1, distance / 2); + for (int i = 0; i < window_offset && window_end < full_end; i++) { + window_begin += BLI_str_utf8_size(window_begin); + window_end += BLI_str_utf8_size(window_end); + } + } +} + +/** + * Takes a query and tries to match it with the first characters of some words. For example, "msfv" + * matches "Mark Sharp from Vertices". Multiple letters of the beginning of a word can be matched + * as well. For example, "seboulo" matches "select boundary loop". The order of words is important. + * So "bose" does not match "select boundary". However, individual words can be skipped. For + * example, "rocc" matches "rotate edge ccw". + * + * Returns true when the match was successfull. If it was successfull, the used words are tagged in + * r_word_is_matched. + */ +static bool match_word_initials(StringRef query, + Span words, + Span word_is_usable, + MutableSpan r_word_is_matched, + int start = 0) +{ + if (start >= words.size()) { + return false; + } + + r_word_is_matched.fill(false); + + size_t query_index = 0; + int word_index = start; + size_t char_index = 0; + + int first_found_word_index = -1; + + while (query_index < query.size()) { + const uint query_unicode = BLI_str_utf8_as_unicode_and_size(query.data() + query_index, + &query_index); + while (true) { + /* We are at the end of words, no complete match has been found yet. */ + if (word_index >= words.size()) { + if (first_found_word_index >= 0) { + /* Try starting to match at another word. In some cases one can still find matches this + * way. */ + return match_word_initials( + query, words, word_is_usable, r_word_is_matched, first_found_word_index + 1); + } + return false; + } + + /* Skip words that the caller does not want us to use. */ + if (!word_is_usable[word_index]) { + word_index++; + BLI_assert(char_index == 0); + continue; + } + + StringRef word = words[word_index]; + /* Try to match the current character with the current word. */ + if (static_cast(char_index) < word.size()) { + const uint32_t char_unicode = BLI_str_utf8_as_unicode_and_size(word.data() + char_index, + &char_index); + if (query_unicode == char_unicode) { + r_word_is_matched[word_index] = true; + if (first_found_word_index == -1) { + first_found_word_index = word_index; + } + break; + } + } + + /* Could not find a match in the current word, go to the beginning of the next word. */ + word_index += 1; + char_index = 0; + } + } + return true; +} + +static int get_shortest_word_index_that_startswith(StringRef query, + Span words, + Span word_is_usable) +{ + int best_word_size = INT32_MAX; + int bset_word_index = -1; + for (const int i : words.index_range()) { + if (!word_is_usable[i]) { + continue; + } + StringRef word = words[i]; + if (word.startswith(query)) { + if (word.size() < best_word_size) { + bset_word_index = i; + } + } + } + return bset_word_index; +} + +static int get_word_index_that_fuzzy_matches(StringRef query, + Span words, + Span word_is_usable, + int *r_error_count) +{ + for (const int i : words.index_range()) { + if (!word_is_usable[i]) { + continue; + } + StringRef word = words[i]; + const int error_count = get_fuzzy_match_errors(query, word); + if (error_count >= 0) { + *r_error_count = error_count; + return i; + } + } + return -1; +} + +/** + * Checks how well the query matches a result. If it does not match, -1 is returned. A positive + * return value indicates how good the match is. The higher the value, the better the match. + */ +static int score_query_against_words(Span query_words, Span result_words) +{ + /* Remember which words have been matched, so that they are not matched again. */ + Array word_is_usable(result_words.size(), true); + + /* Start with some high score, because otherwise the final score might become negative. */ + int total_match_score = 1000; + + for (StringRef query_word : query_words) { + { + /* Check if any result word begins with the query word. */ + const int word_index = get_shortest_word_index_that_startswith( + query_word, result_words, word_is_usable); + if (word_index >= 0) { + total_match_score += 10; + word_is_usable[word_index] = false; + continue; + } + } + { + /* Try to match against word initials. */ + Array matched_words(result_words.size()); + const bool success = match_word_initials( + query_word, result_words, word_is_usable, matched_words); + if (success) { + total_match_score += 3; + for (const int i : result_words.index_range()) { + if (matched_words[i]) { + word_is_usable[i] = false; + } + } + continue; + } + } + { + /* Fuzzy match against words. */ + int error_count = 0; + const int word_index = get_word_index_that_fuzzy_matches( + query_word, result_words, word_is_usable, &error_count); + if (word_index >= 0) { + total_match_score += 3 - error_count; + word_is_usable[word_index] = false; + continue; + } + } + + /* Couldn't match query word with anything. */ + return -1; + } + + return total_match_score; +} + +/** + * Splits a string into words and normalizes them (currently that just means converting to lower + * case). The returned strings are allocated in the given allocator. + */ +void extract_normalized_words(StringRef str, + LinearAllocator<> &allocator, + Vector &r_words) +{ + const uint32_t unicode_space = BLI_str_utf8_as_unicode(" "); + const uint32_t unicode_right_triangle = BLI_str_utf8_as_unicode("▶"); + + auto is_separator = [&](uint32_t unicode) { + return ELEM(unicode, unicode_space, unicode_right_triangle); + }; + + /* Make a copy of the string so that we can edit it. */ + StringRef str_copy = allocator.copy_string(str); + char *mutable_copy = const_cast(str_copy.data()); + const size_t str_size_in_bytes = static_cast(str.size()); + BLI_str_tolower_ascii(mutable_copy, str_size_in_bytes); + + /* Iterate over all unicode code points to split individual words. */ + bool is_in_word = false; + size_t word_start = 0; + size_t offset = 0; + while (offset < str_size_in_bytes) { + size_t size = 0; + uint32_t unicode = BLI_str_utf8_as_unicode_and_size(str.data() + offset, &size); + if (is_separator(unicode)) { + if (is_in_word) { + r_words.append( + str_copy.substr(static_cast(word_start), static_cast(offset - word_start))); + is_in_word = false; + } + } + else { + if (!is_in_word) { + word_start = offset; + is_in_word = true; + } + } + offset += size; + } + /* If the last word is not followed by a separator, it has to be handld separately. */ + if (is_in_word) { + r_words.append(str_copy.drop_prefix(static_cast(word_start))); + } +} + +} // namespace blender::string_search + +struct SearchItem { + blender::Span normalized_words; + void *user_data; +}; + +struct StringSearch { + blender::LinearAllocator<> allocator; + blender::Vector items; +}; + +StringSearch *BLI_string_search_new() +{ + return new StringSearch(); +} + +/** + * Add a new possible result to the search. + * The caller keeps ownership of all parameters. + */ +void BLI_string_search_add(StringSearch *search, const char *str, void *user_data) +{ + using namespace blender; + Vector words; + string_search::extract_normalized_words(str, search->allocator, words); + search->items.append({search->allocator.construct_array_copy(words.as_span()), user_data}); +} + +/** + * Filter and sort all previously added search items. + * Returns an array containing the filtered user data. + * The caller has to free the returned array. + */ +int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data) +{ + using namespace blender; + + LinearAllocator<> allocator; + Vector query_words; + string_search::extract_normalized_words(query, allocator, query_words); + + /* Compute score of every result. */ + MultiValueMap result_indices_by_score; + for (const int result_index : search->items.index_range()) { + const int score = string_search::score_query_against_words( + query_words, search->items[result_index].normalized_words); + if (score >= 0) { + result_indices_by_score.add(score, result_index); + } + } + + Vector found_scores; + for (const int score : result_indices_by_score.keys()) { + found_scores.append(score); + } + std::sort(found_scores.begin(), found_scores.end(), std::greater()); + + /* Add results to output vector in correct order. First come the results with the best match + * score. Results with the same score are in the order they have been added to the search. */ + Vector sorted_result_indices; + for (const int score : found_scores) { + Span indices = result_indices_by_score.lookup(score); + sorted_result_indices.extend(indices); + } + + void **sorted_data = static_cast( + MEM_malloc_arrayN(static_cast(sorted_result_indices.size()), sizeof(void *), AT)); + for (const int i : sorted_result_indices.index_range()) { + const int result_index = sorted_result_indices[i]; + SearchItem &item = search->items[result_index]; + sorted_data[i] = item.user_data; + } + + *r_data = sorted_data; + + return sorted_result_indices.size(); +} + +void BLI_string_search_free(StringSearch *string_search) +{ + delete string_search; +} diff --git a/source/blender/blenlib/tests/BLI_string_search_test.cc b/source/blender/blenlib/tests/BLI_string_search_test.cc new file mode 100644 index 00000000000..0d1fd2cab96 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_string_search_test.cc @@ -0,0 +1,50 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "BLI_array.hh" +#include "BLI_string_search.h" +#include "BLI_vector.hh" + +namespace blender::string_search::tests { + +TEST(string_search, damerau_levenshtein_distance) +{ + EXPECT_EQ(damerau_levenshtein_distance("test", "test"), 0); + EXPECT_EQ(damerau_levenshtein_distance("hello", "ell"), 2); + EXPECT_EQ(damerau_levenshtein_distance("hello", "hel"), 2); + EXPECT_EQ(damerau_levenshtein_distance("ell", "hello"), 2); + EXPECT_EQ(damerau_levenshtein_distance("hell", "hello"), 1); + EXPECT_EQ(damerau_levenshtein_distance("hello", "hallo"), 1); + EXPECT_EQ(damerau_levenshtein_distance("test", ""), 4); + EXPECT_EQ(damerau_levenshtein_distance("", "hello"), 5); + EXPECT_EQ(damerau_levenshtein_distance("Test", "test"), 1); + EXPECT_EQ(damerau_levenshtein_distance("ab", "ba"), 1); + EXPECT_EQ(damerau_levenshtein_distance("what", "waht"), 1); + EXPECT_EQ(damerau_levenshtein_distance("what", "ahwt"), 2); +} + +TEST(string_search, get_fuzzy_match_errors) +{ + EXPECT_EQ(get_fuzzy_match_errors("a", "b"), -1); + EXPECT_EQ(get_fuzzy_match_errors("", "abc"), 0); + EXPECT_EQ(get_fuzzy_match_errors("hello", "hallo"), 1); + EXPECT_EQ(get_fuzzy_match_errors("hap", "hello"), -1); + EXPECT_EQ(get_fuzzy_match_errors("armature", "▶restore"), -1); +} + +TEST(string_search, extract_normalized_words) +{ + LinearAllocator<> allocator; + Vector words; + extract_normalized_words("hello world▶test another test▶ 3", allocator, words); + EXPECT_EQ(words.size(), 6); + EXPECT_EQ(words[0], "hello"); + EXPECT_EQ(words[1], "world"); + EXPECT_EQ(words[2], "test"); + EXPECT_EQ(words[3], "another"); + EXPECT_EQ(words[4], "test"); + EXPECT_EQ(words[5], "3"); +} + +} // namespace blender::string_search::tests -- cgit v1.2.3 From 98eb89be5dd08f3b38f34e7881bae37c3b13e8bb Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Sep 2020 13:44:39 +0200 Subject: UI: improve search results by using fuzzy and prefix matching Blender does string based searching in many different places. This patch updates four of these places to use the new string search api in `BLI_string_search.h`. In the future we probably want to update the other searches as well. Reviewers: Severin, pablovazquez Differential Revision: https://developer.blender.org/D8825 --- source/blender/editors/interface/interface.c | 33 +++--- .../interface/interface_template_search_menu.c | 26 ++-- .../editors/interface/interface_templates.c | 131 ++++++++++++--------- source/blender/editors/space_node/node_select.c | 48 +++++--- 4 files changed, 141 insertions(+), 97 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index ea64fb9cfcd..ce9db09e340 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -41,6 +41,7 @@ #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_string.h" +#include "BLI_string_search.h" #include "BLI_string_utf8.h" #include "BLI_utildefines.h" @@ -6651,30 +6652,34 @@ static void operator_enum_search_update_fn(const struct bContext *C, } else { PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */ - const EnumPropertyItem *item, *item_array; + bool do_free; + const EnumPropertyItem *all_items; + RNA_property_enum_items_gettexted((bContext *)C, ptr, prop, &all_items, NULL, &do_free); - /* Prepare BLI_string_all_words_matched. */ - const size_t str_len = strlen(str); - const int words_max = BLI_string_max_possible_word_count(str_len); - int(*words)[2] = BLI_array_alloca(words, words_max); - const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max); + StringSearch *search = BLI_string_search_new(); + for (const EnumPropertyItem *item = all_items; item->identifier; item++) { + BLI_string_search_add(search, item->name, (void *)item); + } - RNA_property_enum_items_gettexted((bContext *)C, ptr, prop, &item_array, NULL, &do_free); + const EnumPropertyItem **filtered_items; + int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_items); - for (item = item_array; item->identifier; item++) { + for (int i = 0; i < filtered_amount; i++) { + const EnumPropertyItem *item = filtered_items[i]; /* note: need to give the index rather than the * identifier because the enum can be freed */ - if (BLI_string_all_words_matched(item->name, str, words, words_len)) { - if (!UI_search_item_add( - items, item->name, POINTER_FROM_INT(item->value), item->icon, 0, 0)) { - break; - } + if (!UI_search_item_add( + items, item->name, POINTER_FROM_INT(item->value), item->icon, 0, 0)) { + break; } } + MEM_freeN(filtered_items); + BLI_string_search_free(search); + if (do_free) { - MEM_freeN((void *)item_array); + MEM_freeN((void *)all_items); } } } diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 667dcfd935d..5bde51846a8 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -41,6 +41,7 @@ #include "BLI_math_matrix.h" #include "BLI_memarena.h" #include "BLI_string.h" +#include "BLI_string_search.h" #include "BLI_string_utils.h" #include "BLI_utildefines.h" @@ -993,19 +994,24 @@ static void menu_search_update_fn(const bContext *UNUSED(C), { struct MenuSearch_Data *data = arg; - /* Prepare BLI_string_all_words_matched. */ - const size_t str_len = strlen(str); - const int words_max = BLI_string_max_possible_word_count(str_len); - int(*words)[2] = BLI_array_alloca(words, words_max); - const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max); + StringSearch *search = BLI_string_search_new(); - for (struct MenuSearch_Item *item = data->items.first; item; item = item->next) { - if (BLI_string_all_words_matched(item->drawwstr_full, str, words, words_len)) { - if (!UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state, 0)) { - break; - } + LISTBASE_FOREACH (struct MenuSearch_Item *, item, &data->items) { + BLI_string_search_add(search, item->drawwstr_full, item); + } + + struct MenuSearch_Item **filtered_items; + int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_items); + + for (int i = 0; i < filtered_amount; i++) { + struct MenuSearch_Item *item = filtered_items[i]; + if (!UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state, 0)) { + break; } } + + MEM_freeN(filtered_items); + BLI_string_search_free(search); } /** \} */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 5fbd26a4f5a..671a7865c6a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -44,6 +44,7 @@ #include "BLI_path_util.h" #include "BLI_rect.h" #include "BLI_string.h" +#include "BLI_string_search.h" #include "BLI_timecode.h" #include "BLI_utildefines.h" @@ -330,67 +331,61 @@ static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, vo } } -static bool id_search_add(const bContext *C, - TemplateID *template_ui, - const int flag, - const char *str, - uiSearchItems *items, - ID *id) +static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id, const char *query) { ID *id_from = template_ui->ptr.owner_id; - if (!((flag & PROP_ID_SELF_CHECK) && id == id_from)) { + /* Do self check. */ + if ((flag & PROP_ID_SELF_CHECK) && id == id_from) { + return false; + } - /* use filter */ - if (RNA_property_type(template_ui->prop) == PROP_POINTER) { - PointerRNA ptr; - RNA_id_pointer_create(id, &ptr); - if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) { - return true; - } + /* Use filter. */ + if (RNA_property_type(template_ui->prop) == PROP_POINTER) { + PointerRNA ptr; + RNA_id_pointer_create(id, &ptr); + if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) { + return false; } + } - /* hide dot-datablocks, but only if filter does not force it visible */ - if (U.uiflag & USER_HIDE_DOT) { - if ((id->name[2] == '.') && (str[0] != '.')) { - return true; - } + /* Hide dot-datablocks, but only if filter does not force them visible. */ + if (U.uiflag & USER_HIDE_DOT) { + if ((id->name[2] == '.') && (query[0] != '.')) { + return false; } + } - /* Prepare BLI_string_all_words_matched. */ - const size_t str_len = strlen(str); - const int words_max = BLI_string_max_possible_word_count(str_len); - int(*words)[2] = BLI_array_alloca(words, words_max); - const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max); - - if (*str == '\0' || BLI_string_all_words_matched(id->name + 2, str, words, words_len)) { - /* +1 is needed because BKE_id_ui_prefix used 3 letter prefix - * followed by ID_NAME-2 characters from id->name - */ - char name_ui[MAX_ID_FULL_NAME_UI]; - int iconid = ui_id_icon_get(C, id, template_ui->preview); - const bool use_lib_prefix = template_ui->preview || iconid; - const bool has_sep_char = (id->lib != NULL); - - /* When using previews, the library hint (linked, overridden, missing) is added with a - * character prefix, otherwise we can use a icon. */ - int name_prefix_offset; - BKE_id_full_name_ui_prefix_get( - name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset); - if (!use_lib_prefix) { - iconid = UI_library_icon_get(id); - } + return true; +} - if (!UI_search_item_add(items, - name_ui, - id, - iconid, - has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0, - name_prefix_offset)) { - return false; - } - } +static bool id_search_add(const bContext *C, TemplateID *template_ui, uiSearchItems *items, ID *id) +{ + /* +1 is needed because BKE_id_ui_prefix used 3 letter prefix + * followed by ID_NAME-2 characters from id->name + */ + char name_ui[MAX_ID_FULL_NAME_UI]; + int iconid = ui_id_icon_get(C, id, template_ui->preview); + const bool use_lib_prefix = template_ui->preview || iconid; + const bool has_sep_char = (id->lib != NULL); + + /* When using previews, the library hint (linked, overridden, missing) is added with a + * character prefix, otherwise we can use a icon. */ + int name_prefix_offset; + BKE_id_full_name_ui_prefix_get(name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset); + if (!use_lib_prefix) { + iconid = UI_library_icon_get(id); + } + + if (!UI_search_item_add(items, + name_ui, + id, + iconid, + has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0, + name_prefix_offset)) { + return false; } + return true; } @@ -404,12 +399,26 @@ static void id_search_cb(const bContext *C, ListBase *lb = template_ui->idlb; const int flag = RNA_property_flag(template_ui->prop); + StringSearch *search = BLI_string_search_new(); + /* ID listbase */ LISTBASE_FOREACH (ID *, id, lb) { - if (!id_search_add(C, template_ui, flag, str, items, id)) { + if (id_search_allows_id(template_ui, flag, id, str)) { + BLI_string_search_add(search, id->name + 2, id); + } + } + + ID **filtered_ids; + int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids); + + for (int i = 0; i < filtered_amount; i++) { + if (!id_search_add(C, template_ui, items, filtered_ids[i])) { break; } } + + MEM_freeN(filtered_ids); + BLI_string_search_free(search); } /** @@ -424,15 +433,29 @@ static void id_search_cb_tagged(const bContext *C, ListBase *lb = template_ui->idlb; const int flag = RNA_property_flag(template_ui->prop); + StringSearch *search = BLI_string_search_new(); + /* ID listbase */ LISTBASE_FOREACH (ID *, id, lb) { if (id->tag & LIB_TAG_DOIT) { - if (!id_search_add(C, template_ui, flag, str, items, id)) { - break; + if (id_search_allows_id(template_ui, flag, id, str)) { + BLI_string_search_add(search, id->name + 2, id); } id->tag &= ~LIB_TAG_DOIT; } } + + ID **filtered_ids; + int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids); + + for (int i = 0; i < filtered_amount; i++) { + if (!id_search_add(C, template_ui, items, filtered_ids[i])) { + break; + } + } + + MEM_freeN(filtered_ids); + BLI_string_search_free(search); } /** diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 83ccfa65af3..5f3047fbdc2 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -32,6 +32,7 @@ #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_string.h" +#include "BLI_string_search.h" #include "BLI_string_utf8.h" #include "BLI_utildefines.h" @@ -1163,6 +1164,16 @@ void NODE_OT_select_same_type_step(wmOperatorType *ot) /** \name Find Node by Name Operator * \{ */ +static void node_find_create_label(const bNode *node, char *str, int maxlen) +{ + if (node->label[0]) { + BLI_snprintf(str, maxlen, "%s (%s)", node->name, node->label); + } + else { + BLI_strncpy(str, node->name, maxlen); + } +} + /* generic search invoke */ static void node_find_update_fn(const struct bContext *C, void *UNUSED(arg), @@ -1170,30 +1181,29 @@ static void node_find_update_fn(const struct bContext *C, uiSearchItems *items) { SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; - /* Prepare BLI_string_all_words_matched. */ - const size_t str_len = strlen(str); - const int words_max = BLI_string_max_possible_word_count(str_len); - int(*words)[2] = BLI_array_alloca(words, words_max); - const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max); + StringSearch *search = BLI_string_search_new(); - for (node = snode->edittree->nodes.first; node; node = node->next) { - if (BLI_string_all_words_matched(node->name, str, words, words_len) || - BLI_string_all_words_matched(node->label, str, words, words_len)) { - char name[256]; + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { + char name[256]; + node_find_create_label(node, name, ARRAY_SIZE(name)); + BLI_string_search_add(search, name, node); + } - if (node->label[0]) { - BLI_snprintf(name, 256, "%s (%s)", node->name, node->label); - } - else { - BLI_strncpy(name, node->name, 256); - } - if (!UI_search_item_add(items, name, node, ICON_NONE, 0, 0)) { - break; - } + bNode **filtered_nodes; + int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_nodes); + + for (int i = 0; i < filtered_amount; i++) { + bNode *node = filtered_nodes[i]; + char name[256]; + node_find_create_label(node, name, ARRAY_SIZE(name)); + if (!UI_search_item_add(items, name, node, ICON_NONE, 0, 0)) { + break; } } + + MEM_freeN(filtered_nodes); + BLI_string_search_free(search); } static void node_find_exec_fn(struct bContext *C, void *UNUSED(arg1), void *arg2) -- cgit v1.2.3 From 9dcae4eb17d7b5a90fda43d0abab1636acf42851 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Wed, 9 Sep 2020 13:52:37 +0200 Subject: Refactor getting constraints This is the refactoring part of D8805 (should be no functional changes). - exposes pose-related part of former 'get_constraints()' from interface_templates.c to new ED_object_pose_constraint_list - rename ED_object_constraint_list_from_context --> ED_object_constraint_active_list Also clarify comments on both of these. ref T80464 ref https://developer.blender.org/D8805 --- source/blender/editors/include/ED_object.h | 3 +- .../editors/interface/interface_templates.c | 29 +++++--------------- source/blender/editors/object/object_constraint.c | 32 ++++++++++++++-------- source/blender/io/collada/BCAnimationSampler.cpp | 2 +- 4 files changed, 30 insertions(+), 36 deletions(-) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 8aa9cd8184b..b0ef22575ee 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -323,7 +323,8 @@ void ED_objects_recalculate_paths(struct bContext *C, eObjectPathCalcRange range); /* constraints */ -struct ListBase *ED_object_constraint_list_from_context(struct Object *ob); +struct ListBase *ED_object_constraint_active_list(struct Object *ob); +struct ListBase *ED_object_pose_constraint_list(const struct bContext *C); struct ListBase *ED_object_constraint_list_from_constraint(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 671a7865c6a..08d3ad0f23c 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1971,27 +1971,6 @@ static bool constraint_panel_is_bone(Panel *panel) (panel->panelname[2] == 'N') && (panel->panelname[3] == 'E'); } -/** - * Get the constraints for the active pose bone or the active / pinned object. - */ -static ListBase *get_constraints(const bContext *C, bool use_bone_constraints) -{ - ListBase *constraints = {NULL}; - if (use_bone_constraints) { - bPoseChannel *pose_bone = CTX_data_pointer_get(C, "pose_bone").data; - if (pose_bone != NULL) { - constraints = &pose_bone->constraints; - } - } - else { - Object *ob = ED_object_active_context(C); - if (ob != NULL) { - constraints = &ob->constraints; - } - } - return constraints; -} - /** * Move a constraint to the index it's moved to after a drag and drop. */ @@ -2066,7 +2045,13 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_ ARegion *region = CTX_wm_region(C); Object *ob = ED_object_active_context(C); - ListBase *constraints = get_constraints(C, use_bone_constraints); + ListBase *constraints = {NULL}; + if (use_bone_constraints) { + constraints = ED_object_pose_constraint_list(C); + } + else { + constraints = ED_object_constraint_active_list(ob); + } /* Switch between the bone panel ID function and the object panel ID function. */ uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id : diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 2cca3045aee..9da5b774af2 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -80,8 +80,9 @@ /** \name Constraint Data Accessors * \{ */ -/* if object in posemode, active bone constraints, else object constraints */ -ListBase *ED_object_constraint_list_from_context(Object *ob) +/* If object is in posemode, return active bone constraints, else object constraints. No + * constraints are returned for a bone on an inactive bonelayer. */ +ListBase *ED_object_constraint_active_list(Object *ob) { if (ob == NULL) { return NULL; @@ -102,6 +103,18 @@ ListBase *ED_object_constraint_list_from_context(Object *ob) return NULL; } +/* Get the constraints for the active pose bone. Bone may be on an inactive bonelayer (unlike + * ED_object_constraint_active_list, such constraints are not excluded here). */ +ListBase *ED_object_pose_constraint_list(const bContext *C) +{ + bPoseChannel *pose_bone = CTX_data_pointer_get(C, "pose_bone").data; + if (pose_bone == NULL) { + return NULL; + } + + return &pose_bone->constraints; +} + /* Find the list that a given constraint belongs to, * and/or also get the posechannel this is from (if applicable) */ ListBase *ED_object_constraint_list_from_constraint(Object *ob, @@ -147,7 +160,7 @@ ListBase *ED_object_constraint_list_from_constraint(Object *ob, /* single constraint */ bConstraint *ED_object_constraint_active_get(Object *ob) { - return BKE_constraints_active_get(ED_object_constraint_list_from_context(ob)); + return BKE_constraints_active_get(ED_object_constraint_active_list(ob)); } /** \} */ @@ -813,7 +826,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int printf("edit_constraint_property_get: defaulting to getting list in the standard way\n"); } #endif - list = ED_object_constraint_list_from_context(ob); + list = ED_object_constraint_active_list(ob); } con = BKE_constraints_find_name(list, constraint_name); @@ -2161,8 +2174,7 @@ static int pose_constraint_add_exec(bContext *C, wmOperator *op) with_targets = 1; } - return constraint_add_exec( - C, op, ob, ED_object_constraint_list_from_context(ob), type, with_targets); + return constraint_add_exec(C, op, ob, ED_object_constraint_active_list(ob), type, with_targets); } /* ------------------ */ @@ -2363,12 +2375,8 @@ static int pose_ik_add_exec(bContext *C, wmOperator *op) /* add the constraint - all necessary checks should have * been done by the invoke() callback already... */ - return constraint_add_exec(C, - op, - ob, - ED_object_constraint_list_from_context(ob), - CONSTRAINT_TYPE_KINEMATIC, - with_targets); + return constraint_add_exec( + C, op, ob, ED_object_constraint_active_list(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets); } void POSE_OT_ik_add(wmOperatorType *ot) diff --git a/source/blender/io/collada/BCAnimationSampler.cpp b/source/blender/io/collada/BCAnimationSampler.cpp index a27bb10f705..b8df98e8acb 100644 --- a/source/blender/io/collada/BCAnimationSampler.cpp +++ b/source/blender/io/collada/BCAnimationSampler.cpp @@ -271,7 +271,7 @@ void BCAnimationSampler::find_depending_animated(std::set &animated_ob std::set::iterator it; for (it = candidates.begin(); it != candidates.end(); ++it) { Object *cob = *it; - ListBase *conlist = ED_object_constraint_list_from_context(cob); + ListBase *conlist = ED_object_constraint_active_list(cob); if (is_animated_by_constraint(cob, conlist, animated_objects)) { animated_objects.insert(cob); candidates.erase(cob); -- cgit v1.2.3 From 6dc7266cf1f4ee4e6e6eaa7e4949fcff11372479 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Wed, 9 Sep 2020 14:10:47 +0200 Subject: Fix T80464: Crash deleting bone constraints when the armature layer is not active Caused by {rB608d9b5aa1f1} Prior to rB608d9b5aa1f1, the constraint was gotten using **context** [CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint) -- which is valid for bones on hidden layers]. After rB608d9b5aa1f1, the constraint is found (or isnt) using `edit_constraint_property_get` [this is **not** valid for bones on hidden layers because internally `BKE_pose_channel_active` checks if the bone is on an active layer]. Some observations: - Every operator using `edit_constraint_property_get` doesnt work for bones on inactive layers [delete, moveup, movedown, move to index (drag n drop nowadays)] -- moveup, movedown, move to index check if they could find a constraint beforehand though (dont crash) -- delete crashes (doesnt check if a constraint could actually be found) - Every operator using `edit_constraint_property_get` for constraint data doesnt work for bones on inactive layers [stretchto_reset, limitdistance_reset, childof_set_inverse, ...] -- these all check if they could find a constraint beforehand though (dont crash) This is because the poll function is using **context** to get the constraint, the operators themselves use **edit_constraint_property_get** which leads to inconsistent/unexpected results. Possible solutions were: - [1] let the delete operator just work with the context constraint again (like prior to rB608d9b5aa1f1) -- allows for deleting constraints on bones in inactive layers - [2] check if we could get a constraint -- prevents the crash, but does **not** allow for deleting constraints on bones in inactive layers - [3] make the poll `edit_constraint_poll_generic` be as strict as the operators -- dont use **context** to get the constraint, but something like **edit_constraint_property_get** - [4] make the operators be more graceful and let them act on bones on hidden layers -- let **edit_constraint_property_get** actually use the same **context** This patch implements [4], so poll an doperators are now in sync. - prevents reported crash - also enables operators for bone constraints on hidden layers - also enables drag and drop reordering of constraints on hidden layers This might be a candidate for 2.90.1? (if it is, take care to include prior "Refactor getting constraints" refactoring commit) Note: Adding constraints also doesnt work for bones on inactive layers [that was the case in 2.79 as well -- it is also using `BKE_pose_channel_active`] Maniphest Tasks: T80464 Differential Revision: https://developer.blender.org/D8805 --- source/blender/editors/object/object_constraint.c | 48 +++++++---------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 9da5b774af2..2f9917a2674 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -793,7 +793,7 @@ static bool edit_constraint_invoke_properties(bContext *C, return false; } -static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int type) +static bConstraint *edit_constraint_property_get(bContext *C, wmOperator *op, Object *ob, int type) { char constraint_name[MAX_NAME]; int owner = RNA_enum_get(op->ptr, "owner"); @@ -802,30 +802,10 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int RNA_string_get(op->ptr, "constraint", constraint_name); - if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) { - list = &ob->constraints; - } - else if (owner == EDIT_CONSTRAINT_OWNER_BONE) { - bPoseChannel *pchan = BKE_pose_channel_active(ob); - if (pchan) { - list = &pchan->constraints; - } - else { -#if 0 - if (G.debug & G_DEBUG) { - printf("edit_constraint_property_get: No active bone for object '%s'\n", - (ob) ? ob->id.name + 2 : ""); - } -#endif - return NULL; - } + if (owner == EDIT_CONSTRAINT_OWNER_BONE) { + list = ED_object_pose_constraint_list(C); } else { -#if 0 - if (G.debug & G_DEBUG) { - printf("edit_constraint_property_get: defaulting to getting list in the standard way\n"); - } -#endif list = ED_object_constraint_active_list(ob); } @@ -855,7 +835,7 @@ static int stretchto_reset_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_STRETCHTO); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_STRETCHTO); bStretchToConstraint *data = (con) ? (bStretchToConstraint *)con->data : NULL; /* despite 3 layers of checks, we may still not be able to find a constraint */ @@ -910,7 +890,7 @@ static int limitdistance_reset_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_DISTLIMIT); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_DISTLIMIT); bDistLimitConstraint *data = (con) ? (bDistLimitConstraint *)con->data : NULL; /* despite 3 layers of checks, we may still not be able to find a constraint */ @@ -982,7 +962,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_CHILDOF); bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; /* despite 3 layers of checks, we may still not be able to find a constraint */ @@ -1036,7 +1016,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_CHILDOF); bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; if (data == NULL) { @@ -1090,7 +1070,7 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_FOLLOWPATH); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_FOLLOWPATH); bFollowPathConstraint *data = (con) ? (bFollowPathConstraint *)con->data : NULL; bAction *act = NULL; @@ -1234,7 +1214,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; /* despite 3 layers of checks, we may still not be able to find a constraint */ @@ -1296,7 +1276,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; if (data == NULL) { @@ -1444,7 +1424,7 @@ static int constraint_delete_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, 0); + bConstraint *con = edit_constraint_property_get(C, op, ob, 0); ListBase *lb = ED_object_constraint_list_from_constraint(ob, con, NULL); /* Store name temporarily for report. */ @@ -1510,7 +1490,7 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot) static int constraint_move_down_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, 0); + bConstraint *con = edit_constraint_property_get(C, op, ob, 0); if (con && con->next) { ListBase *conlist = ED_object_constraint_list_from_constraint(ob, con, NULL); @@ -1565,7 +1545,7 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot) static int constraint_move_up_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, 0); + bConstraint *con = edit_constraint_property_get(C, op, ob, 0); if (con && con->prev) { ListBase *conlist = ED_object_constraint_list_from_constraint(ob, con, NULL); @@ -1618,7 +1598,7 @@ void CONSTRAINT_OT_move_up(wmOperatorType *ot) static int constraint_move_to_index_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, 0); + bConstraint *con = edit_constraint_property_get(C, op, ob, 0); int new_index = RNA_int_get(op->ptr, "index"); if (new_index < 0) { -- cgit v1.2.3 From 842f52d418aaccae45c8e400eb0a8bddef0dbb51 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 9 Sep 2020 08:41:15 -0500 Subject: Cleanup: Rename public "bUnit" functions This commit renames the functions in "BKE_unit.h` to be consistent with the naming in the rest of blenkernel. bUnit_AsString -> BKE_unit_value_as_string_adaptive bUnit_AsString2 -> BKE_unit_value_as_string bUnit_ReplaceString -> BKE_unit_replace_string bUnit_ApplyPreferredUnit -> BKE_unit_apply_preferred_unit bUnit_ToUnitAltName -> BKE_unit_name_to_alt bUnit_ClosestScalar -> BKE_unit_closest_scalar bUnit_BaseScalar -> BKE_unit_base_scalar bUnit_IsValid -> BKE_unit_is_valid bUnit_GetSystem -> BKE_unit_system_get bUnit_GetBaseUnit -> BKE_unit_base_get bUnit_GetBaseUnitOfType -> BKE_unit_base_of_type_get bUnit_GetName -> BKE_unit_name_get bUnit_GetNameDisplay -> BKE_unit_display_name_get bUnit_GetIdentifier -> BKE_unit_identifier_get bUnit_GetScaler -> BKE_unit_scalar_get bUnit_IsSuppressed -> BKE_unit_is_suppressed Differential Revision: https://developer.blender.org/D8828 --- source/blender/blenkernel/BKE_unit.h | 46 ++++++++++---------- source/blender/blenkernel/intern/scene.c | 10 ++--- source/blender/blenkernel/intern/unit.c | 50 +++++++++++----------- source/blender/blenloader/intern/versioning_280.c | 6 +-- source/blender/draw/intern/draw_manager_text.c | 29 +++++++------ source/blender/editors/interface/interface.c | 21 ++++----- .../editors/interface/interface_eyedropper_depth.c | 14 +++--- .../blender/editors/interface/interface_handlers.c | 4 +- source/blender/editors/mesh/editmesh_bevel.c | 14 +++--- source/blender/editors/space_view3d/view3d_draw.c | 18 ++++---- .../editors/space_view3d/view3d_gizmo_ruler.c | 16 +++---- .../editors/transform/transform_mode_translate.c | 28 ++++++------ source/blender/editors/util/numinput.c | 40 ++++++++--------- source/blender/makesrna/intern/rna_scene.c | 12 +++--- source/blender/python/intern/bpy_utils_units.c | 9 ++-- 15 files changed, 160 insertions(+), 157 deletions(-) diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h index d47cebb5dc8..c4af9ab40e2 100644 --- a/source/blender/blenkernel/BKE_unit.h +++ b/source/blender/blenkernel/BKE_unit.h @@ -29,49 +29,49 @@ struct UnitSettings; /* in all cases the value is assumed to be scaled by the user preference */ /* humanly readable representation of a value in units (used for button drawing) */ -size_t bUnit_AsString( +size_t BKE_unit_value_as_string_adaptive( char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad); -size_t bUnit_AsString2(char *str, - int len_max, - double value, - int prec, - int type, - const struct UnitSettings *settings, - bool pad); +size_t BKE_unit_value_as_string(char *str, + int len_max, + double value, + int prec, + int type, + const struct UnitSettings *settings, + bool pad); /* replace units with values, used before python button evaluation */ -bool bUnit_ReplaceString( +bool BKE_unit_replace_string( char *str, int len_max, const char *str_prev, double scale_pref, int system, int type); /* return true if the string contains any valid unit for the given type */ -bool bUnit_ContainsUnit(const char *str, int type); +bool BKE_unit_string_contains_unit(const char *str, int type); /* If user does not specify a unit, this converts it to the unit from the settings. */ -double bUnit_ApplyPreferredUnit(const struct UnitSettings *settings, int type, double value); +double BKE_unit_apply_preferred_unit(const struct UnitSettings *settings, int type, double value); /* make string keyboard-friendly: 10µm --> 10um */ -void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type); +void BKE_unit_name_to_alt(char *str, int len_max, const char *orig_str, int system, int type); /* the size of the unit used for this value (used for calculating the ckickstep) */ -double bUnit_ClosestScalar(double value, int system, int type); +double BKE_unit_closest_scalar(double value, int system, int type); /* base scale for these units */ -double bUnit_BaseScalar(int system, int type); +double BKE_unit_base_scalar(int system, int type); /* return true is the unit system exists */ -bool bUnit_IsValid(int system, int type); +bool BKE_unit_is_valid(int system, int type); /* loop over scales, could add names later */ // double bUnit_Iter(void **unit, char **name, int system, int type); -void bUnit_GetSystem(int system, int type, void const **r_usys_pt, int *r_len); -int bUnit_GetBaseUnit(const void *usys_pt); -int bUnit_GetBaseUnitOfType(int system, int type); -const char *bUnit_GetName(const void *usys_pt, int index); -const char *bUnit_GetNameDisplay(const void *usys_pt, int index); -const char *bUnit_GetIdentifier(const void *usys_pt, int index); -double bUnit_GetScaler(const void *usys_pt, int index); -bool bUnit_IsSuppressed(const void *usys_pt, int index); +void BKE_unit_system_get(int system, int type, const void **r_usys_pt, int *r_len); +int BKE_unit_base_get(const void *usys_pt); +int BKE_unit_base_of_type_get(int system, int type); +const char *BKE_unit_name_get(const void *usys_pt, int index); +const char *BKE_unit_display_name_get(const void *usys_pt, int index); +const char *BKE_unit_identifier_get(const void *usys_pt, int index); +double BKE_unit_scalar_get(const void *usys_pt, int index); +bool BKE_unit_is_suppressed(const void *usys_pt, int index); /* aligned with PropertyUnit */ enum { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index a1f74dddbad..34af226ef72 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -154,11 +154,11 @@ static void scene_init_data(ID *id) scene->unit.system = USER_UNIT_METRIC; scene->unit.scale_length = 1.0f; - scene->unit.length_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_LENGTH); - scene->unit.mass_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_MASS); - scene->unit.time_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_TIME); - scene->unit.temperature_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, - B_UNIT_TEMPERATURE); + scene->unit.length_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_LENGTH); + scene->unit.mass_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_MASS); + scene->unit.time_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_TIME); + scene->unit.temperature_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, + B_UNIT_TEMPERATURE); /* Anti-Aliasing threshold. */ scene->grease_pencil_settings.smaa_threshold = 1.0f; diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index f4a280581f3..bfa031f0d64 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -662,7 +662,7 @@ static size_t unit_as_string_main(char *str, return unit_as_string(str, len_max, value, prec, usys, main_unit, pad ? ' ' : '\0'); } -size_t bUnit_AsString( +size_t BKE_unit_value_as_string_adaptive( char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad) { PreferredUnits units; @@ -675,13 +675,13 @@ size_t bUnit_AsString( return unit_as_string_main(str, len_max, value, prec, type, split, pad, units); } -size_t bUnit_AsString2(char *str, - int len_max, - double value, - int prec, - int type, - const UnitSettings *settings, - bool pad) +size_t BKE_unit_value_as_string(char *str, + int len_max, + double value, + int prec, + int type, + const UnitSettings *settings, + bool pad) { bool do_split = (settings->flag & USER_UNIT_OPT_SPLIT) != 0; PreferredUnits units = preferred_units_from_UnitSettings(settings); @@ -1059,7 +1059,7 @@ static const bUnitDef *unit_detect_from_str(const bUnitCollection *usys, return unit; } -bool bUnit_ContainsUnit(const char *str, int type) +bool BKE_unit_string_contains_unit(const char *str, int type) { for (int system = 0; system < UNIT_SYSTEM_TOT; system++) { const bUnitCollection *usys = unit_get_system(system, type); @@ -1076,12 +1076,12 @@ bool bUnit_ContainsUnit(const char *str, int type) return false; } -double bUnit_ApplyPreferredUnit(const struct UnitSettings *settings, int type, double value) +double BKE_unit_apply_preferred_unit(const struct UnitSettings *settings, int type, double value) { PreferredUnits units = preferred_units_from_UnitSettings(settings); const bUnitDef *unit = get_preferred_display_unit_if_used(type, units); - const double scalar = (unit == NULL) ? bUnit_BaseScalar(units.system, type) : unit->scalar; + const double scalar = (unit == NULL) ? BKE_unit_base_scalar(units.system, type) : unit->scalar; const double bias = (unit == NULL) ? 0.0 : unit->bias; /* Base unit shouldn't have a bias. */ return value * scalar + bias; @@ -1103,7 +1103,7 @@ double bUnit_ApplyPreferredUnit(const struct UnitSettings *settings, int type, d * * \return True of a change was made. */ -bool bUnit_ReplaceString( +bool BKE_unit_replace_string( char *str, int len_max, const char *str_prev, double scale_pref, int system, int type) { const bUnitCollection *usys = unit_get_system(system, type); @@ -1133,7 +1133,7 @@ bool bUnit_ReplaceString( } else { /* BLI_snprintf would not fit into str_tmp, cant do much in this case. - * Check for this because otherwise bUnit_ReplaceString could call its self forever. */ + * Check for this because otherwise BKE_unit_replace_string could call its self forever. */ return changed; } @@ -1194,7 +1194,7 @@ bool bUnit_ReplaceString( } /* 45µm --> 45um */ -void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type) +void BKE_unit_name_to_alt(char *str, int len_max, const char *orig_str, int system, int type) { const bUnitCollection *usys = unit_get_system(system, type); @@ -1234,7 +1234,7 @@ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int syste strncpy(str, orig_str, len_max); } -double bUnit_ClosestScalar(double value, int system, int type) +double BKE_unit_closest_scalar(double value, int system, int type) { const bUnitCollection *usys = unit_get_system(system, type); @@ -1250,7 +1250,7 @@ double bUnit_ClosestScalar(double value, int system, int type) return unit->scalar; } -double bUnit_BaseScalar(int system, int type) +double BKE_unit_base_scalar(int system, int type) { const bUnitCollection *usys = unit_get_system(system, type); if (usys) { @@ -1260,12 +1260,12 @@ double bUnit_BaseScalar(int system, int type) return 1.0; } -bool bUnit_IsValid(int system, int type) +bool BKE_unit_is_valid(int system, int type) { return !(system < 0 || system > UNIT_SYSTEM_TOT || type < 0 || type > B_UNIT_TYPE_TOT); } -void bUnit_GetSystem(int system, int type, void const **r_usys_pt, int *r_len) +void BKE_unit_system_get(int system, int type, void const **r_usys_pt, int *r_len) { const bUnitCollection *usys = unit_get_system(system, type); *r_usys_pt = usys; @@ -1278,25 +1278,25 @@ void bUnit_GetSystem(int system, int type, void const **r_usys_pt, int *r_len) *r_len = usys->length; } -int bUnit_GetBaseUnit(const void *usys_pt) +int BKE_unit_base_get(const void *usys_pt) { return ((bUnitCollection *)usys_pt)->base_unit; } -int bUnit_GetBaseUnitOfType(int system, int type) +int BKE_unit_base_of_type_get(int system, int type) { return unit_get_system(system, type)->base_unit; } -const char *bUnit_GetName(const void *usys_pt, int index) +const char *BKE_unit_name_get(const void *usys_pt, int index) { return ((bUnitCollection *)usys_pt)->units[index].name; } -const char *bUnit_GetNameDisplay(const void *usys_pt, int index) +const char *BKE_unit_display_name_get(const void *usys_pt, int index) { return ((bUnitCollection *)usys_pt)->units[index].name_display; } -const char *bUnit_GetIdentifier(const void *usys_pt, int index) +const char *BKE_unit_identifier_get(const void *usys_pt, int index) { const bUnitDef *unit = ((const bUnitCollection *)usys_pt)->units + index; if (unit->identifier == NULL) { @@ -1305,12 +1305,12 @@ const char *bUnit_GetIdentifier(const void *usys_pt, int index) return unit->identifier; } -double bUnit_GetScaler(const void *usys_pt, int index) +double BKE_unit_scalar_get(const void *usys_pt, int index) { return ((bUnitCollection *)usys_pt)->units[index].scalar; } -bool bUnit_IsSuppressed(const void *usys_pt, int index) +bool BKE_unit_is_suppressed(const void *usys_pt, int index) { return (((bUnitCollection *)usys_pt)->units[index].flag & B_UNIT_DEF_SUPPRESS) != 0; } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index e07ee7ee2b9..213fbe0bde0 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -2975,10 +2975,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { UnitSettings *unit = &scene->unit; if (unit->system != USER_UNIT_NONE) { - unit->length_unit = bUnit_GetBaseUnitOfType(scene->unit.system, B_UNIT_LENGTH); - unit->mass_unit = bUnit_GetBaseUnitOfType(scene->unit.system, B_UNIT_MASS); + unit->length_unit = BKE_unit_base_of_type_get(scene->unit.system, B_UNIT_LENGTH); + unit->mass_unit = BKE_unit_base_of_type_get(scene->unit.system, B_UNIT_MASS); } - unit->time_unit = bUnit_GetBaseUnitOfType(USER_UNIT_NONE, B_UNIT_TIME); + unit->time_unit = BKE_unit_base_of_type_get(USER_UNIT_NONE, B_UNIT_TIME); } /* gpencil grid settings */ diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c index b3c4c97715e..adcac15ab85 100644 --- a/source/blender/draw/intern/draw_manager_text.c +++ b/source/blender/draw/intern/draw_manager_text.c @@ -298,13 +298,13 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, } if (unit->system) { - numstr_len = bUnit_AsString2(numstr, - sizeof(numstr), - len_v3v3(v1, v2) * unit->scale_length, - 3, - B_UNIT_LENGTH, - unit, - false); + numstr_len = BKE_unit_value_as_string(numstr, + sizeof(numstr), + len_v3v3(v1, v2) * unit->scale_length, + 3, + B_UNIT_LENGTH, + unit, + false); } else { numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); @@ -440,13 +440,14 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, mul_m4_v3(ob->obmat, vmid); if (unit->system) { - numstr_len = bUnit_AsString2(numstr, - sizeof(numstr), - (double)(area * unit->scale_length * unit->scale_length), - 3, - B_UNIT_AREA, - unit, - false); + numstr_len = BKE_unit_value_as_string( + numstr, + sizeof(numstr), + (double)(area * unit->scale_length * unit->scale_length), + 3, + B_UNIT_AREA, + unit, + false); } else { numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index ce9db09e340..0bd4934dd0f 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2571,7 +2571,7 @@ void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) orig_str = BLI_strdup(str); - bUnit_ToUnitAltName(str, maxlen, orig_str, unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); + BKE_unit_name_to_alt(str, maxlen, orig_str, unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); MEM_freeN(orig_str); } @@ -2606,13 +2606,13 @@ static void ui_get_but_string_unit( precision = float_precision; } - bUnit_AsString2(str, - len_max, - ui_get_but_scale_unit(but, value), - precision, - RNA_SUBTYPE_UNIT_VALUE(unit_type), - unit, - pad); + BKE_unit_value_as_string(str, + len_max, + ui_get_but_scale_unit(but, value), + precision, + RNA_SUBTYPE_UNIT_VALUE(unit_type), + unit, + pad); } static float ui_get_but_step_unit(uiBut *but, float step_default) @@ -2622,12 +2622,13 @@ static float ui_get_but_step_unit(uiBut *but, float step_default) /* Scaling up 'step_origg ' here is a bit arbitrary, * its just giving better scales from user POV */ const double scale_step = ui_get_but_scale_unit(but, step_orig * 10); - const double step = bUnit_ClosestScalar(scale_step, but->block->unit->system, unit_type); + const double step = BKE_unit_closest_scalar(scale_step, but->block->unit->system, unit_type); /* -1 is an error value */ if (step != -1.0) { const double scale_unit = ui_get_but_scale_unit(but, 1.0); - const double step_unit = bUnit_ClosestScalar(scale_unit, but->block->unit->system, unit_type); + const double step_unit = BKE_unit_closest_scalar( + scale_unit, but->block->unit->system, unit_type); double step_final; BLI_assert(step > 0.0); diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c index fbc0ed1fc1f..ead65a62226 100644 --- a/source/blender/editors/interface/interface_eyedropper_depth.c +++ b/source/blender/editors/interface/interface_eyedropper_depth.c @@ -193,13 +193,13 @@ static void depthdropper_depth_sample_pt( *r_depth = len_v3v3(view_co, co_align); - bUnit_AsString2(ddr->name, - sizeof(ddr->name), - (double)*r_depth, - 4, - B_UNIT_LENGTH, - &scene->unit, - false); + BKE_unit_value_as_string(ddr->name, + sizeof(ddr->name), + (double)*r_depth, + 4, + B_UNIT_LENGTH, + &scene->unit, + false); } else { BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name)); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index a4042ab8265..6a6914daf47 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4614,8 +4614,8 @@ static float ui_numedit_apply_snapf( UnitSettings *unit = but->block->unit; const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); - if (bUnit_IsValid(unit->system, unit_type)) { - fac = (float)bUnit_BaseScalar(unit->system, unit_type); + if (BKE_unit_is_valid(unit->system, unit_type)) { + fac = (float)BKE_unit_base_scalar(unit->system, unit_type); if (ELEM(unit_type, B_UNIT_LENGTH, B_UNIT_AREA, B_UNIT_VOLUME)) { fac /= unit->scale_length; } diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index dd4b8146154..a90d6530453 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -158,13 +158,13 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op) } else { double offset_val = (double)RNA_float_get(op->ptr, "offset"); - bUnit_AsString2(offset_str, - NUM_STR_REP_LEN, - offset_val * sce->unit.scale_length, - 3, - B_UNIT_LENGTH, - &sce->unit, - true); + BKE_unit_value_as_string(offset_str, + NUM_STR_REP_LEN, + offset_val * sce->unit.scale_length, + 3, + B_UNIT_LENGTH, + &sce->unit, + true); } prop = RNA_struct_find_property(op->ptr, "offset_type"); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6cd940244b4..da44815b31a 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -879,14 +879,14 @@ float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit) const void *usys; int len; - bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len); + BKE_unit_system_get(scene->unit.system, B_UNIT_LENGTH, &usys, &len); if (usys) { - int i = bUnit_GetBaseUnit(usys); + int i = BKE_unit_base_get(usys); if (r_grid_unit) { - *r_grid_unit = bUnit_GetNameDisplay(usys, i); + *r_grid_unit = BKE_unit_display_name_get(usys, i); } - return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length; + return (float)BKE_unit_scalar_get(usys, i) / scene->unit.scale_length; } } @@ -906,20 +906,20 @@ void ED_view3d_grid_steps(const Scene *scene, { const void *usys; int i, len; - bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len); + BKE_unit_system_get(scene->unit.system, B_UNIT_LENGTH, &usys, &len); float grid_scale = v3d->grid; BLI_assert(STEPS_LEN >= len); if (usys) { if (rv3d->view == RV3D_VIEW_USER) { /* Skip steps */ - len = bUnit_GetBaseUnit(usys) + 1; + len = BKE_unit_base_get(usys) + 1; } grid_scale /= scene->unit.scale_length; for (i = 0; i < len; i++) { - r_grid_steps[i] = (float)bUnit_GetScaler(usys, len - 1 - i) * grid_scale; + r_grid_steps[i] = (float)BKE_unit_scalar_get(usys, len - 1 - i) * grid_scale; } for (; i < STEPS_LEN; i++) { /* Fill last slots */ @@ -971,10 +971,10 @@ float ED_view3d_grid_view_scale(Scene *scene, if (r_grid_unit) { const void *usys; int len; - bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len); + BKE_unit_system_get(scene->unit.system, B_UNIT_LENGTH, &usys, &len); if (usys) { - *r_grid_unit = bUnit_GetNameDisplay(usys, len - i - 1); + *r_grid_unit = BKE_unit_display_name_get(usys, len - i - 1); } } } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 5aba1fecc53..990b7952e39 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -179,7 +179,7 @@ static void ruler_item_as_string( BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle)); } else { - bUnit_AsString2( + BKE_unit_value_as_string( numstr, numstr_size, (double)ruler_angle, prec, B_UNIT_ROTATION, unit, false); } } @@ -190,13 +190,13 @@ static void ruler_item_as_string( BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len); } else { - bUnit_AsString2(numstr, - numstr_size, - (double)(ruler_len * unit->scale_length), - prec, - B_UNIT_LENGTH, - unit, - false); + BKE_unit_value_as_string(numstr, + numstr_size, + (double)(ruler_len * unit->scale_length), + prec, + B_UNIT_LENGTH, + unit, + false); } } } diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 36be26049d3..866b9d921c8 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -89,13 +89,13 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ dist = len_v3(vec); if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) { for (int i = 0; i < 3; i++) { - bUnit_AsString2(&tvec[NUM_STR_REP_LEN * i], - NUM_STR_REP_LEN, - dvec[i] * t->scene->unit.scale_length, - 4, - B_UNIT_LENGTH, - &t->scene->unit, - true); + BKE_unit_value_as_string(&tvec[NUM_STR_REP_LEN * i], + NUM_STR_REP_LEN, + dvec[i] * t->scene->unit.scale_length, + 4, + B_UNIT_LENGTH, + &t->scene->unit, + true); } } else { @@ -106,13 +106,13 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ } if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) { - bUnit_AsString2(distvec, - sizeof(distvec), - dist * t->scene->unit.scale_length, - 4, - B_UNIT_LENGTH, - &t->scene->unit, - false); + BKE_unit_value_as_string(distvec, + sizeof(distvec), + dist * t->scene->unit.scale_length, + 4, + B_UNIT_LENGTH, + &t->scene->unit, + false); } else if (dist > 1e10f || dist < -1e10f) { /* prevent string buffer overflow */ diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index f8e3dda0ed3..ba22bcca0e1 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -136,14 +136,14 @@ void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings) BLI_strncpy(val, "Invalid", sizeof(val)); } else { - bUnit_AsString(val, - sizeof(val), - (double)(n->val[i] * fac), - prec, - n->unit_sys, - n->unit_type[i], - true, - false); + BKE_unit_value_as_string_adaptive(val, + sizeof(val), + (double)(n->val[i] * fac), + prec, + n->unit_sys, + n->unit_type[i], + true, + false); } /* +1 because of trailing '\0' */ @@ -165,7 +165,7 @@ void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings) } else { char tstr[NUM_STR_REP_LEN]; - bUnit_AsString( + BKE_unit_value_as_string_adaptive( tstr, ln, (double)n->val[i], prec, n->unit_sys, n->unit_type[i], true, false); BLI_snprintf(&str[j * ln], ln, "%s%s%s", cur, tstr, cur); } @@ -252,14 +252,14 @@ bool applyNumInput(NumInput *n, float *vec) static void value_to_editstr(NumInput *n, int idx) { const int prec = 6; /* editing, higher precision needed. */ - n->str_cur = bUnit_AsString(n->str, - NUM_STR_REP_LEN, - (double)n->val[idx], - prec, - n->unit_sys, - n->unit_type[idx], - true, - false); + n->str_cur = BKE_unit_value_as_string_adaptive(n->str, + NUM_STR_REP_LEN, + (double)n->val[idx], + prec, + n->unit_sys, + n->unit_type[idx], + true, + false); } static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf_len) @@ -288,17 +288,17 @@ bool user_string_to_number(bContext *C, { #ifdef WITH_PYTHON double unit_scale = BKE_scene_unit_scale(unit, type, 1.0); - if (bUnit_ContainsUnit(str, type)) { + if (BKE_unit_string_contains_unit(str, type)) { char str_unit_convert[256]; BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); - bUnit_ReplaceString( + BKE_unit_replace_string( str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type); return BPY_run_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value); } int success = BPY_run_string_as_number(C, NULL, str, error_prefix, r_value); - *r_value = bUnit_ApplyPreferredUnit(unit, type, *r_value); + *r_value = BKE_unit_apply_preferred_unit(unit, type, *r_value); *r_value /= unit_scale; return success; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ebec5e3bff8..bf97e4fcc0f 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2514,7 +2514,7 @@ static const EnumPropertyItem *rna_UnitSettings_itemf_wrapper(const int system, { const void *usys; int len; - bUnit_GetSystem(system, type, &usys, &len); + BKE_unit_system_get(system, type, &usys, &len); EnumPropertyItem *items = NULL; int totitem = 0; @@ -2526,10 +2526,10 @@ static const EnumPropertyItem *rna_UnitSettings_itemf_wrapper(const int system, RNA_enum_item_add(&items, &totitem, &adaptive); for (int i = 0; i < len; i++) { - if (!bUnit_IsSuppressed(usys, i)) { + if (!BKE_unit_is_suppressed(usys, i)) { EnumPropertyItem tmp = {0}; - tmp.identifier = bUnit_GetIdentifier(usys, i); - tmp.name = bUnit_GetNameDisplay(usys, i); + tmp.identifier = BKE_unit_identifier_get(usys, i); + tmp.name = BKE_unit_display_name_get(usys, i); tmp.value = i; RNA_enum_item_add(&items, &totitem, &tmp); } @@ -2587,8 +2587,8 @@ static void rna_UnitSettings_system_update(Main *UNUSED(bmain), unit->mass_unit = USER_UNIT_ADAPTIVE; } else { - unit->length_unit = bUnit_GetBaseUnitOfType(unit->system, B_UNIT_LENGTH); - unit->mass_unit = bUnit_GetBaseUnitOfType(unit->system, B_UNIT_MASS); + unit->length_unit = BKE_unit_base_of_type_get(unit->system, B_UNIT_LENGTH); + unit->mass_unit = BKE_unit_base_of_type_get(unit->system, B_UNIT_MASS); } } diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c index 4433f5d0f88..a58e2bcb975 100644 --- a/source/blender/python/intern/bpy_utils_units.c +++ b/source/blender/python/intern/bpy_utils_units.c @@ -134,7 +134,7 @@ static bool bpyunits_validate(const char *usys_str, const char *ucat_str, int *r return false; } - if (!bUnit_IsValid(*r_usys, *r_ucat)) { + if (!BKE_unit_is_valid(*r_usys, *r_ucat)) { PyErr_Format(PyExc_ValueError, "%.200s / %.200s unit system/category combination is not valid.", usys_str, @@ -197,7 +197,7 @@ static PyObject *bpyunits_to_value(PyObject *UNUSED(self), PyObject *args, PyObj str = PyMem_MALLOC(sizeof(*str) * (size_t)str_len); BLI_strncpy(str, inpt, (size_t)str_len); - bUnit_ReplaceString(str, (int)str_len, uref, scale, usys, ucat); + BKE_unit_replace_string(str, (int)str_len, uref, scale, usys, ucat); if (!PyC_RunString_AsNumber(NULL, str, "", &result)) { if (PyErr_Occurred()) { @@ -291,10 +291,11 @@ static PyObject *bpyunits_to_string(PyObject *UNUSED(self), PyObject *args, PyOb char buf1[64], buf2[64], *str; PyObject *result; - bUnit_AsString(buf1, sizeof(buf1), value, precision, usys, ucat, (bool)split_unit, false); + BKE_unit_value_as_string_adaptive( + buf1, sizeof(buf1), value, precision, usys, ucat, (bool)split_unit, false); if (compatible_unit) { - bUnit_ToUnitAltName(buf2, sizeof(buf2), buf1, usys, ucat); + BKE_unit_name_to_alt(buf2, sizeof(buf2), buf1, usys, ucat); str = buf2; } else { -- cgit v1.2.3