diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 29dc6f6c70c..f3142c6f001 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -6532,6 +6532,8 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) va_list args; uiStringInfo *si; + PointerRNA *opptr = UI_but_operator_ptr_get(but); + const EnumPropertyItem *items = nullptr, *item = nullptr; int totitems; bool free_items = false; @@ -6610,10 +6612,13 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } else if (but->optype) { if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(WM_operatortype_name(but->optype, but->opptr)); + tmp = BLI_strdup(WM_operatortype_name(but->optype, opptr)); } else { - tmp = WM_operatortype_description(C, but->optype, but->opptr); + bContextStore *previous_ctx = CTX_store_get(C); + CTX_store_set(C, but->context); + tmp = WM_operatortype_description(C, but->optype, opptr); + CTX_store_set(C, previous_ctx); } } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { @@ -6696,7 +6701,6 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) int(ui_but_value_get(but)); } else if (but->optype) { - PointerRNA *opptr = UI_but_operator_ptr_get(but); wmOperatorType *ot = but->optype; /* So the context is passed to `itemf` functions. */ diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 0e3e6f0ece9..05b481035ba 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -456,6 +456,22 @@ static int node_add_group_asset_invoke(bContext *C, wmOperator *op, const wmEven return OPERATOR_FINISHED; } +static char *node_add_group_asset_get_description(struct bContext *C, + struct wmOperatorType * /*op*/, + struct PointerRNA * /*values*/) +{ + bool is_valid; + const AssetHandle handle = CTX_wm_asset_handle(C, &is_valid); + if (!is_valid) { + return nullptr; + } + const AssetMetaData &asset_data = *ED_asset_handle_get_metadata(&handle); + if (!asset_data.description) { + return nullptr; + } + return BLI_strdup(asset_data.description); +} + void NODE_OT_add_group_asset(wmOperatorType *ot) { ot->name = "Add Node Group Asset"; @@ -464,6 +480,7 @@ void NODE_OT_add_group_asset(wmOperatorType *ot) ot->invoke = node_add_group_asset_invoke; ot->poll = node_add_group_poll; + ot->get_description = node_add_group_asset_get_description; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index a6d411a6ef0..0e73398f31e 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -951,14 +951,16 @@ void GPU_material_compile(GPUMaterial *mat) * As PSOs do not always match for default shaders, we limit warming for PSO * configurations to ensure compile time remains fast, as these first * entries will be the most commonly used PSOs. As not all PSOs are necessarily - * required immediately, this limit should remain low (1-3 at most). - * */ + * required immediately, this limit should remain low (1-3 at most). */ if (mat->default_mat != NULL && mat->default_mat != mat) { if (mat->default_mat->pass != NULL) { GPUShader *parent_sh = GPU_pass_shader_get(mat->default_mat->pass); if (parent_sh) { - GPU_shader_set_parent(sh, parent_sh); - GPU_shader_warm_cache(sh, 1); + /* Skip warming if cached pass is identical to the default material. */ + if (mat->default_mat->pass != mat->pass && parent_sh != sh) { + GPU_shader_set_parent(sh, parent_sh); + GPU_shader_warm_cache(sh, 1); + } } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc index 9e9bccb004e..94b12d9897b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc @@ -45,6 +45,31 @@ static Array accumulated_lengths_curve_domain(const bke::CurvesGeometry & return lengths; } +static Array calculate_curve_parameters(const bke::CurvesGeometry &curves) +{ + const VArray cyclic = curves.cyclic(); + Array lengths = accumulated_lengths_curve_domain(curves); + + const int last_index = curves.curves_num() - 1; + const float total_length = lengths.last() + curves.evaluated_length_total_for_curve( + last_index, cyclic[last_index]); + if (total_length > 0.0f) { + const float factor = 1.0f / total_length; + for (float &value : lengths) { + value *= factor; + } + } + else { + /* It is arbitrary what to do in those rare cases when all the points are + * in the same position. In this case we are just arbitrarily giving a valid + * value in the range based on the curve index. */ + for (const int i : lengths.index_range()) { + lengths[i] = i / (lengths.size() - 1.0f); + } + } + return lengths; +} + /** * Return the length of each control point along each curve, starting at zero for the first point. * Importantly, this is different than the length at each evaluated point. The implementation is @@ -55,7 +80,7 @@ static Array accumulated_lengths_curve_domain(const bke::CurvesGeometry & * - NURBS Curves: Treat the control points as if they were a poly curve, because there * is no obvious mapping from each control point to a specific evaluated point. */ -static Array curve_length_point_domain(const bke::CurvesGeometry &curves) +static Array calculate_point_lengths(const bke::CurvesGeometry &curves) { curves.ensure_evaluated_lengths(); const OffsetIndices points_by_curve = curves.points_by_curve(); @@ -106,107 +131,36 @@ static Array curve_length_point_domain(const bke::CurvesGeometry &curves) return result; } -static VArray construct_curve_parameter_varray(const bke::CurvesGeometry &curves, - const IndexMask /*mask*/, - const eAttrDomain domain) +static Array calculate_point_parameters(const bke::CurvesGeometry &curves) { - const VArray cyclic = curves.cyclic(); + Array lengths = calculate_point_lengths(curves); + const OffsetIndices points_by_curve = curves.points_by_curve(); - if (domain == ATTR_DOMAIN_POINT) { - Array result = curve_length_point_domain(curves); - MutableSpan lengths = result.as_mutable_span(); - const OffsetIndices points_by_curve = curves.points_by_curve(); - - threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) { - for (const int i_curve : range) { - MutableSpan curve_lengths = lengths.slice(points_by_curve[i_curve]); - const float total_length = curve_lengths.last(); - if (total_length > 0.0f) { - const float factor = 1.0f / total_length; - for (float &value : curve_lengths) { - value *= factor; - } - } - else if (curve_lengths.size() == 1) { - /* The curve is a single point. */ - curve_lengths[0] = 0.0f; - } - else { - /* It is arbitrary what to do in those rare cases when all the points are - * in the same position. In this case we are just arbitrarily giving a valid - * value in the range based on the point index. */ - for (const int i : curve_lengths.index_range()) { - curve_lengths[i] = i / (curve_lengths.size() - 1.0f); - } + threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) { + for (const int i_curve : range) { + MutableSpan curve_lengths = lengths.as_mutable_span().slice(points_by_curve[i_curve]); + const float total_length = curve_lengths.last(); + if (total_length > 0.0f) { + const float factor = 1.0f / total_length; + for (float &value : curve_lengths) { + value *= factor; } } - }); - return VArray::ForContainer(std::move(result)); - } - - if (domain == ATTR_DOMAIN_CURVE) { - Array lengths = accumulated_lengths_curve_domain(curves); - - const int last_index = curves.curves_num() - 1; - const float total_length = lengths.last() + curves.evaluated_length_total_for_curve( - last_index, cyclic[last_index]); - if (total_length > 0.0f) { - const float factor = 1.0f / total_length; - for (float &value : lengths) { - value *= factor; + else if (curve_lengths.size() == 1) { + /* The curve is a single point. */ + curve_lengths[0] = 0.0f; + } + else { + /* It is arbitrary what to do in those rare cases when all the points are + * in the same position. In this case we are just arbitrarily giving a valid + * value in the range based on the point index. */ + for (const int i : curve_lengths.index_range()) { + curve_lengths[i] = i / (curve_lengths.size() - 1.0f); + } } } - else { - /* It is arbitrary what to do in those rare cases when all the points are - * in the same position. In this case we are just arbitrarily giving a valid - * value in the range based on the curve index. */ - for (const int i : lengths.index_range()) { - lengths[i] = i / (lengths.size() - 1.0f); - } - } - return VArray::ForContainer(std::move(lengths)); - } - return {}; -} - -static VArray construct_curve_length_parameter_varray(const bke::CurvesGeometry &curves, - const IndexMask /*mask*/, - const eAttrDomain domain) -{ - curves.ensure_evaluated_lengths(); - - if (domain == ATTR_DOMAIN_POINT) { - Array lengths = curve_length_point_domain(curves); - return VArray::ForContainer(std::move(lengths)); - } - - if (domain == ATTR_DOMAIN_CURVE) { - Array lengths = accumulated_lengths_curve_domain(curves); - return VArray::ForContainer(std::move(lengths)); - } - - return {}; -} - -static VArray construct_index_on_spline_varray(const bke::CurvesGeometry &curves, - const IndexMask /*mask*/, - const eAttrDomain domain) -{ - if (domain == ATTR_DOMAIN_POINT) { - Array result(curves.points_num()); - MutableSpan span = result.as_mutable_span(); - const OffsetIndices points_by_curve = curves.points_by_curve(); - threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) { - for (const int i_curve : range) { - MutableSpan indices = span.slice(points_by_curve[i_curve]); - for (const int i : indices.index_range()) { - indices[i] = i; - } - } - }); - return VArray::ForContainer(std::move(result)); - } - return {}; + }); + return lengths; } class CurveParameterFieldInput final : public bke::CurvesFieldInput { @@ -218,14 +172,21 @@ class CurveParameterFieldInput final : public bke::CurvesFieldInput { GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, - IndexMask mask) const final + const IndexMask /*mask*/) const final { - return construct_curve_parameter_varray(curves, mask, domain); + switch (domain) { + case ATTR_DOMAIN_POINT: + return VArray::ForContainer(calculate_point_parameters(curves)); + case ATTR_DOMAIN_CURVE: + return VArray::ForContainer(calculate_curve_parameters(curves)); + default: + BLI_assert_unreachable(); + return {}; + } } uint64_t hash() const override { - /* Some random constant hash. */ return 29837456298; } @@ -245,14 +206,21 @@ class CurveLengthParameterFieldInput final : public bke::CurvesFieldInput { GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, - IndexMask mask) const final + const IndexMask /*mask*/) const final { - return construct_curve_length_parameter_varray(curves, mask, domain); + switch (domain) { + case ATTR_DOMAIN_POINT: + return VArray::ForContainer(calculate_point_lengths(curves)); + case ATTR_DOMAIN_CURVE: + return VArray::ForContainer(accumulated_lengths_curve_domain(curves)); + default: + BLI_assert_unreachable(); + return {}; + } } uint64_t hash() const override { - /* Some random constant hash. */ return 345634563454; } @@ -271,14 +239,26 @@ class IndexOnSplineFieldInput final : public bke::CurvesFieldInput { GVArray get_varray_for_context(const bke::CurvesGeometry &curves, const eAttrDomain domain, - IndexMask mask) const final + const IndexMask /*mask*/) const final { - return construct_index_on_spline_varray(curves, mask, domain); + if (domain != ATTR_DOMAIN_POINT) { + return {}; + } + Array result(curves.points_num()); + const OffsetIndices points_by_curve = curves.points_by_curve(); + threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) { + for (const int i_curve : range) { + MutableSpan indices = result.as_mutable_span().slice(points_by_curve[i_curve]); + for (const int i : indices.index_range()) { + indices[i] = i; + } + } + }); + return VArray::ForContainer(std::move(result)); } uint64_t hash() const override { - /* Some random constant hash. */ return 4536246522; }