Merge branch 'blender-v3.5-release'
This commit is contained in:
@@ -6532,6 +6532,8 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
uiStringInfo *si;
|
uiStringInfo *si;
|
||||||
|
|
||||||
|
PointerRNA *opptr = UI_but_operator_ptr_get(but);
|
||||||
|
|
||||||
const EnumPropertyItem *items = nullptr, *item = nullptr;
|
const EnumPropertyItem *items = nullptr, *item = nullptr;
|
||||||
int totitems;
|
int totitems;
|
||||||
bool free_items = false;
|
bool free_items = false;
|
||||||
@@ -6610,10 +6612,13 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
|
|||||||
}
|
}
|
||||||
else if (but->optype) {
|
else if (but->optype) {
|
||||||
if (type == BUT_GET_RNA_LABEL) {
|
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 {
|
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)) {
|
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));
|
int(ui_but_value_get(but));
|
||||||
}
|
}
|
||||||
else if (but->optype) {
|
else if (but->optype) {
|
||||||
PointerRNA *opptr = UI_but_operator_ptr_get(but);
|
|
||||||
wmOperatorType *ot = but->optype;
|
wmOperatorType *ot = but->optype;
|
||||||
|
|
||||||
/* So the context is passed to `itemf` functions. */
|
/* So the context is passed to `itemf` functions. */
|
||||||
|
|||||||
@@ -456,6 +456,22 @@ static int node_add_group_asset_invoke(bContext *C, wmOperator *op, const wmEven
|
|||||||
return OPERATOR_FINISHED;
|
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)
|
void NODE_OT_add_group_asset(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
ot->name = "Add Node Group Asset";
|
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->invoke = node_add_group_asset_invoke;
|
||||||
ot->poll = node_add_group_poll;
|
ot->poll = node_add_group_poll;
|
||||||
|
ot->get_description = node_add_group_asset_get_description;
|
||||||
|
|
||||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -951,17 +951,19 @@ void GPU_material_compile(GPUMaterial *mat)
|
|||||||
* As PSOs do not always match for default shaders, we limit warming for PSO
|
* As PSOs do not always match for default shaders, we limit warming for PSO
|
||||||
* configurations to ensure compile time remains fast, as these first
|
* configurations to ensure compile time remains fast, as these first
|
||||||
* entries will be the most commonly used PSOs. As not all PSOs are necessarily
|
* 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 != NULL && mat->default_mat != mat) {
|
||||||
if (mat->default_mat->pass != NULL) {
|
if (mat->default_mat->pass != NULL) {
|
||||||
GPUShader *parent_sh = GPU_pass_shader_get(mat->default_mat->pass);
|
GPUShader *parent_sh = GPU_pass_shader_get(mat->default_mat->pass);
|
||||||
if (parent_sh) {
|
if (parent_sh) {
|
||||||
|
/* 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_set_parent(sh, parent_sh);
|
||||||
GPU_shader_warm_cache(sh, 1);
|
GPU_shader_warm_cache(sh, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Flag success. */
|
/* Flag success. */
|
||||||
mat->status = GPU_MAT_SUCCESS;
|
mat->status = GPU_MAT_SUCCESS;
|
||||||
|
|||||||
@@ -45,6 +45,31 @@ static Array<float> accumulated_lengths_curve_domain(const bke::CurvesGeometry &
|
|||||||
return lengths;
|
return lengths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Array<float> calculate_curve_parameters(const bke::CurvesGeometry &curves)
|
||||||
|
{
|
||||||
|
const VArray<bool> cyclic = curves.cyclic();
|
||||||
|
Array<float> 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.
|
* 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
|
* Importantly, this is different than the length at each evaluated point. The implementation is
|
||||||
@@ -55,7 +80,7 @@ static Array<float> accumulated_lengths_curve_domain(const bke::CurvesGeometry &
|
|||||||
* - NURBS Curves: Treat the control points as if they were a poly curve, because there
|
* - 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.
|
* is no obvious mapping from each control point to a specific evaluated point.
|
||||||
*/
|
*/
|
||||||
static Array<float> curve_length_point_domain(const bke::CurvesGeometry &curves)
|
static Array<float> calculate_point_lengths(const bke::CurvesGeometry &curves)
|
||||||
{
|
{
|
||||||
curves.ensure_evaluated_lengths();
|
curves.ensure_evaluated_lengths();
|
||||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||||
@@ -106,20 +131,14 @@ static Array<float> curve_length_point_domain(const bke::CurvesGeometry &curves)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry &curves,
|
static Array<float> calculate_point_parameters(const bke::CurvesGeometry &curves)
|
||||||
const IndexMask /*mask*/,
|
|
||||||
const eAttrDomain domain)
|
|
||||||
{
|
{
|
||||||
const VArray<bool> cyclic = curves.cyclic();
|
Array<float> lengths = calculate_point_lengths(curves);
|
||||||
|
|
||||||
if (domain == ATTR_DOMAIN_POINT) {
|
|
||||||
Array<float> result = curve_length_point_domain(curves);
|
|
||||||
MutableSpan<float> lengths = result.as_mutable_span();
|
|
||||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||||
|
|
||||||
threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) {
|
threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) {
|
||||||
for (const int i_curve : range) {
|
for (const int i_curve : range) {
|
||||||
MutableSpan<float> curve_lengths = lengths.slice(points_by_curve[i_curve]);
|
MutableSpan<float> curve_lengths = lengths.as_mutable_span().slice(points_by_curve[i_curve]);
|
||||||
const float total_length = curve_lengths.last();
|
const float total_length = curve_lengths.last();
|
||||||
if (total_length > 0.0f) {
|
if (total_length > 0.0f) {
|
||||||
const float factor = 1.0f / total_length;
|
const float factor = 1.0f / total_length;
|
||||||
@@ -141,72 +160,7 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return VArray<float>::ForContainer(std::move(result));
|
return lengths;
|
||||||
}
|
|
||||||
|
|
||||||
if (domain == ATTR_DOMAIN_CURVE) {
|
|
||||||
Array<float> 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 VArray<float>::ForContainer(std::move(lengths));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
static VArray<float> 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<float> lengths = curve_length_point_domain(curves);
|
|
||||||
return VArray<float>::ForContainer(std::move(lengths));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domain == ATTR_DOMAIN_CURVE) {
|
|
||||||
Array<float> lengths = accumulated_lengths_curve_domain(curves);
|
|
||||||
return VArray<float>::ForContainer(std::move(lengths));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
static VArray<int> construct_index_on_spline_varray(const bke::CurvesGeometry &curves,
|
|
||||||
const IndexMask /*mask*/,
|
|
||||||
const eAttrDomain domain)
|
|
||||||
{
|
|
||||||
if (domain == ATTR_DOMAIN_POINT) {
|
|
||||||
Array<int> result(curves.points_num());
|
|
||||||
MutableSpan<int> 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<int> indices = span.slice(points_by_curve[i_curve]);
|
|
||||||
for (const int i : indices.index_range()) {
|
|
||||||
indices[i] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return VArray<int>::ForContainer(std::move(result));
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CurveParameterFieldInput final : public bke::CurvesFieldInput {
|
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,
|
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
|
||||||
const eAttrDomain domain,
|
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<float>::ForContainer(calculate_point_parameters(curves));
|
||||||
|
case ATTR_DOMAIN_CURVE:
|
||||||
|
return VArray<float>::ForContainer(calculate_curve_parameters(curves));
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
{
|
{
|
||||||
/* Some random constant hash. */
|
|
||||||
return 29837456298;
|
return 29837456298;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,14 +206,21 @@ class CurveLengthParameterFieldInput final : public bke::CurvesFieldInput {
|
|||||||
|
|
||||||
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
|
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
|
||||||
const eAttrDomain domain,
|
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<float>::ForContainer(calculate_point_lengths(curves));
|
||||||
|
case ATTR_DOMAIN_CURVE:
|
||||||
|
return VArray<float>::ForContainer(accumulated_lengths_curve_domain(curves));
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
{
|
{
|
||||||
/* Some random constant hash. */
|
|
||||||
return 345634563454;
|
return 345634563454;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,14 +239,26 @@ class IndexOnSplineFieldInput final : public bke::CurvesFieldInput {
|
|||||||
|
|
||||||
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
|
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
|
||||||
const eAttrDomain domain,
|
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<int> 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<int> indices = result.as_mutable_span().slice(points_by_curve[i_curve]);
|
||||||
|
for (const int i : indices.index_range()) {
|
||||||
|
indices[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return VArray<int>::ForContainer(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
{
|
{
|
||||||
/* Some random constant hash. */
|
|
||||||
return 4536246522;
|
return 4536246522;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user