diff options
author | jon denning <gfxcoder@gmail.com> | 2022-07-26 16:52:53 +0300 |
---|---|---|
committer | jon denning <gfxcoder@gmail.com> | 2022-07-26 16:53:25 +0300 |
commit | dbdab681cfe4dea8f1dc417f0027166dde10e6dc (patch) | |
tree | eae9706a40a08d00100403148386bf1287b8f21a /source | |
parent | 66c6cf0d7120737a90c9762a38188f7d4d49ad01 (diff) | |
parent | 1998269b109f65373336087da7f9751a3c3317f3 (diff) |
Added operator to determine if operator is actively modal
Differential Revision: https://developer.blender.org/D15546
Diffstat (limited to 'source')
38 files changed, 377 insertions, 689 deletions
diff --git a/source/blender/blenkernel/intern/curve_poly.cc b/source/blender/blenkernel/intern/curve_poly.cc index 7ab92068d81..2b2cf9adeee 100644 --- a/source/blender/blenkernel/intern/curve_poly.cc +++ b/source/blender/blenkernel/intern/curve_poly.cc @@ -65,8 +65,21 @@ void calculate_tangents(const Span<float3> positions, tangents.last() = direction_bisect(second_to_last, last, first, used_fallback); } else { - tangents.first() = math::normalize(positions[1] - positions.first()); - tangents.last() = math::normalize(positions.last() - positions[positions.size() - 2]); + const float epsilon = 1e-6f; + if (math::almost_equal_relative(positions[0], positions[1], epsilon)) { + tangents.first() = {0.0f, 0.0f, 0.0f}; + used_fallback = true; + } + else { + tangents.first() = math::normalize(positions[1] - positions[0]); + } + if (math::almost_equal_relative(positions.last(0), positions.last(1), epsilon)) { + tangents.last() = {0.0f, 0.0f, 0.0f}; + used_fallback = true; + } + else { + tangents.last() = math::normalize(positions.last(0) - positions.last(1)); + } } if (!used_fallback) { diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc index 6554f42d3dd..baa9c32a9ff 100644 --- a/source/blender/blenkernel/intern/curves.cc +++ b/source/blender/blenkernel/intern/curves.cc @@ -291,6 +291,8 @@ static void curves_evaluate_modifiers(struct Depsgraph *depsgraph, ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE; const ModifierEvalContext mectx = {depsgraph, object, apply_flag}; + BKE_modifiers_clear_errors(object); + /* Get effective list of modifiers to execute. Some effects like shape keys * are added as virtual modifiers before the user created modifiers. */ VirtualModifierData virtualModifierData; diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 3050e01e528..6486be4afe0 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -1165,6 +1165,7 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves, CurvesGeometry new_curves{new_point_count, new_curve_count}; threading::parallel_invoke( + 256 < new_point_count * new_curve_count, /* Initialize curve offsets. */ [&]() { new_curves.offsets_for_write().copy_from(new_curve_offsets); }, [&]() { @@ -1237,6 +1238,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, CurvesGeometry new_curves{new_tot_points, new_tot_curves}; threading::parallel_invoke( + 256 < new_tot_points * new_tot_curves, /* Initialize curve offsets. */ [&]() { MutableSpan<int> new_offsets = new_curves.offsets_for_write(); diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 3d546c5c36a..8a36cfe14c6 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -271,7 +271,7 @@ static void greasepencil_blend_read_lib(BlendLibReader *reader, ID *id) { bGPdata *gpd = (bGPdata *)id; - /* Relink all data-lock linked by GP data-lock */ + /* Relink all data-block linked by GP data-block. */ /* Layers */ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* Layer -> Parent References */ diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index dabc76f29ca..0202fb3ff5e 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -2303,7 +2303,7 @@ static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb, BLO_read_data_address(reader, &lc->scene_collection); #endif - /* Master collection is not a real data-lock. */ + /* Master collection is not a real data-block. */ if (master) { BLO_read_data_address(reader, &lc->collection); } @@ -2343,7 +2343,7 @@ static void lib_link_layer_collection(BlendLibReader *reader, LayerCollection *layer_collection, bool master) { - /* Master collection is not a real data-lock. */ + /* Master collection is not a real data-block. */ if (!master) { BLO_read_id_address(reader, lib, &layer_collection->collection); } diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index 261b053e4f9..426ad797cef 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -364,6 +364,8 @@ static void pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph, ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE; const ModifierEvalContext mectx = {depsgraph, object, apply_flag}; + BKE_modifiers_clear_errors(object); + /* Get effective list of modifiers to execute. Some effects like shape keys * are added as virtual modifiers before the user created modifiers. */ VirtualModifierData virtualModifierData; diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 82405830437..2f5bf0de58f 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -1089,6 +1089,8 @@ static void volume_evaluate_modifiers(struct Depsgraph *depsgraph, ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE; const ModifierEvalContext mectx = {depsgraph, object, apply_flag}; + BKE_modifiers_clear_errors(object); + /* Get effective list of modifiers to execute. Some effects like shape keys * are added as virtual modifiers before the user created modifiers. */ VirtualModifierData virtualModifierData; diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh index 904dea66f7a..33a781d3749 100644 --- a/source/blender/blenlib/BLI_task.hh +++ b/source/blender/blenlib/BLI_task.hh @@ -105,6 +105,22 @@ template<typename... Functions> void parallel_invoke(Functions &&...functions) #endif } +/** + * Same #parallel_invoke, but allows disabling threading dynamically. This is useful because when + * the individual functions do very little work, there is a lot of overhead from starting parallel + * tasks. + */ +template<typename... Functions> +void parallel_invoke(const bool use_threading, Functions &&...functions) +{ + if (use_threading) { + parallel_invoke(std::forward<Functions>(functions)...); + } + else { + (functions(), ...); + } +} + /** See #BLI_task_isolate for a description of what isolating a task means. */ template<typename Function> void isolate_task(const Function &function) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f0d390677bb..1ed0f2d5dfe 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -517,7 +517,7 @@ void blo_split_main(ListBase *mainlist, Main *main) while (i--) { ID *id = lbarray[i]->first; if (id == NULL || GS(id->name) == ID_LI) { - /* No ID_LI data-lock should ever be linked anyway, but just in case, better be explicit. */ + /* No ID_LI data-block should ever be linked anyway, but just in case, better be explicit. */ continue; } split_libdata(lbarray[i], lib_main_array, lib_main_array_len); @@ -4175,7 +4175,7 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) } if (bhead->code == ID_LINK_PLACEHOLDER) { - /* Placeholder link to data-lock in another library. */ + /* Placeholder link to data-block in another library. */ BHead *bheadlib = find_previous_lib(fd, bhead); if (bheadlib == NULL) { return; @@ -4229,7 +4229,7 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) */ oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); - /* If "id" is a real data-lock and not a placeholder, we need to + /* If "id" is a real data-block and not a placeholder, we need to * update fd->libmap to replace ID_LINK_PLACEHOLDER with the real * ID_* code. * @@ -4890,11 +4890,11 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } } - /* Read linked data-locks for each link placeholder, and replace - * the placeholder with the real data-lock. */ + /* Read linked data-blocks for each link placeholder, and replace + * the placeholder with the real data-block. */ read_library_linked_ids(basefd, fd, mainlist, mainptr); - /* Test if linked data-locks need to read further linked data-locks + /* Test if linked data-blocks need to read further linked data-blocks * and create link placeholders for them. */ BLO_expand_main(fd, mainptr); } @@ -4906,7 +4906,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) /* Drop weak links for which no data-block was found. */ read_library_clear_weak_links(basefd, mainlist, mainptr); - /* Do versioning for newly added linked data-locks. If no data-locks + /* Do versioning for newly added linked data-blocks. If no data-blocks * were read from a library versionfile will still be zero and we can * skip it. */ if (mainptr->versionfile) { diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index bbbeba4d687..fa3789ea590 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -875,6 +875,34 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports)) */ { /* Keep this block, even when empty. */ + + { + /* In the Dope Sheet, for every mode other than Timeline, open the Properties panel. */ + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype != SPACE_ACTION) { + continue; + } + + /* Skip the timeline, it shouldn't get its Properties panel opened. */ + SpaceAction *saction = (SpaceAction *)sl; + if (saction->mode == SACTCONT_TIMELINE) { + continue; + } + + const bool is_first_space = sl == area->spacedata.first; + ListBase *regionbase = is_first_space ? &area->regionbase : &sl->regionbase; + ARegion *region = BKE_region_find_in_listbase_by_type(regionbase, RGN_TYPE_UI); + if (region == NULL) { + continue; + } + + region->flag &= ~RGN_FLAG_HIDDEN; + } + } + } + } } } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index dfd98cb94f3..a2e3fd5346e 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -134,6 +134,14 @@ static void blo_update_defaults_screen(bScreen *screen, } } } + else { + /* Open properties panel by default. */ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->regiontype == RGN_TYPE_UI) { + region->flag &= ~RGN_FLAG_HIDDEN; + } + } + } } else if (area->spacetype == SPACE_GRAPH) { SpaceGraph *sipo = area->spacedata.first; diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index d20745f28c0..9744f2e3cee 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -67,7 +67,6 @@ set(SRC intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc intern/mesh_extractors/extract_mesh_vbo_tan.cc intern/mesh_extractors/extract_mesh_vbo_uv.cc - intern/mesh_extractors/extract_mesh_vbo_vcol.cc intern/mesh_extractors/extract_mesh_vbo_weights.cc intern/draw_attributes.cc intern/draw_cache_impl_curve.cc diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc index 3f187aef8e6..011d72e9e8f 100644 --- a/source/blender/draw/intern/draw_attributes.cc +++ b/source/blender/draw/intern/draw_attributes.cc @@ -88,7 +88,7 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data, int *r_layer_index, eCustomDataType *r_type) { - const eCustomDataType possible_attribute_types[7] = { + const eCustomDataType possible_attribute_types[8] = { CD_PROP_BOOL, CD_PROP_INT8, CD_PROP_INT32, @@ -96,6 +96,7 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data, CD_PROP_FLOAT2, CD_PROP_FLOAT3, CD_PROP_COLOR, + CD_PROP_BYTE_COLOR, }; for (int i = 0; i < ARRAY_SIZE(possible_attribute_types); i++) { diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh index c7127d169e1..203da22406c 100644 --- a/source/blender/draw/intern/draw_cache_extract.hh +++ b/source/blender/draw/intern/draw_cache_extract.hh @@ -55,7 +55,6 @@ enum { struct DRW_MeshCDMask { uint32_t uv : 8; uint32_t tan : 8; - uint32_t vcol : 8; uint32_t orco : 1; uint32_t tan_orco : 1; uint32_t sculpt_overlays : 1; @@ -111,7 +110,6 @@ struct MeshBufferList { GPUVertBuf *weights; /* extend */ GPUVertBuf *uv; GPUVertBuf *tan; - GPUVertBuf *vcol; GPUVertBuf *sculpt_data; GPUVertBuf *orco; /* Only for edit mode. */ diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index 380736ef656..b1d1631cb6d 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -619,7 +619,6 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, EXTRACT_ADD_REQUESTED(vbo, lnor); EXTRACT_ADD_REQUESTED(vbo, uv); EXTRACT_ADD_REQUESTED(vbo, tan); - EXTRACT_ADD_REQUESTED(vbo, vcol); EXTRACT_ADD_REQUESTED(vbo, sculpt_data); EXTRACT_ADD_REQUESTED(vbo, orco); EXTRACT_ADD_REQUESTED(vbo, edge_fac); @@ -848,7 +847,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle); EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask); EXTRACT_ADD_REQUESTED(ibo, lines_adjacency); - EXTRACT_ADD_REQUESTED(vbo, vcol); EXTRACT_ADD_REQUESTED(vbo, weights); EXTRACT_ADD_REQUESTED(vbo, sculpt_data); diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 77cbb5efa12..fc09606f9f3 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -431,6 +431,30 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ } } +static void retrieve_active_attribute_names(MeshRenderData &mr, + const Object &object, + const Mesh &mesh) +{ + const Mesh *mesh_final = editmesh_final_or_this(&object, &mesh); + const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(mesh_final); + const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(mesh_final); + + /* Necessary because which attributes are active/default is stored in #CustomData. */ + Mesh me_query = blender::dna::shallow_zero_initialize(); + BKE_id_attribute_copy_domains_temp( + ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); + + mr.active_color_name = nullptr; + mr.default_color_name = nullptr; + + if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) { + mr.active_color_name = active->name; + } + if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) { + mr.default_color_name = render->name; + } +} + MeshRenderData *mesh_render_data_create(Object *object, Mesh *me, const bool is_editmode, @@ -566,6 +590,8 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len); } + retrieve_active_attribute_names(*mr, *object, *me); + return mr; } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index e93b1a66b66..d3d9db13005 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -21,6 +21,7 @@ #include "BLI_math_vector.h" #include "BLI_span.hh" #include "BLI_string.h" +#include "BLI_string_ref.hh" #include "BLI_task.h" #include "BLI_utildefines.h" @@ -67,6 +68,7 @@ using blender::IndexRange; using blender::Map; using blender::Span; +using blender::StringRefNull; /* ---------------------------------------------------------------------- */ /** \name Dependencies between buffer and batch @@ -115,8 +117,6 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index) MBC_SURFACE_PER_MAT; case BUFFER_INDEX(vbo.tan): return MBC_SURFACE_PER_MAT; - case BUFFER_INDEX(vbo.vcol): - return MBC_SURFACE | MBC_SURFACE_PER_MAT; case BUFFER_INDEX(vbo.sculpt_data): return MBC_SCULPT_OVERLAYS; case BUFFER_INDEX(vbo.orco): @@ -236,87 +236,11 @@ BLI_INLINE void mesh_cd_layers_type_clear(DRW_MeshCDMask *a) *((uint32_t *)a) = 0; } -BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *me) -{ - if (me->edit_mesh != nullptr) { - Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object); - if (editmesh_eval_final != nullptr) { - return editmesh_eval_final; - } - } - - return me; -} - static void mesh_cd_calc_edit_uv_layer(const Mesh *UNUSED(me), DRW_MeshCDMask *cd_used) { cd_used->edit_uv = 1; } -BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me) -{ - switch ((eMeshWrapperType)me->runtime.wrapper_type) { - case ME_WRAPPER_TYPE_SUBD: - case ME_WRAPPER_TYPE_MDATA: - return &me->ldata; - break; - case ME_WRAPPER_TYPE_BMESH: - return &me->edit_mesh->bm->ldata; - break; - } - - BLI_assert(0); - return &me->ldata; -} - -BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me) -{ - switch ((eMeshWrapperType)me->runtime.wrapper_type) { - case ME_WRAPPER_TYPE_SUBD: - case ME_WRAPPER_TYPE_MDATA: - return &me->pdata; - break; - case ME_WRAPPER_TYPE_BMESH: - return &me->edit_mesh->bm->pdata; - break; - } - - BLI_assert(0); - return &me->pdata; -} - -BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me) -{ - switch ((eMeshWrapperType)me->runtime.wrapper_type) { - case ME_WRAPPER_TYPE_SUBD: - case ME_WRAPPER_TYPE_MDATA: - return &me->edata; - break; - case ME_WRAPPER_TYPE_BMESH: - return &me->edit_mesh->bm->edata; - break; - } - - BLI_assert(0); - return &me->edata; -} - -BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me) -{ - switch ((eMeshWrapperType)me->runtime.wrapper_type) { - case ME_WRAPPER_TYPE_SUBD: - case ME_WRAPPER_TYPE_MDATA: - return &me->vdata; - break; - case ME_WRAPPER_TYPE_BMESH: - return &me->edit_mesh->bm->vdata; - break; - } - - BLI_assert(0); - return &me->vdata; -} - static void mesh_cd_calc_active_uv_layer(const Object *object, const Mesh *me, DRW_MeshCDMask *cd_used) @@ -341,75 +265,6 @@ static void mesh_cd_calc_active_mask_uv_layer(const Object *object, } } -static void mesh_cd_calc_active_mloopcol_layer(const Object *object, - const Mesh *me, - DRW_MeshCDMask *cd_used) -{ - const Mesh *me_final = editmesh_final_or_this(object, me); - Mesh me_query = blender::dna::shallow_zero_initialize(); - - const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); - const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); - - BKE_id_attribute_copy_domains_temp( - ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); - - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me_query.id); - int layer_i = BKE_id_attribute_to_index( - &me_query.id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); - - if (layer_i != -1) { - cd_used->vcol |= (1UL << (uint)layer_i); - } -} - -static uint mesh_cd_calc_gpu_layers_vcol_used(const Mesh *me_query, - const CustomData *cd_vdata, - const CustomData *cd_ldata, - const char name[]) -{ - const CustomDataLayer *layer = nullptr; - eAttrDomain domain; - - if (name[0]) { - int layer_i = 0; - - domain = ATTR_DOMAIN_POINT; - layer_i = CustomData_get_named_layer_index(cd_vdata, CD_PROP_COLOR, name); - layer_i = layer_i == -1 ? - CustomData_get_named_layer_index(cd_vdata, CD_PROP_BYTE_COLOR, name) : - layer_i; - - if (layer_i == -1) { - domain = ATTR_DOMAIN_CORNER; - layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_ldata, CD_PROP_COLOR, name) : - layer_i; - layer_i = layer_i == -1 ? - CustomData_get_named_layer_index(cd_ldata, CD_PROP_BYTE_COLOR, name) : - layer_i; - } - - /* NOTE: this is not the same as the layer_i below. */ - if (layer_i != -1) { - layer = (domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata)->layers + layer_i; - } - } - else { - layer = BKE_id_attributes_render_color_get(&me_query->id); - } - - if (!layer) { - return -1; - } - - /* NOTE: this is the logical index into the color attribute list, - * not the customdata index. */ - int vcol_i = BKE_id_attribute_to_index( - (ID *)me_query, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); - - return vcol_i; -} - static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, const Mesh *me, struct GPUMaterial **gpumat_array, @@ -433,6 +288,9 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, DRW_MeshCDMask cd_used; mesh_cd_layers_type_clear(&cd_used); + const CustomDataLayer *default_color = BKE_id_attributes_render_color_get(&me_query.id); + const StringRefNull default_color_name = default_color ? default_color->name : ""; + for (int i = 0; i < gpumat_array_len; i++) { GPUMaterial *gpumat = gpumat_array[i]; if (gpumat) { @@ -443,6 +301,10 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, int layer = -1; std::optional<eAttrDomain> domain; + if (gpu_attr->is_default_color) { + name = default_color_name.c_str(); + } + if (type == CD_AUTO_FROM_NAME) { /* We need to deduce what exact layer is used. * @@ -452,38 +314,6 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name); type = CD_MTFACE; - if (layer == -1) { - layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name); - if (layer != -1) { - type = CD_PROP_COLOR; - domain = ATTR_DOMAIN_POINT; - } - } - - if (layer == -1) { - layer = CustomData_get_named_layer(cd_ldata, CD_PROP_COLOR, name); - if (layer != -1) { - type = CD_PROP_COLOR; - domain = ATTR_DOMAIN_CORNER; - } - } - - if (layer == -1) { - layer = CustomData_get_named_layer(cd_vdata, CD_PROP_BYTE_COLOR, name); - if (layer != -1) { - type = CD_PROP_BYTE_COLOR; - domain = ATTR_DOMAIN_POINT; - } - } - - if (layer == -1) { - layer = CustomData_get_named_layer(cd_ldata, CD_PROP_BYTE_COLOR, name); - if (layer != -1) { - type = CD_PROP_BYTE_COLOR; - domain = ATTR_DOMAIN_CORNER; - } - } - #if 0 /* Tangents are always from UV's - this will never happen. */ if (layer == -1) { layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name); @@ -556,28 +386,8 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, cd_used.orco = 1; break; } - - /* NOTE: attr->type will always be CD_PROP_COLOR even for - * CD_PROP_BYTE_COLOR layers, see node_shader_gpu_vertex_color in - * node_shader_vertex_color.cc. - */ - case CD_MCOL: case CD_PROP_BYTE_COLOR: - case CD_PROP_COLOR: { - /* First check Color attributes, when not found check mesh attributes. Geometry nodes - * can generate those layers. */ - int vcol_bit = mesh_cd_calc_gpu_layers_vcol_used(&me_query, cd_vdata, cd_ldata, name); - - if (vcol_bit != -1) { - cd_used.vcol |= 1UL << (uint)vcol_bit; - break; - } - - if (layer != -1 && domain.has_value()) { - drw_attributes_add_request(attributes, name, type, layer, *domain); - } - break; - } + case CD_PROP_COLOR: case CD_PROP_FLOAT3: case CD_PROP_BOOL: case CD_PROP_INT8: @@ -863,10 +673,9 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache) FOREACH_MESH_BUFFER_CACHE (cache, mbc) { GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.uv); GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.tan); - GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.vcol); GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.orco); } - DRWBatchFlag batch_map = BATCH_MAP(vbo.uv, vbo.tan, vbo.vcol, vbo.orco); + DRWBatchFlag batch_map = BATCH_MAP(vbo.uv, vbo.tan, vbo.orco); mesh_batch_cache_discard_batch(cache, batch_map); mesh_cd_layers_type_clear(&cache->cd_used); } @@ -1070,42 +879,35 @@ static void texpaint_request_active_uv(MeshBatchCache *cache, Object *object, Me mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed); } -static void texpaint_request_active_vcol(MeshBatchCache *cache, Object *object, Mesh *me) -{ - DRW_MeshCDMask cd_needed; - mesh_cd_layers_type_clear(&cd_needed); - mesh_cd_calc_active_mloopcol_layer(object, me, &cd_needed); - - BLI_assert(cd_needed.vcol != 0 && - "No MLOOPCOL layer available in vertpaint, but batches requested anyway!"); - - mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed); -} - -static void sculpt_request_active_vcol(MeshBatchCache *cache, Object *object, Mesh *me) +static void request_active_and_default_color_attributes(const Object &object, + const Mesh &mesh, + DRW_Attributes &attributes) { - const Mesh *me_final = editmesh_final_or_this(object, me); + const Mesh *me_final = editmesh_final_or_this(&object, &mesh); const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); + /* Necessary because which attributes are active/default is stored in #CustomData. */ Mesh me_query = blender::dna::shallow_zero_initialize(); BKE_id_attribute_copy_domains_temp( ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); - const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id); - const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id); - - int active_i = BKE_id_attribute_to_index( - &me_query.id, active, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); - int render_i = BKE_id_attribute_to_index( - &me_query.id, render, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + auto request_color_attribute = [&](const char *name) { + int layer_index; + eCustomDataType type; + if (drw_custom_data_match_attribute(cd_vdata, name, &layer_index, &type)) { + drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_POINT); + } + else if (drw_custom_data_match_attribute(cd_ldata, name, &layer_index, &type)) { + drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_CORNER); + } + }; - if (active_i >= 0) { - cache->cd_needed.vcol |= 1UL << (uint)active_i; + if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) { + request_color_attribute(active->name); } - - if (render_i >= 0) { - cache->cd_needed.vcol |= 1UL << (uint)render_i; + if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) { + request_color_attribute(render->name); } } @@ -1214,7 +1016,13 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Object *object, Mesh GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); - texpaint_request_active_vcol(cache, object, me); + + DRW_Attributes attrs_needed{}; + request_active_and_default_color_attributes(*object, *me, attrs_needed); + + ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex; + drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex); + mesh_batch_cache_request_surface_batches(cache); return cache->batch.surface; } @@ -1222,7 +1030,13 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me) GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Object *object, Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); - sculpt_request_active_vcol(cache, object, me); + + DRW_Attributes attrs_needed{}; + request_active_and_default_color_attributes(*object, *me, attrs_needed); + + ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex; + drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex); + mesh_batch_cache_request_surface_batches(cache); return cache->batch.surface; } @@ -1621,9 +1435,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, if (cache->cd_used.sculpt_overlays != cache->cd_needed.sculpt_overlays) { GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.sculpt_data); } - if ((cache->cd_used.vcol & cache->cd_needed.vcol) != cache->cd_needed.vcol) { - GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.vcol); - } if (!drw_attributes_overlap(&cache->attr_used, &cache->attr_needed)) { for (int i = 0; i < GPU_MAX_ATTR; i++) { GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.attr[i]); @@ -1710,15 +1521,26 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, MeshBufferList *mbuflist = &cache->final.buff; /* Initialize batches and request VBO's & IBO's. */ - assert_deps_valid( - MBC_SURFACE, - {BUFFER_INDEX(ibo.tris), BUFFER_INDEX(vbo.lnor), BUFFER_INDEX(vbo.pos_nor), - BUFFER_INDEX(vbo.uv), BUFFER_INDEX(vbo.vcol), BUFFER_INDEX(vbo.attr[0]), - BUFFER_INDEX(vbo.attr[1]), BUFFER_INDEX(vbo.attr[2]), BUFFER_INDEX(vbo.attr[3]), - BUFFER_INDEX(vbo.attr[4]), BUFFER_INDEX(vbo.attr[5]), BUFFER_INDEX(vbo.attr[6]), - BUFFER_INDEX(vbo.attr[7]), BUFFER_INDEX(vbo.attr[8]), BUFFER_INDEX(vbo.attr[9]), - BUFFER_INDEX(vbo.attr[10]), BUFFER_INDEX(vbo.attr[11]), BUFFER_INDEX(vbo.attr[12]), - BUFFER_INDEX(vbo.attr[13]), BUFFER_INDEX(vbo.attr[14])}); + assert_deps_valid(MBC_SURFACE, + {BUFFER_INDEX(ibo.tris), + BUFFER_INDEX(vbo.lnor), + BUFFER_INDEX(vbo.pos_nor), + BUFFER_INDEX(vbo.uv), + BUFFER_INDEX(vbo.attr[0]), + BUFFER_INDEX(vbo.attr[1]), + BUFFER_INDEX(vbo.attr[2]), + BUFFER_INDEX(vbo.attr[3]), + BUFFER_INDEX(vbo.attr[4]), + BUFFER_INDEX(vbo.attr[5]), + BUFFER_INDEX(vbo.attr[6]), + BUFFER_INDEX(vbo.attr[7]), + BUFFER_INDEX(vbo.attr[8]), + BUFFER_INDEX(vbo.attr[9]), + BUFFER_INDEX(vbo.attr[10]), + BUFFER_INDEX(vbo.attr[11]), + BUFFER_INDEX(vbo.attr[12]), + BUFFER_INDEX(vbo.attr[13]), + BUFFER_INDEX(vbo.attr[14])}); if (DRW_batch_requested(cache->batch.surface, GPU_PRIM_TRIS)) { DRW_ibo_request(cache->batch.surface, &mbuflist->ibo.tris); /* Order matters. First ones override latest VBO's attributes. */ @@ -1727,9 +1549,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, if (cache->cd_used.uv != 0) { DRW_vbo_request(cache->batch.surface, &mbuflist->vbo.uv); } - if (cache->cd_used.vcol != 0) { - DRW_vbo_request(cache->batch.surface, &mbuflist->vbo.vcol); - } drw_add_attributes_vbo(cache->batch.surface, mbuflist, &cache->attr_used); } assert_deps_valid(MBC_ALL_VERTS, {BUFFER_INDEX(vbo.pos_nor)}); @@ -1807,12 +1626,12 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, assert_deps_valid( MBC_SURFACE_PER_MAT, {BUFFER_INDEX(vbo.lnor), BUFFER_INDEX(vbo.pos_nor), BUFFER_INDEX(vbo.uv), - BUFFER_INDEX(vbo.tan), BUFFER_INDEX(vbo.vcol), BUFFER_INDEX(vbo.orco), - BUFFER_INDEX(vbo.attr[0]), BUFFER_INDEX(vbo.attr[1]), BUFFER_INDEX(vbo.attr[2]), - BUFFER_INDEX(vbo.attr[3]), BUFFER_INDEX(vbo.attr[4]), BUFFER_INDEX(vbo.attr[5]), - BUFFER_INDEX(vbo.attr[6]), BUFFER_INDEX(vbo.attr[7]), BUFFER_INDEX(vbo.attr[8]), - BUFFER_INDEX(vbo.attr[9]), BUFFER_INDEX(vbo.attr[10]), BUFFER_INDEX(vbo.attr[11]), - BUFFER_INDEX(vbo.attr[12]), BUFFER_INDEX(vbo.attr[13]), BUFFER_INDEX(vbo.attr[14])}); + BUFFER_INDEX(vbo.tan), BUFFER_INDEX(vbo.orco), BUFFER_INDEX(vbo.attr[0]), + BUFFER_INDEX(vbo.attr[1]), BUFFER_INDEX(vbo.attr[2]), BUFFER_INDEX(vbo.attr[3]), + BUFFER_INDEX(vbo.attr[4]), BUFFER_INDEX(vbo.attr[5]), BUFFER_INDEX(vbo.attr[6]), + BUFFER_INDEX(vbo.attr[7]), BUFFER_INDEX(vbo.attr[8]), BUFFER_INDEX(vbo.attr[9]), + BUFFER_INDEX(vbo.attr[10]), BUFFER_INDEX(vbo.attr[11]), BUFFER_INDEX(vbo.attr[12]), + BUFFER_INDEX(vbo.attr[13]), BUFFER_INDEX(vbo.attr[14])}); assert_deps_valid(MBC_SURFACE_PER_MAT, {TRIS_PER_MAT_INDEX}); for (int i = 0; i < cache->mat_len; i++) { if (DRW_batch_requested(cache->surface_per_mat[i], GPU_PRIM_TRIS)) { @@ -1826,9 +1645,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, if ((cache->cd_used.tan != 0) || (cache->cd_used.tan_orco != 0)) { DRW_vbo_request(cache->surface_per_mat[i], &mbuflist->vbo.tan); } - if (cache->cd_used.vcol != 0) { - DRW_vbo_request(cache->surface_per_mat[i], &mbuflist->vbo.vcol); - } if (cache->cd_used.orco != 0) { DRW_vbo_request(cache->surface_per_mat[i], &mbuflist->vbo.orco); } @@ -1994,7 +1810,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, assert_final_deps_valid(BUFFER_INDEX(vbo.lnor)); assert_final_deps_valid(BUFFER_INDEX(vbo.pos_nor)); assert_final_deps_valid(BUFFER_INDEX(vbo.uv)); - assert_final_deps_valid(BUFFER_INDEX(vbo.vcol)); assert_final_deps_valid(BUFFER_INDEX(vbo.sculpt_data)); assert_final_deps_valid(BUFFER_INDEX(vbo.weights)); assert_final_deps_valid(BUFFER_INDEX(vbo.edge_fac)); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 8052b277d45..a4773736f0c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -86,6 +86,9 @@ struct MeshRenderData { float (*loop_normals)[3]; int *lverts, *ledges; + const char *active_color_name; + const char *default_color_name; + struct { int *tri_first_index; int *mat_tri_len; @@ -93,6 +96,82 @@ struct MeshRenderData { } poly_sorted; }; +BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *me) +{ + if (me->edit_mesh != nullptr) { + Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object); + if (editmesh_eval_final != nullptr) { + return editmesh_eval_final; + } + } + + return me; +} + +BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me) +{ + switch ((eMeshWrapperType)me->runtime.wrapper_type) { + case ME_WRAPPER_TYPE_SUBD: + case ME_WRAPPER_TYPE_MDATA: + return &me->ldata; + break; + case ME_WRAPPER_TYPE_BMESH: + return &me->edit_mesh->bm->ldata; + break; + } + + BLI_assert(0); + return &me->ldata; +} + +BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me) +{ + switch ((eMeshWrapperType)me->runtime.wrapper_type) { + case ME_WRAPPER_TYPE_SUBD: + case ME_WRAPPER_TYPE_MDATA: + return &me->pdata; + break; + case ME_WRAPPER_TYPE_BMESH: + return &me->edit_mesh->bm->pdata; + break; + } + + BLI_assert(0); + return &me->pdata; +} + +BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me) +{ + switch ((eMeshWrapperType)me->runtime.wrapper_type) { + case ME_WRAPPER_TYPE_SUBD: + case ME_WRAPPER_TYPE_MDATA: + return &me->edata; + break; + case ME_WRAPPER_TYPE_BMESH: + return &me->edit_mesh->bm->edata; + break; + } + + BLI_assert(0); + return &me->edata; +} + +BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me) +{ + switch ((eMeshWrapperType)me->runtime.wrapper_type) { + case ME_WRAPPER_TYPE_SUBD: + case ME_WRAPPER_TYPE_MDATA: + return &me->vdata; + break; + case ME_WRAPPER_TYPE_BMESH: + return &me->edit_mesh->bm->vdata; + break; + } + + BLI_assert(0); + return &me->vdata; +} + BLI_INLINE BMFace *bm_original_face_get(const MeshRenderData *mr, int idx) { return ((mr->p_origindex != NULL) && (mr->p_origindex[idx] != ORIGINDEX_NONE) && mr->bm) ? diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index b98af3be17f..7f16837022c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -9,6 +9,7 @@ #include <functional> +#include "BLI_color.hh" #include "BLI_math_vec_types.hh" #include "BLI_string.h" @@ -74,6 +75,18 @@ template<> struct AttributeTypeConverter<MPropCol, gpuMeshCol> { } }; +template<> struct AttributeTypeConverter<ColorGeometry4b, gpuMeshCol> { + static gpuMeshCol convert_value(ColorGeometry4b value) + { + gpuMeshCol result; + result.r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]); + result.g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]); + result.b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]); + result.a = unit_float_to_ushort_clamp(value.a * (1.0f / 255.0f)); + return result; + } +}; + /* Return the number of component for the attribute's value type, or 0 if is it unsupported. */ static uint gpu_component_size_for_attribute_type(eCustomDataType type) { @@ -90,6 +103,7 @@ static uint gpu_component_size_for_attribute_type(eCustomDataType type) case CD_PROP_FLOAT3: return 3; case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: return 4; default: return 0; @@ -102,6 +116,7 @@ static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type) case CD_PROP_INT32: return GPU_FETCH_INT_TO_FLOAT; case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: return GPU_FETCH_INT_TO_FLOAT_UNIT; default: return GPU_FETCH_FLOAT; @@ -114,13 +129,15 @@ static GPUVertCompType get_comp_type_for_type(eCustomDataType type) case CD_PROP_INT32: return GPU_COMP_I32; case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: return GPU_COMP_U16; default: return GPU_COMP_F32; } } -static void init_vbo_for_attribute(GPUVertBuf *vbo, +static void init_vbo_for_attribute(const MeshRenderData &mr, + GPUVertBuf *vbo, const DRW_AttributeRequest &request, bool build_on_device, uint32_t len) @@ -140,6 +157,13 @@ static void init_vbo_for_attribute(GPUVertBuf *vbo, GPU_vertformat_deinterleave(&format); GPU_vertformat_attr_add(&format, attr_name, comp_type, comp_size, fetch_mode); + if (mr.active_color_name && STREQ(request.attribute_name, mr.active_color_name)) { + GPU_vertformat_alias_add(&format, "ac"); + } + if (mr.default_color_name && STREQ(request.attribute_name, mr.default_color_name)) { + GPU_vertformat_alias_add(&format, "c"); + } + if (build_on_device) { GPU_vertbuf_init_build_on_device(vbo, &format, len); } @@ -262,7 +286,7 @@ static void extract_attr_init( GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); - init_vbo_for_attribute(vbo, request, false, static_cast<uint32_t>(mr->loop_len)); + init_vbo_for_attribute(*mr, vbo, request, false, static_cast<uint32_t>(mr->loop_len)); /* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by * OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the @@ -290,6 +314,9 @@ static void extract_attr_init( case CD_PROP_COLOR: extract_attr_generic<MPropCol, gpuMeshCol>(mr, vbo, request); break; + case CD_PROP_BYTE_COLOR: + extract_attr_generic<ColorGeometry4b, gpuMeshCol>(mr, vbo, request); + break; default: BLI_assert_unreachable(); } @@ -338,12 +365,15 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache, case CD_PROP_COLOR: extract_attr_generic<MPropCol, gpuMeshCol>(mr, src_data, request); break; + case CD_PROP_BYTE_COLOR: + extract_attr_generic<ColorGeometry4b, gpuMeshCol>(mr, src_data, request); + break; default: BLI_assert_unreachable(); } GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer); - init_vbo_for_attribute(dst_buffer, request, true, subdiv_cache->num_subdiv_loops); + init_vbo_for_attribute(*mr, dst_buffer, request, true, subdiv_cache->num_subdiv_loops); /* Ensure data is uploaded properly. */ GPU_vertbuf_tag_dirty(src_data); @@ -352,7 +382,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache, dst_buffer, static_cast<int>(dimensions), 0, - request.cd_type == CD_PROP_COLOR); + ELEM(request.cd_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)); GPU_vertbuf_discard(src_data); } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc deleted file mode 100644 index 419cbb0267f..00000000000 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc +++ /dev/null @@ -1,387 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2021 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup draw - */ - -#include "MEM_guardedalloc.h" - -#include "BKE_attribute.h" -#include "BLI_string.h" -#include "BLI_vector.hh" - -#include "draw_subdivision.h" -#include "extract_mesh.hh" - -namespace blender::draw { - -struct VColRef { - const CustomDataLayer *layer; - eAttrDomain domain; -}; - -/** Get all vcol layers as AttributeRefs. - * - * \param vcol_layers: bitmask to filter vcol layers by, each bit - * corresponds to the integer position of the attribute - * within the global color attribute list. - */ -static Vector<VColRef> get_vcol_refs(const CustomData *cd_vdata, - const CustomData *cd_ldata, - const uint vcol_layers) -{ - Vector<VColRef> refs; - uint layeri = 0; - - auto buildList = [&](const CustomData *cdata, eAttrDomain domain) { - for (int i = 0; i < cdata->totlayer; i++) { - const CustomDataLayer *layer = cdata->layers + i; - - if (!(CD_TYPE_AS_MASK(layer->type) & CD_MASK_COLOR_ALL)) { - continue; - } - - if (layer->flag & CD_FLAG_TEMPORARY) { - continue; - } - - if (!(vcol_layers & (1UL << layeri))) { - layeri++; - continue; - } - - VColRef ref = {}; - ref.domain = domain; - ref.layer = layer; - - refs.append(ref); - layeri++; - } - }; - - buildList(cd_vdata, ATTR_DOMAIN_POINT); - buildList(cd_ldata, ATTR_DOMAIN_CORNER); - - return refs; -} - -/* ---------------------------------------------------------------------- */ -/** \name Extract VCol - * \{ */ - -/* Initialize the common vertex format for vcol for coarse and subdivided meshes. */ -static void init_vcol_format(GPUVertFormat *format, - const MeshBatchCache *cache, - const CustomData *cd_vdata, - const CustomData *cd_ldata, - const CustomDataLayer *active, - const CustomDataLayer *render) -{ - GPU_vertformat_deinterleave(format); - - const uint32_t vcol_layers = cache->cd_used.vcol; - - Vector<VColRef> refs = get_vcol_refs(cd_vdata, cd_ldata, vcol_layers); - - for (const VColRef &ref : refs) { - char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - - GPU_vertformat_safe_attr_name(ref.layer->name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); - - /* VCol layer name. */ - BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name); - GPU_vertformat_attr_add(format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - - /* Active layer name. */ - if (ref.layer == active) { - GPU_vertformat_alias_add(format, "ac"); - } - - /* Active render layer name. */ - if (ref.layer == render) { - GPU_vertformat_alias_add(format, "c"); - } - } -} - -/* Vertex format for vertex colors, only used during the coarse data upload for the subdivision - * case. */ -static GPUVertFormat *get_coarse_vcol_format() -{ - static GPUVertFormat format = {0}; - if (format.attr_len == 0) { - GPU_vertformat_attr_add(&format, "cCol", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - GPU_vertformat_alias_add(&format, "c"); - GPU_vertformat_alias_add(&format, "ac"); - } - return &format; -} - -struct gpuMeshVcol { - ushort r, g, b, a; -}; - -static void extract_vcol_init(const MeshRenderData *mr, - MeshBatchCache *cache, - void *buf, - void *UNUSED(tls_data)) -{ - GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); - GPUVertFormat format = {0}; - - const CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : - &mr->me->vdata; - const CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : - &mr->me->ldata; - - Mesh me_query = blender::dna::shallow_zero_initialize(); - - BKE_id_attribute_copy_domains_temp( - ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); - - const CustomDataLayer *active_color = BKE_id_attributes_active_color_get(&me_query.id); - const CustomDataLayer *render_color = BKE_id_attributes_render_color_get(&me_query.id); - - const uint32_t vcol_layers = cache->cd_used.vcol; - init_vcol_format(&format, cache, cd_vdata, cd_ldata, active_color, render_color); - - GPU_vertbuf_init_with_format(vbo, &format); - GPU_vertbuf_data_alloc(vbo, mr->loop_len); - - gpuMeshVcol *vcol_data = (gpuMeshVcol *)GPU_vertbuf_get_data(vbo); - - Vector<VColRef> refs = get_vcol_refs(cd_vdata, cd_ldata, vcol_layers); - - for (const VColRef &ref : refs) { - const CustomData *cdata = ref.domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata; - - if (mr->extract_type == MR_EXTRACT_BMESH) { - int cd_ofs = ref.layer->offset; - - if (cd_ofs == -1) { - vcol_data += ref.domain == ATTR_DOMAIN_POINT ? mr->bm->totvert : mr->bm->totloop; - continue; - } - - BMIter iter; - const bool is_byte = ref.layer->type == CD_PROP_BYTE_COLOR; - const bool is_point = ref.domain == ATTR_DOMAIN_POINT; - - BMFace *f; - BM_ITER_MESH (f, &iter, mr->bm, BM_FACES_OF_MESH) { - const BMLoop *l_iter = f->l_first; - do { - const BMElem *elem = is_point ? reinterpret_cast<const BMElem *>(l_iter->v) : - reinterpret_cast<const BMElem *>(l_iter); - if (is_byte) { - const MLoopCol *mloopcol = (const MLoopCol *)BM_ELEM_CD_GET_VOID_P(elem, cd_ofs); - vcol_data->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->r]); - vcol_data->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->g]); - vcol_data->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->b]); - vcol_data->a = unit_float_to_ushort_clamp(mloopcol->a * (1.0f / 255.0f)); - vcol_data++; - } - else { - const MPropCol *mpcol = (const MPropCol *)BM_ELEM_CD_GET_VOID_P(elem, cd_ofs); - vcol_data->r = unit_float_to_ushort_clamp(mpcol->color[0]); - vcol_data->g = unit_float_to_ushort_clamp(mpcol->color[1]); - vcol_data->b = unit_float_to_ushort_clamp(mpcol->color[2]); - vcol_data->a = unit_float_to_ushort_clamp(mpcol->color[3]); - vcol_data++; - } - } while ((l_iter = l_iter->next) != f->l_first); - } - } - else { - int totloop = mr->loop_len; - const int idx = CustomData_get_named_layer_index(cdata, ref.layer->type, ref.layer->name); - - const MLoopCol *mcol = nullptr; - const MPropCol *pcol = nullptr; - const MLoop *mloop = mr->mloop; - - if (ref.layer->type == CD_PROP_COLOR) { - pcol = static_cast<const MPropCol *>(cdata->layers[idx].data); - } - else { - mcol = static_cast<const MLoopCol *>(cdata->layers[idx].data); - } - - const bool is_corner = ref.domain == ATTR_DOMAIN_CORNER; - - for (int i = 0; i < totloop; i++, mloop++) { - const int v_i = is_corner ? i : mloop->v; - - if (mcol) { - vcol_data->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[v_i].r]); - vcol_data->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[v_i].g]); - vcol_data->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[v_i].b]); - vcol_data->a = unit_float_to_ushort_clamp(mcol[v_i].a * (1.0f / 255.0f)); - vcol_data++; - } - else if (pcol) { - vcol_data->r = unit_float_to_ushort_clamp(pcol[v_i].color[0]); - vcol_data->g = unit_float_to_ushort_clamp(pcol[v_i].color[1]); - vcol_data->b = unit_float_to_ushort_clamp(pcol[v_i].color[2]); - vcol_data->a = unit_float_to_ushort_clamp(pcol[v_i].color[3]); - vcol_data++; - } - } - } - } -} - -static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, - const MeshRenderData *mr, - MeshBatchCache *cache, - void *buffer, - void *UNUSED(data)) -{ - GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer); - const Mesh *coarse_mesh = subdiv_cache->mesh; - - bool extract_bmesh = mr->extract_type == MR_EXTRACT_BMESH; - - const CustomData *cd_vdata = extract_bmesh ? &coarse_mesh->edit_mesh->bm->vdata : - &coarse_mesh->vdata; - const CustomData *cd_ldata = extract_bmesh ? &coarse_mesh->edit_mesh->bm->ldata : - &coarse_mesh->ldata; - const int totloop = extract_bmesh ? coarse_mesh->edit_mesh->bm->totloop : coarse_mesh->totloop; - - Mesh me_query = blender::dna::shallow_copy(*coarse_mesh); - BKE_id_attribute_copy_domains_temp( - ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); - - const CustomDataLayer *active_color = BKE_id_attributes_active_color_get(&me_query.id); - const CustomDataLayer *render_color = BKE_id_attributes_render_color_get(&me_query.id); - - GPUVertFormat format = {0}; - init_vcol_format( - &format, cache, &coarse_mesh->vdata, &coarse_mesh->ldata, active_color, render_color); - - GPU_vertbuf_init_build_on_device(dst_buffer, &format, subdiv_cache->num_subdiv_loops); - - GPUVertBuf *src_data = GPU_vertbuf_calloc(); - /* Dynamic as we upload and interpolate layers one at a time. */ - GPU_vertbuf_init_with_format_ex(src_data, get_coarse_vcol_format(), GPU_USAGE_DYNAMIC); - - GPU_vertbuf_data_alloc(src_data, totloop); - - gpuMeshVcol *mesh_vcol = (gpuMeshVcol *)GPU_vertbuf_get_data(src_data); - - const uint vcol_layers = cache->cd_used.vcol; - - Vector<VColRef> refs = get_vcol_refs(cd_vdata, cd_ldata, vcol_layers); - - /* Index of the vertex color layer in the compact buffer. Used vertex color layers are stored in - * a single buffer. */ - int pack_layer_index = 0; - for (const VColRef &ref : refs) { - /* Include stride in offset, we use a stride of 2 since colors are packed into 2 uints. */ - const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 2 * pack_layer_index++; - - const CustomData *cdata = ref.domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata; - int layer_i = CustomData_get_named_layer_index(cdata, ref.layer->type, ref.layer->name); - - if (layer_i == -1) { - printf("%s: missing color layer %s\n", __func__, ref.layer->name); - continue; - } - - gpuMeshVcol *vcol = mesh_vcol; - - const bool is_vert = ref.domain == ATTR_DOMAIN_POINT; - - if (extract_bmesh) { - BMesh *bm = coarse_mesh->edit_mesh->bm; - BMIter iter; - BMFace *f; - int cd_ofs = cdata->layers[layer_i].offset; - const bool is_byte = ref.layer->type == CD_PROP_BYTE_COLOR; - - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - const BMLoop *l_iter = f->l_first; - - do { - const BMElem *elem = is_vert ? reinterpret_cast<const BMElem *>(l_iter->v) : - reinterpret_cast<const BMElem *>(l_iter); - - if (is_byte) { - const MLoopCol *mcol2 = static_cast<const MLoopCol *>( - BM_ELEM_CD_GET_VOID_P(elem, cd_ofs)); - - vcol->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->r]); - vcol->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->g]); - vcol->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->b]); - vcol->a = unit_float_to_ushort_clamp(mcol2->a * (1.0f / 255.0f)); - } - else { - const MPropCol *pcol2 = static_cast<const MPropCol *>( - BM_ELEM_CD_GET_VOID_P(elem, cd_ofs)); - - vcol->r = unit_float_to_ushort_clamp(pcol2->color[0]); - vcol->g = unit_float_to_ushort_clamp(pcol2->color[1]); - vcol->b = unit_float_to_ushort_clamp(pcol2->color[2]); - vcol->a = unit_float_to_ushort_clamp(pcol2->color[3]); - } - - vcol++; - } while ((l_iter = l_iter->next) != f->l_first); - } - } - else { - const MLoop *ml = coarse_mesh->mloop; - const MLoopCol *mcol = nullptr; - const MPropCol *pcol = nullptr; - - if (ref.layer->type == CD_PROP_COLOR) { - pcol = static_cast<const MPropCol *>(cdata->layers[layer_i].data); - } - else { - mcol = static_cast<const MLoopCol *>(cdata->layers[layer_i].data); - } - - for (int ml_index = 0; ml_index < coarse_mesh->totloop; ml_index++, vcol++, ml++) { - int idx = is_vert ? ml->v : ml_index; - - if (mcol) { - vcol->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[idx].r]); - vcol->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[idx].g]); - vcol->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol[idx].b]); - vcol->a = unit_float_to_ushort_clamp(mcol[idx].a * (1.0f / 255.0f)); - } - else if (pcol) { - vcol->r = unit_float_to_ushort_clamp(pcol[idx].color[0]); - vcol->g = unit_float_to_ushort_clamp(pcol[idx].color[1]); - vcol->b = unit_float_to_ushort_clamp(pcol[idx].color[2]); - vcol->a = unit_float_to_ushort_clamp(pcol[idx].color[3]); - } - } - } - - /* Ensure data is uploaded properly. */ - GPU_vertbuf_tag_dirty(src_data); - draw_subdiv_interp_custom_data(subdiv_cache, src_data, dst_buffer, 4, dst_offset, true); - } - - GPU_vertbuf_discard(src_data); -} - -constexpr MeshExtract create_extractor_vcol() -{ - MeshExtract extractor = {nullptr}; - extractor.init = extract_vcol_init; - extractor.init_subdiv = extract_vcol_init_subdiv; - extractor.data_type = MR_DATA_NONE; - extractor.data_size = 0; - extractor.use_threading = false; - extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.vcol); - return extractor; -} - -/** \} */ - -} // namespace blender::draw - -const MeshExtract extract_vcol = blender::draw::create_extractor_vcol(); diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index c9c96900af3..c612a84a631 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -1601,6 +1601,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } } + BKE_gpencil_stroke_geometry_update(gpd, gps); } } } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc index 907c2c29c42..e1ac941eb2b 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc @@ -188,6 +188,7 @@ struct DensityAddOperationExecutor { * curves. */ Array<bool> new_curve_skipped(new_positions_cu.size(), false); threading::parallel_invoke( + 512 < already_added_curves + new_positions_cu.size(), /* Build kdtree from root points created by the current stroke. */ [&]() { for (const int i : IndexRange(already_added_curves)) { @@ -309,6 +310,7 @@ struct DensityAddOperationExecutor { }; threading::parallel_invoke( + 1024 < original_positions.size() + deformed_positions.size(), [&]() { self_->original_curve_roots_kdtree_ = roots_kdtree_from_positions(original_positions); }, diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 02ebd622469..4ae4149a2a0 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -734,6 +734,8 @@ static void select_grow_invoke_per_curve(Curves &curves_id, } threading::parallel_invoke( + 1024 < curve_op_data.selected_point_indices.size() + + curve_op_data.unselected_point_indices.size(), [&]() { /* Build KD-tree for the selected points. */ KDTree_3d *kdtree = BLI_kdtree_3d_new(curve_op_data.selected_point_indices.size()); diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 3e507f73d1a..166a4351377 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -90,7 +90,6 @@ static SpaceLink *action_create(const ScrArea *area, const Scene *scene) BLI_addtail(&saction->regionbase, region); region->regiontype = RGN_TYPE_UI; region->alignment = RGN_ALIGN_RIGHT; - region->flag = RGN_FLAG_HIDDEN; /* main region */ region = MEM_callocN(sizeof(ARegion), "main region for action"); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 43621d74e79..3dd21fd22c6 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -90,7 +90,6 @@ static SpaceLink *graph_create(const ScrArea *UNUSED(area), const Scene *scene) BLI_addtail(&sipo->regionbase, region); region->regiontype = RGN_TYPE_UI; region->alignment = RGN_ALIGN_RIGHT; - region->flag = RGN_FLAG_HIDDEN; /* main region */ region = MEM_callocN(sizeof(ARegion), "main region for graphedit"); diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 13035a9d5fd..1dd5bb41fef 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -79,7 +79,6 @@ static SpaceLink *nla_create(const ScrArea *area, const Scene *scene) BLI_addtail(&snla->regionbase, region); region->regiontype = RGN_TYPE_UI; region->alignment = RGN_ALIGN_RIGHT; - region->flag = RGN_FLAG_HIDDEN; /* main region */ region = MEM_callocN(sizeof(ARegion), "main region for nla"); diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 66e07c804b6..25ab06850f5 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1455,7 +1455,11 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout } case SOCK_BOOLEAN: case SOCK_RGBA: - case SOCK_STRING: { + case SOCK_STRING: + case SOCK_OBJECT: + case SOCK_COLLECTION: + case SOCK_TEXTURE: + case SOCK_MATERIAL: { uiItemR(col, ptr, "default_value", DEFAULT_FLAGS, IFACE_("Default"), 0); break; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc index 780dd0303cd..3fe4c7c8ee0 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc @@ -287,7 +287,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { for (const int i : values.index_range()) { std::stringstream ss; const float value = values[i]; - ss << std::fixed << std::setprecision(3) << value; + ss << " " << std::fixed << std::setprecision(3) << value; const std::string value_str = ss.str(); uiBut *but = uiDefIconTextBut(params.block, UI_BTYPE_LABEL, @@ -318,7 +318,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { for (const int i : values.index_range()) { std::stringstream ss; const float value = values[i]; - ss << std::fixed << std::setprecision(3) << value; + ss << " " << std::fixed << std::setprecision(3) << value; const std::string value_str = ss.str(); uiBut *but = uiDefIconTextBut(params.block, UI_BTYPE_LABEL, diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index c0633f0323d..3ca465fa57a 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -131,6 +131,11 @@ typedef void (*GPUCodegenCallbackFn)(void *thunk, GPUMaterial *mat, GPUCodegenOu GPUNodeLink *GPU_constant(const float *num); GPUNodeLink *GPU_uniform(const float *num); GPUNodeLink *GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name); +/** + * Add a GPU attribute that refers to the default color attribute on a geometry. + * The name, type, and domain are unknown and do not depend on the material. + */ +GPUNodeLink *GPU_attribute_default_color(GPUMaterial *mat); GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, eCustomDataType type, const char *name, @@ -266,6 +271,12 @@ typedef struct GPUMaterialAttribute { eGPUDefaultValue default_value; /* Only for volumes attributes. */ int id; int users; + /** + * If true, the corresponding attribute is the specified default color attribute on the mesh, + * if it exists. In that case the type and name data can vary per geometry, so it will not be + * valid here. + */ + bool is_default_color; } GPUMaterialAttribute; typedef struct GPUMaterialTexture { diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index 1338c5312c2..684070dbdc0 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -328,13 +328,14 @@ void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph) /* Attributes and Textures */ -static char attr_prefix_get(eCustomDataType type) +static char attr_prefix_get(GPUMaterialAttribute *attr) { - switch (type) { + if (attr->is_default_color) { + return 'c'; + } + switch (attr->type) { case CD_TANGENT: return 't'; - case CD_MCOL: - return 'c'; case CD_AUTO_FROM_NAME: return 'a'; case CD_HAIRLENGTH: @@ -353,7 +354,7 @@ static void attr_input_name(GPUMaterialAttribute *attr) STRNCPY(attr->input_name, "orco"); } else { - attr->input_name[0] = attr_prefix_get(attr->type); + attr->input_name[0] = attr_prefix_get(attr); attr->input_name[1] = '\0'; if (attr->name[0] != '\0') { /* XXX FIXME: see notes in mesh_render_data_create() */ @@ -365,13 +366,15 @@ static void attr_input_name(GPUMaterialAttribute *attr) /** Add a new varying attribute of given type and name. Returns NULL if out of slots. */ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, eCustomDataType type, - const char *name) + const char *name, + const bool is_default_color) { /* Find existing attribute. */ int num_attributes = 0; GPUMaterialAttribute *attr = graph->attributes.first; for (; attr; attr = attr->next) { - if (attr->type == type && STREQ(attr->name, name)) { + if (attr->type == type && STREQ(attr->name, name) && + attr->is_default_color == is_default_color) { break; } num_attributes++; @@ -380,6 +383,7 @@ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, /* Add new requested attribute if it's within GPU limits. */ if (attr == NULL) { attr = MEM_callocN(sizeof(*attr), __func__); + attr->is_default_color = is_default_color; attr->type = type; STRNCPY(attr->name, name); attr_input_name(attr); @@ -471,7 +475,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const char *name) { GPUNodeGraph *graph = gpu_material_node_graph(mat); - GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name); + GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name, false); if (type == CD_ORCO) { /* OPTI: orco might be computed from local positions and needs object infos. */ @@ -490,6 +494,21 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const c return link; } +GPUNodeLink *GPU_attribute_default_color(GPUMaterial *mat) +{ + GPUNodeGraph *graph = gpu_material_node_graph(mat); + GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, CD_AUTO_FROM_NAME, "", true); + if (attr == NULL) { + static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f}; + return GPU_constant(zero_data); + } + attr->is_default_color = true; + GPUNodeLink *link = gpu_node_link_create(); + link->link_type = GPU_NODE_LINK_ATTR; + link->attr = attr; + return link; +} + GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, const eCustomDataType type, const char *name, diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c index 8cd83ddcf12..4657f7e9a9f 100644 --- a/source/blender/makesrna/intern/rna_collection.c +++ b/source/blender/makesrna/intern/rna_collection.c @@ -359,6 +359,14 @@ static void rna_Collection_color_tag_update(Main *UNUSED(bmain), WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, scene); } +static void rna_Collection_instance_offset_update(Main *UNUSED(bmain), + Scene *UNUSED(scene), + PointerRNA *ptr) +{ + Collection *collection = (Collection *)ptr->data; + DEG_id_tag_update(&collection->id, ID_RECALC_GEOMETRY); +} + #else /* collection.objects */ @@ -433,7 +441,7 @@ void RNA_def_collections(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Instance Offset", "Offset from the origin to use when instancing"); RNA_def_property_ui_range(prop, -10000.0, 10000.0, 10, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Collection_instance_offset_update"); prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index c2d17f73023..a3c5b14d6f5 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -11532,6 +11532,8 @@ static void rna_def_node_socket_object(BlenderRNA *brna, RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_image(BlenderRNA *brna, @@ -11568,6 +11570,8 @@ static void rna_def_node_socket_image(BlenderRNA *brna, RNA_def_property_struct_type(prop, "Image"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_geometry(BlenderRNA *brna, @@ -11619,6 +11623,8 @@ static void rna_def_node_socket_collection(BlenderRNA *brna, RNA_def_property_struct_type(prop, "Collection"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_texture(BlenderRNA *brna, @@ -11655,6 +11661,8 @@ static void rna_def_node_socket_texture(BlenderRNA *brna, RNA_def_property_struct_type(prop, "Texture"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_material(BlenderRNA *brna, @@ -11695,6 +11703,8 @@ static void rna_def_node_socket_material(BlenderRNA *brna, prop, NULL, NULL, NULL, "rna_NodeSocketMaterial_default_value_poll"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_standard_types(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index e67d840eeac..5cee2ca00a3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4554,7 +4554,7 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) RNA_def_property_enum_items(prop, rna_enum_curve_display_handle_items); RNA_def_property_ui_text( prop, "Display Handles", "Limit the display of curve handles in edit mode"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPencil_update"); prop = RNA_def_property(srna, "show_curve_normals", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "overlay.edit_flag", V3D_OVERLAY_EDIT_CU_NORMALS); diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index 8b653296e12..e739b052b6b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -60,6 +60,7 @@ static void deform_curves(const CurvesGeometry &curves, Array<ReverseUVSampler::Result> surface_samples_old(curves_num); Array<ReverseUVSampler::Result> surface_samples_new(curves_num); threading::parallel_invoke( + 1024 < curves_num, [&]() { reverse_uv_sampler_old.sample_many(curve_attachment_uvs, surface_samples_old); }, [&]() { reverse_uv_sampler_new.sample_many(curve_attachment_uvs, surface_samples_new); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc index 64861e529bc..7d44ac34f15 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc @@ -15,11 +15,11 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input<decl::Int>(N_("Index")).min(0).supports_field(); - b.add_input<decl::Float>(N_("Value"), "Value_Float").supports_field(); - b.add_input<decl::Int>(N_("Value"), "Value_Int").supports_field(); - b.add_input<decl::Vector>(N_("Value"), "Value_Vector").supports_field(); - b.add_input<decl::Color>(N_("Value"), "Value_Color").supports_field(); - b.add_input<decl::Bool>(N_("Value"), "Value_Bool").supports_field(); + b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field(); + b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field(); + b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field(); + b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field(); + b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field(); b.add_output<decl::Float>(N_("Value"), "Value_Float").field_source(); b.add_output<decl::Int>(N_("Value"), "Value_Int").field_source(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc index 2af86b4b1d2..a5edc6c4b3f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc @@ -183,6 +183,7 @@ Mesh *create_line_mesh(const float3 start, const float3 delta, const int count) MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; threading::parallel_invoke( + 1024 < count, [&]() { threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index a46bb40a3eb..85facf1e758 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -307,6 +307,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; threading::parallel_invoke( + 1024 < segments * rings, [&]() { MutableSpan vert_normals{(float3 *)BKE_mesh_vertex_normals_for_write(mesh), mesh->totvert}; calculate_sphere_vertex_data(verts, vert_normals, radius, segments, rings); diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc index 830f02d8df1..c636cc976e6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc @@ -42,9 +42,8 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat, GPUNodeStack *out) { NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage; - /* NOTE: using CD_AUTO_FROM_NAME instead of CD_MCOL or CD_PROP_COLOR for named attributes - * as geometry nodes may overwrite data which will also change the eCustomDataType. - * This will also make EEVEE and Cycles + /* NOTE: Using #CD_AUTO_FROM_NAME is necessary because there are multiple color attribute types, + * and the type may change during evaluation anyway. This will also make EEVEE and Cycles * consistent. See T93179. */ GPUNodeLink *vertexColorLink; @@ -53,7 +52,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat, vertexColorLink = GPU_attribute(mat, CD_AUTO_FROM_NAME, vertexColor->layer_name); } else { /* Fall back on active render color attribute. */ - vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name); + vertexColorLink = GPU_attribute_default_color(mat); } return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink); |