UI: Configurable UI Font Weight #112454

Merged
Harley Acheson merged 36 commits from Harley/blender:TextUiStyles into main 2023-10-21 00:28:37 +02:00
21 changed files with 280 additions and 199 deletions
Showing only changes of commit fecce94c3e - Show all commits

View File

@ -94,9 +94,8 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
/* Make a copy to split faces if we use auto-smooth, otherwise not needed.
* Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */
if (mesh.is_editmode() ||
(mesh.normals_domain() == BL::Mesh::normals_domain_CORNER &&
subdivision_type == Mesh::SUBDIVISION_NONE))
if (mesh.is_editmode() || (mesh.normals_domain() == BL::Mesh::normals_domain_CORNER &&
subdivision_type == Mesh::SUBDIVISION_NONE))
{
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);

View File

@ -4612,7 +4612,8 @@ def km_grease_pencil_edit(params):
op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}),
# Cyclical set
("grease_pencil.cyclical_set", {"type": 'F', "value": 'PRESS'}, {"properties": [("type", "CLOSE")]}),
("grease_pencil.cyclical_set", {"type": 'C', "value": 'PRESS', "alt": True}, {"properties": [("type", "TOGGLE")]}),
("grease_pencil.cyclical_set", {"type": 'C', "value": 'PRESS',
"alt": True}, {"properties": [("type", "TOGGLE")]}),
])
return keymap

View File

@ -299,8 +299,8 @@ class EEVEE_NEXT_MATERIAL_PT_settings_surface(MaterialButtonsPanel, Panel):
col.prop(mat, "use_backface_culling", text="Camera")
col.prop(mat, "use_backface_culling_shadow", text="Shadow")
#TODO(fclem): Displacement option
#TODO(fclem): Transparent shadow option
# TODO(fclem): Displacement option
# TODO(fclem): Transparent shadow option
col = layout.column()
col.prop(mat, "surface_render_method", text="Render Method")

View File

@ -5817,7 +5817,7 @@ class VIEW3D_MT_edit_greasepencil_stroke(Menu):
layout.operator("grease_pencil.stroke_simplify")
layout.separator()
layout.operator_enum("grease_pencil.cyclical_set", "type")

View File

@ -28,10 +28,10 @@ class Drawing;
class MeshFieldContext : public fn::FieldContext {
private:
const Mesh &mesh_;
const eAttrDomain domain_;
eAttrDomain domain_;
public:
MeshFieldContext(const Mesh &mesh, const eAttrDomain domain);
MeshFieldContext(const Mesh &mesh, eAttrDomain domain);
const Mesh &mesh() const
{
return mesh_;
@ -46,10 +46,10 @@ class MeshFieldContext : public fn::FieldContext {
class CurvesFieldContext : public fn::FieldContext {
private:
const CurvesGeometry &curves_;
const eAttrDomain domain_;
eAttrDomain domain_;
public:
CurvesFieldContext(const CurvesGeometry &curves, const eAttrDomain domain);
CurvesFieldContext(const CurvesGeometry &curves, eAttrDomain domain);
const CurvesGeometry &curves() const
{
@ -91,8 +91,8 @@ class GreasePencilFieldContext : public fn::FieldContext {
class GreasePencilLayerFieldContext : public fn::FieldContext {
private:
const GreasePencil &grease_pencil_;
const eAttrDomain domain_;
const int layer_index_;
eAttrDomain domain_;
int layer_index_;
public:
GreasePencilLayerFieldContext(const GreasePencil &grease_pencil,
@ -148,7 +148,7 @@ class GeometryFieldContext : public fn::FieldContext {
*/
const void *geometry_;
const GeometryComponent::Type type_;
const eAttrDomain domain_;
eAttrDomain domain_;
/**
* Only used when the type is grease pencil and the domain is either points or curves
* (not layers).
@ -332,7 +332,7 @@ class IDAttributeFieldInput : public GeometryFieldInput {
bool is_equal_to(const fn::FieldNode &other) const override;
};
VArray<float3> curve_normals_varray(const CurvesGeometry &curves, const eAttrDomain domain);
VArray<float3> curve_normals_varray(const CurvesGeometry &curves, eAttrDomain domain);
VArray<float3> mesh_normals_varray(const Mesh &mesh, const IndexMask &mask, eAttrDomain domain);
@ -363,7 +363,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput {
std::string producer_name)
: GeometryFieldInput(type, anonymous_id->user_name()),
anonymous_id_(std::move(anonymous_id)),
producer_name_(producer_name)
producer_name_(std::move(producer_name))
{
category_ = Category::AnonymousAttribute;
}
@ -405,12 +405,12 @@ class CurveLengthFieldInput final : public CurvesFieldInput {
bool try_capture_field_on_geometry(GeometryComponent &component,
const AttributeIDRef &attribute_id,
const eAttrDomain domain,
eAttrDomain domain,
const fn::GField &field);
bool try_capture_field_on_geometry(GeometryComponent &component,
const AttributeIDRef &attribute_id,
const eAttrDomain domain,
eAttrDomain domain,
const fn::Field<bool> &selection,
const fn::GField &field);

View File

@ -506,16 +506,10 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
Span<LayerGroup *> groups_for_write();
/**
* Returns a pointer to the layer with \a name. If no such layer was found, returns nullptr.
* Returns a pointer to the node with \a name. If no such node was found, returns nullptr.
*/
const Layer *find_layer_by_name(StringRefNull name) const;
Layer *find_layer_by_name(StringRefNull name);
/**
* Returns a pointer to the group with \a name. If no such group was found, returns nullptr.
*/
const LayerGroup *find_group_by_name(StringRefNull name) const;
LayerGroup *find_group_by_name(StringRefNull name);
const TreeNode *find_node_by_name(StringRefNull name) const;
TreeNode *find_node_by_name(StringRefNull name);
/**
* Print the nodes. For debugging purposes.

View File

@ -553,19 +553,37 @@ inline void bNodeTree::ensure_interface_cache() const
this->tree_interface.ensure_items_cache();
}
inline blender::Span<bNodeTreeInterfaceSocket *> bNodeTree::interface_inputs() const
inline blender::Span<bNodeTreeInterfaceSocket *> bNodeTree::interface_inputs()
{
BLI_assert(this->tree_interface.items_cache_is_available());
return this->tree_interface.runtime->inputs_;
}
inline blender::Span<bNodeTreeInterfaceSocket *> bNodeTree::interface_outputs() const
inline blender::Span<const bNodeTreeInterfaceSocket *> bNodeTree::interface_inputs() const
{
BLI_assert(this->tree_interface.items_cache_is_available());
return this->tree_interface.runtime->inputs_;
}
inline blender::Span<bNodeTreeInterfaceSocket *> bNodeTree::interface_outputs()
{
BLI_assert(this->tree_interface.items_cache_is_available());
return this->tree_interface.runtime->outputs_;
}
inline blender::Span<bNodeTreeInterfaceItem *> bNodeTree::interface_items() const
inline blender::Span<const bNodeTreeInterfaceSocket *> bNodeTree::interface_outputs() const
{
BLI_assert(this->tree_interface.items_cache_is_available());
return this->tree_interface.runtime->outputs_;
}
inline blender::Span<bNodeTreeInterfaceItem *> bNodeTree::interface_items()
{
BLI_assert(this->tree_interface.items_cache_is_available());
return this->tree_interface.runtime->items_;
}
inline blender::Span<const bNodeTreeInterfaceItem *> bNodeTree::interface_items() const
{
BLI_assert(this->tree_interface.items_cache_is_available());
return this->tree_interface.runtime->items_;

View File

@ -128,8 +128,8 @@ class DynamicAttributesProvider {
class CustomDataAttributeProvider final : public DynamicAttributesProvider {
private:
static constexpr uint64_t supported_types_mask = CD_MASK_PROP_ALL;
const eAttrDomain domain_;
const CustomDataAccessInfo custom_data_access_;
eAttrDomain domain_;
CustomDataAccessInfo custom_data_access_;
public:
CustomDataAttributeProvider(const eAttrDomain domain,

View File

@ -103,8 +103,10 @@ static void grease_pencil_copy_data(Main * /*bmain*/,
/* Set active layer. */
if (grease_pencil_src->has_active_layer()) {
grease_pencil_dst->set_active_layer(
grease_pencil_dst->find_layer_by_name(grease_pencil_src->active_layer->wrap().name()));
bke::greasepencil::TreeNode *active_node = grease_pencil_dst->find_node_by_name(
grease_pencil_src->active_layer->wrap().name());
BLI_assert(active_node && active_node->is_layer());
grease_pencil_dst->set_active_layer(&active_node->as_layer());
}
CustomData_copy(&grease_pencil_src->layers_data,
@ -1006,41 +1008,21 @@ Span<LayerGroup *> LayerGroup::groups_for_write()
return this->runtime->layer_group_cache_.as_span();
}
const Layer *LayerGroup::find_layer_by_name(const StringRefNull name) const
const TreeNode *LayerGroup::find_node_by_name(const StringRefNull name) const
{
for (const Layer *layer : this->layers()) {
if (StringRef(layer->name()) == StringRef(name)) {
return layer;
for (const TreeNode *node : this->nodes()) {
if (StringRef(node->name()) == StringRef(name)) {
return node;
}
}
return nullptr;
}
Layer *LayerGroup::find_layer_by_name(const StringRefNull name)
TreeNode *LayerGroup::find_node_by_name(const StringRefNull name)
{
for (Layer *layer : this->layers_for_write()) {
if (StringRef(layer->name()) == StringRef(name)) {
return layer;
}
}
return nullptr;
}
const LayerGroup *LayerGroup::find_group_by_name(StringRefNull name) const
{
for (const LayerGroup *group : this->groups()) {
if (StringRef(group->name()) == StringRef(name)) {
return group;
}
}
return nullptr;
}
LayerGroup *LayerGroup::find_group_by_name(StringRefNull name)
{
for (LayerGroup *group : this->groups_for_write()) {
if (StringRef(group->name()) == StringRef(name)) {
return group;
for (TreeNode *node : this->nodes_for_write()) {
if (StringRef(node->name()) == StringRef(name)) {
return node;
}
}
return nullptr;
@ -2391,28 +2373,16 @@ void GreasePencil::move_node_into(blender::bke::greasepencil::TreeNode &node,
parent_group.add_node(node);
}
const blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
const blender::bke::greasepencil::TreeNode *GreasePencil::find_node_by_name(
const blender::StringRefNull name) const
{
return this->root_group().find_layer_by_name(name);
return this->root_group().find_node_by_name(name);
}
blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
blender::bke::greasepencil::TreeNode *GreasePencil::find_node_by_name(
const blender::StringRefNull name)
{
return this->root_group().find_layer_by_name(name);
}
const blender::bke::greasepencil::LayerGroup *GreasePencil::find_layer_group_by_name(
blender::StringRefNull name) const
{
return this->root_group().find_group_by_name(name);
}
blender::bke::greasepencil::LayerGroup *GreasePencil::find_layer_group_by_name(
blender::StringRefNull name)
{
return this->root_group().find_group_by_name(name);
return this->root_group().find_node_by_name(name);
}
void GreasePencil::rename_node(blender::bke::greasepencil::TreeNode &node,

View File

@ -195,11 +195,11 @@ TEST(greasepencil, layer_tree_is_child_of)
EXPECT_FALSE(ex.grease_pencil.root_group().is_child_of(ex.grease_pencil.root_group()));
const LayerGroup &group1 = *ex.grease_pencil.find_layer_group_by_name("Group1");
const LayerGroup &group2 = *ex.grease_pencil.find_layer_group_by_name("Group2");
const Layer &layer1 = *ex.grease_pencil.find_layer_by_name("Layer1");
const Layer &layer3 = *ex.grease_pencil.find_layer_by_name("Layer3");
const Layer &layer5 = *ex.grease_pencil.find_layer_by_name("Layer5");
const LayerGroup &group1 = ex.grease_pencil.find_node_by_name("Group1")->as_group();
const LayerGroup &group2 = ex.grease_pencil.find_node_by_name("Group2")->as_group();
const Layer &layer1 = ex.grease_pencil.find_node_by_name("Layer1")->as_layer();
const Layer &layer3 = ex.grease_pencil.find_node_by_name("Layer3")->as_layer();
const Layer &layer5 = ex.grease_pencil.find_node_by_name("Layer5")->as_layer();
EXPECT_TRUE(layer1.is_child_of(ex.grease_pencil.root_group()));
EXPECT_TRUE(layer1.is_child_of(group1));

View File

@ -8,12 +8,14 @@
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_anonymous_attributes.hh"
#include "BKE_node_tree_dot_export.hh"
#include "BKE_node_tree_zones.hh"
#include "BLI_bit_group_vector.hh"
#include "BLI_bit_span_ops.hh"
#include "BLI_resource_scope.hh"
#include <iostream>
#include <sstream>
namespace blender::bke::anonymous_attribute_inferencing {
@ -195,6 +197,21 @@ class bNodeTreeToDotOptionsForAnonymousAttributeInferencing : public bNodeTreeTo
}
};
static bool or_into_each_other(MutableBoundedBitSpan a, MutableBoundedBitSpan b)
{
if (bits::spans_equal(a, b)) {
return false;
}
a |= b;
b |= a;
return true;
}
static bool or_into_each_other(BitGroupVector<> &vec, const int64_t a, const int64_t b)
{
return or_into_each_other(vec[a], vec[b]);
}
static AnonymousAttributeInferencingResult analyse_anonymous_attribute_usages(
const bNodeTree &tree)
{
@ -204,6 +221,22 @@ static AnonymousAttributeInferencingResult analyse_anonymous_attribute_usages(
ResourceScope scope;
const Array<const aal::RelationsInNode *> relations_by_node = get_relations_by_node(tree, scope);
/* Repeat zones need some special behavior because they can propagate anonymous attributes from
* right to left (from the repeat output to the repeat input node). */
const bNodeTreeZones *zones = tree.zones();
Vector<const bNodeTreeZone *> repeat_zones_to_consider;
if (zones) {
for (const std::unique_ptr<bNodeTreeZone> &zone : zones->zones) {
if (ELEM(nullptr, zone->input_node, zone->output_node)) {
continue;
}
if (zone->output_node->type != GEO_NODE_REPEAT_OUTPUT) {
continue;
}
repeat_zones_to_consider.append(zone.get());
}
}
Vector<FieldSource> all_field_sources;
Vector<GeometrySource> all_geometry_sources;
@ -300,44 +333,72 @@ static AnonymousAttributeInferencingResult analyse_anonymous_attribute_usages(
/* Inferencing pass from left to right to figure out where fields and geometries may be
* propagated to. */
for (const bNode *node : tree.toposort_left_to_right()) {
for (const bNodeSocket *socket : node->input_sockets()) {
if (!socket->is_available()) {
continue;
}
const int dst_index = socket->index_in_tree();
for (const bNodeLink *link : socket->directly_linked_links()) {
if (link->is_used()) {
const int src_index = link->fromsock->index_in_tree();
propagated_fields_by_socket[dst_index] |= propagated_fields_by_socket[src_index];
propagated_geometries_by_socket[dst_index] |= propagated_geometries_by_socket[src_index];
available_fields_by_geometry_socket[dst_index] |=
available_fields_by_geometry_socket[src_index];
auto pass_left_to_right = [&]() {
for (const bNode *node : tree.toposort_left_to_right()) {
for (const bNodeSocket *socket : node->input_sockets()) {
if (!socket->is_available()) {
continue;
}
const int dst_index = socket->index_in_tree();
for (const bNodeLink *link : socket->directly_linked_links()) {
if (link->is_used()) {
const int src_index = link->fromsock->index_in_tree();
propagated_fields_by_socket[dst_index] |= propagated_fields_by_socket[src_index];
propagated_geometries_by_socket[dst_index] |=
propagated_geometries_by_socket[src_index];
available_fields_by_geometry_socket[dst_index] |=
available_fields_by_geometry_socket[src_index];
}
}
}
}
const aal::RelationsInNode &relations = *relations_by_node[node->index()];
for (const aal::ReferenceRelation &relation : relations.reference_relations) {
const bNodeSocket &from_socket = node->input_socket(relation.from_field_input);
const bNodeSocket &to_socket = node->output_socket(relation.to_field_output);
if (!from_socket.is_available() || !to_socket.is_available()) {
continue;
const aal::RelationsInNode &relations = *relations_by_node[node->index()];
for (const aal::ReferenceRelation &relation : relations.reference_relations) {
const bNodeSocket &from_socket = node->input_socket(relation.from_field_input);
const bNodeSocket &to_socket = node->output_socket(relation.to_field_output);
if (!from_socket.is_available() || !to_socket.is_available()) {
continue;
}
const int src_index = from_socket.index_in_tree();
const int dst_index = to_socket.index_in_tree();
propagated_fields_by_socket[dst_index] |= propagated_fields_by_socket[src_index];
}
const int src_index = from_socket.index_in_tree();
const int dst_index = to_socket.index_in_tree();
propagated_fields_by_socket[dst_index] |= propagated_fields_by_socket[src_index];
}
for (const aal::PropagateRelation &relation : relations.propagate_relations) {
const bNodeSocket &from_socket = node->input_socket(relation.from_geometry_input);
const bNodeSocket &to_socket = node->output_socket(relation.to_geometry_output);
if (!from_socket.is_available() || !to_socket.is_available()) {
continue;
for (const aal::PropagateRelation &relation : relations.propagate_relations) {
const bNodeSocket &from_socket = node->input_socket(relation.from_geometry_input);
const bNodeSocket &to_socket = node->output_socket(relation.to_geometry_output);
if (!from_socket.is_available() || !to_socket.is_available()) {
continue;
}
const int src_index = from_socket.index_in_tree();
const int dst_index = to_socket.index_in_tree();
propagated_geometries_by_socket[dst_index] |= propagated_geometries_by_socket[src_index];
available_fields_by_geometry_socket[dst_index] |=
available_fields_by_geometry_socket[src_index];
}
const int src_index = from_socket.index_in_tree();
const int dst_index = to_socket.index_in_tree();
propagated_geometries_by_socket[dst_index] |= propagated_geometries_by_socket[src_index];
available_fields_by_geometry_socket[dst_index] |=
available_fields_by_geometry_socket[src_index];
}
};
while (true) {
pass_left_to_right();
/* Repeat zones may need multiple inference passes. That's because anonymous attributes
* propagated to a repeat output node also come out of the corresponding repeat input node. */
bool changed = false;
for (const bNodeTreeZone *zone : repeat_zones_to_consider) {
const auto &storage = *static_cast<const NodeGeometryRepeatOutput *>(
zone->output_node->storage);
for (const int i : IndexRange(storage.items_num)) {
const bNodeSocket &body_input_socket = zone->input_node->output_socket(i);
const bNodeSocket &body_output_socket = zone->output_node->input_socket(i);
const int in_index = body_input_socket.index_in_tree();
const int out_index = body_output_socket.index_in_tree();
changed |= or_into_each_other(propagated_fields_by_socket, in_index, out_index);
changed |= or_into_each_other(propagated_geometries_by_socket, in_index, out_index);
changed |= or_into_each_other(available_fields_by_geometry_socket, in_index, out_index);
}
}
if (!changed) {
break;
}
}
@ -346,8 +407,8 @@ static AnonymousAttributeInferencingResult analyse_anonymous_attribute_usages(
VectorSet<int> propagated_output_geometry_indices;
aal::RelationsInNode tree_relations;
/* Create #PropagateRelation, #AvailableRelation and #ReferenceRelation for the tree based on the
* propagated data from above. */
/* Create #PropagateRelation, #AvailableRelation and #ReferenceRelation for the tree based on
* the propagated data from above. */
if (const bNode *group_output_node = tree.group_output_node()) {
for (const bNodeSocket *socket : group_output_node->input_sockets().drop_back(1)) {
if (socket->type == SOCK_GEOMETRY) {
@ -410,38 +471,64 @@ static AnonymousAttributeInferencingResult analyse_anonymous_attribute_usages(
/* Inferencing pass from right to left to determine which anonymous attributes have to be
* propagated to which geometry sockets. */
for (const bNode *node : tree.toposort_right_to_left()) {
for (const bNodeSocket *socket : node->output_sockets()) {
if (!socket->is_available()) {
continue;
}
const int dst_index = socket->index_in_tree();
for (const bNodeLink *link : socket->directly_linked_links()) {
if (link->is_used()) {
const int src_index = link->tosock->index_in_tree();
required_fields_by_geometry_socket[dst_index] |=
required_fields_by_geometry_socket[src_index];
propagate_to_output_by_geometry_socket[dst_index] |=
propagate_to_output_by_geometry_socket[src_index];
auto pass_right_to_left = [&]() {
for (const bNode *node : tree.toposort_right_to_left()) {
for (const bNodeSocket *socket : node->output_sockets()) {
if (!socket->is_available()) {
continue;
}
const int dst_index = socket->index_in_tree();
for (const bNodeLink *link : socket->directly_linked_links()) {
if (link->is_used()) {
const int src_index = link->tosock->index_in_tree();
required_fields_by_geometry_socket[dst_index] |=
required_fields_by_geometry_socket[src_index];
propagate_to_output_by_geometry_socket[dst_index] |=
propagate_to_output_by_geometry_socket[src_index];
}
}
}
const aal::RelationsInNode &relations = *relations_by_node[node->index()];
for (const aal::PropagateRelation &relation : relations.propagate_relations) {
const bNodeSocket &output_socket = node->output_socket(relation.to_geometry_output);
const bNodeSocket &input_socket = node->input_socket(relation.from_geometry_input);
const int src_index = output_socket.index_in_tree();
const int dst_index = input_socket.index_in_tree();
required_fields_by_geometry_socket[dst_index] |=
required_fields_by_geometry_socket[src_index];
propagate_to_output_by_geometry_socket[dst_index] |=
propagate_to_output_by_geometry_socket[src_index];
}
for (const aal::EvalRelation &relation : relations.eval_relations) {
const bNodeSocket &geometry_socket = node->input_socket(relation.geometry_input);
const bNodeSocket &field_socket = node->input_socket(relation.field_input);
required_fields_by_geometry_socket[geometry_socket.index_in_tree()] |=
propagated_fields_by_socket[field_socket.index_in_tree()];
}
}
const aal::RelationsInNode &relations = *relations_by_node[node->index()];
for (const aal::PropagateRelation &relation : relations.propagate_relations) {
const bNodeSocket &output_socket = node->output_socket(relation.to_geometry_output);
const bNodeSocket &input_socket = node->input_socket(relation.from_geometry_input);
const int src_index = output_socket.index_in_tree();
const int dst_index = input_socket.index_in_tree();
required_fields_by_geometry_socket[dst_index] |=
required_fields_by_geometry_socket[src_index];
propagate_to_output_by_geometry_socket[dst_index] |=
propagate_to_output_by_geometry_socket[src_index];
};
while (true) {
pass_right_to_left();
/* Data required by a repeat input node will also be required by the repeat output node,
* because that's where the data comes from after the first iteration. */
bool changed = false;
for (const bNodeTreeZone *zone : repeat_zones_to_consider) {
const auto &storage = *static_cast<const NodeGeometryRepeatOutput *>(
zone->output_node->storage);
for (const int i : IndexRange(storage.items_num)) {
const bNodeSocket &body_input_socket = zone->input_node->output_socket(i);
const bNodeSocket &body_output_socket = zone->output_node->input_socket(i);
const int in_index = body_input_socket.index_in_tree();
const int out_index = body_output_socket.index_in_tree();
changed |= or_into_each_other(required_fields_by_geometry_socket, in_index, out_index);
changed |= or_into_each_other(propagate_to_output_by_geometry_socket, in_index, out_index);
}
}
for (const aal::EvalRelation &relation : relations.eval_relations) {
const bNodeSocket &geometry_socket = node->input_socket(relation.geometry_input);
const bNodeSocket &field_socket = node->input_socket(relation.field_input);
required_fields_by_geometry_socket[geometry_socket.index_in_tree()] |=
propagated_fields_by_socket[field_socket.index_in_tree()];
if (!changed) {
break;
}
}

View File

@ -238,9 +238,23 @@ template<typename... BitSpanT> inline bool has_common_set_bits(const BitSpanT &.
return any_set_expr([](const auto... x) { return (x & ...); }, args...);
}
template<typename BitSpanT> inline bool any_bit_set(const BitSpanT &arg)
{
return has_common_set_bits(arg);
}
template<typename BitSpanT, typename Fn> inline void foreach_1_index(const BitSpanT &data, Fn &&fn)
{
foreach_1_index_expr([](const BitInt x) { return x; }, fn, data);
}
template<typename BitSpanT1, typename BitSpanT2>
inline bool spans_equal(const BitSpanT1 &a, const BitSpanT2 &b)
{
if (a.size() != b.size()) {
return false;
}
return !any_set_expr([](const BitInt a, const BitInt b) { return a ^ b; }, a, b);
}
} // namespace blender::bits

View File

@ -216,7 +216,7 @@ static bool apply_mesh_output_to_bmesh(BMesh *bm, IMesh &m_out, bool keep_hidden
/* Save the original #BMEdge's so we can use them as examples. */
Array<BMEdge *> old_edges(bm->totedge);
std::copy(bm->etable, bm->etable + bm->totedge, old_edges.begin());
std::copy_n(bm->etable, bm->totedge, old_edges.begin());
/* Reuse or make new #BMFace's, as the faces are identical to old ones or not.
* If reusing, mark them as "keep". First find the maximum face length

View File

@ -479,7 +479,7 @@ struct PBVHBatches {
face_no = convert_value<float3, short4>(args.face_normals[face_i]);
last_face = face_i;
}
std::fill(data, data + 3, face_no);
std::fill_n(data, 3, face_no);
data += 3;
}
else {
@ -738,7 +738,7 @@ struct PBVHBatches {
fset_color[0] = fset_color[1] = fset_color[2] = UCHAR_MAX;
}
}
std::fill(data, data + 3, fset_color);
std::fill_n(data, 3, fset_color);
data += 3;
}
}
@ -893,7 +893,7 @@ struct PBVHBatches {
data++;
}
else {
std::fill(data, data + 3, convert_value<float3, short4>(f->no));
std::fill_n(data, 3, convert_value<float3, short4>(f->no));
data += 3;
}
}
@ -933,7 +933,7 @@ struct PBVHBatches {
/* Skip for the default color face set to render it white. */
fset_color[0] = fset_color[1] = fset_color[2] = UCHAR_MAX;
}
std::fill(data, data + 3, fset_color);
std::fill_n(data, 3, fset_color);
data += 3;
}
}

View File

@ -450,7 +450,7 @@ static void run_node_group_ui(bContext *C, wmOperator *op)
node_tree->ensure_interface_cache();
int input_index = 0;
for (bNodeTreeInterfaceSocket *io_socket : node_tree->interface_inputs()) {
for (const bNodeTreeInterfaceSocket *io_socket : node_tree->interface_inputs()) {
draw_property_for_socket(
*node_tree, layout, op->properties, &bmain_ptr, op->ptr, *io_socket, input_index);
++input_index;

View File

@ -459,7 +459,6 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op)
if (curves.points_num() == 0) {
return;
}
if (!ed::curves::has_anything_selected(curves)) {
return;
}
@ -666,7 +665,6 @@ static int grease_pencil_dissolve_exec(bContext *C, wmOperator *op)
if (curves.points_num() == 0) {
return;
}
if (!ed::curves::has_anything_selected(curves)) {
return;
}
@ -884,23 +882,20 @@ static int grease_pencil_cyclical_set_exec(bContext *C, wmOperator *op)
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int /*layer_index*/, bke::greasepencil::Drawing &drawing) {
bke::CurvesGeometry &curves = drawing.strokes_for_write();
if (curves.points_num() == 0) {
return;
}
if (!ed::curves::has_anything_selected(curves)) {
if (mode == CyclicalMode::OPEN && !curves.attributes().contains("cyclic")) {
/* Avoid creating unneeded attribute. */
return;
}
/* Return to stop from creating unneeded attribute. */
if (mode == CyclicalMode::OPEN && !curves.attributes().contains("cyclic")) {
IndexMaskMemory memory;
const IndexMask curve_selection = ed::curves::retrieve_selected_curves(curves, memory);
if (curve_selection.is_empty()) {
return;
}
MutableSpan<bool> cyclic = curves.cyclic_for_write();
IndexMaskMemory memory;
const IndexMask curve_selection = ed::curves::retrieve_selected_curves(curves, memory);
switch (mode) {
case CyclicalMode::CLOSE:
index_mask::masked_fill(cyclic, true, curve_selection);
@ -914,10 +909,11 @@ static int grease_pencil_cyclical_set_exec(bContext *C, wmOperator *op)
}
/* Remove the attribute if it is empty. */
if (mode != CyclicalMode::CLOSE &&
!ed::curves::has_anything_selected(curves.cyclic(), curves.curves_range()))
{
curves.attributes_for_write().remove("cyclic");
if (mode != CyclicalMode::CLOSE) {
if (array_utils::booleans_mix_calc(curves.cyclic()) == array_utils::BooleanMix::AllFalse)
{
curves.attributes_for_write().remove("cyclic");
}
}
changed = true;

View File

@ -141,8 +141,8 @@ static int grease_pencil_layer_reorder_exec(bContext *C, wmOperator *op)
op->ptr, "target_layer_name", nullptr, 0, &target_layer_name_length);
const int reorder_location = RNA_enum_get(op->ptr, "location");
Layer *target_layer = grease_pencil.find_layer_by_name(target_layer_name);
if (!target_layer) {
TreeNode *target_node = grease_pencil.find_node_by_name(target_layer_name);
if (!target_node || !target_node->is_layer()) {
MEM_SAFE_FREE(target_layer_name);
return OPERATOR_CANCELLED;
}
@ -152,13 +152,13 @@ static int grease_pencil_layer_reorder_exec(bContext *C, wmOperator *op)
case LAYER_REORDER_ABOVE: {
/* NOTE: The layers are stored from bottom to top, so inserting above (visually), means
* inserting the link after the target. */
grease_pencil.move_node_after(active_layer.as_node(), target_layer->as_node());
grease_pencil.move_node_after(active_layer.as_node(), *target_node);
break;
}
case LAYER_REORDER_BELOW: {
/* NOTE: The layers are stored from bottom to top, so inserting below (visually), means
* inserting the link before the target. */
grease_pencil.move_node_before(active_layer.as_node(), target_layer->as_node());
grease_pencil.move_node_before(active_layer.as_node(), *target_node);
break;
}
default:

View File

@ -3107,18 +3107,19 @@ static bool ed_curves_select_pick(bContext &C, const int mval[2], const SelectPi
for (Base *base : bases.slice(range)) {
Curves &curves_id = *static_cast<Curves *>(base->object->data);
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
if (ed::curves::has_anything_selected(curves)) {
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
ed::curves::fill_selection_false(selection.span);
selection.finish();
deselected = true;
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(&C, NC_GEOM | ND_DATA, &curves_id);
if (!ed::curves::has_anything_selected(curves)) {
continue;
}
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
ed::curves::fill_selection_false(selection.span);
selection.finish();
deselected = true;
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(&C, NC_GEOM | ND_DATA, &curves_id);
}
});
}
@ -3213,14 +3214,15 @@ static bool ed_grease_pencil_select_pick(bContext *C,
threading::parallel_for(drawings.index_range(), 1L, [&](const IndexRange range) {
for (const int i : range) {
bke::CurvesGeometry &curves = drawings[i]->geometry.wrap();
if (ed::curves::has_anything_selected(curves)) {
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
ed::curves::fill_selection_false(selection.span);
selection.finish();
deselected = true;
if (!ed::curves::has_anything_selected(curves)) {
continue;
}
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
ed::curves::fill_selection_false(selection.span);
selection.finish();
deselected = true;
}
});
}

View File

@ -637,7 +637,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
static void recalcData_nla(TransInfo *t)
{
SpaceNla *snla = (SpaceNla *)t->area->spacedata.first;
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
/* For each strip we've got, perform some additional validation of the values

View File

@ -492,11 +492,8 @@ typedef struct GreasePencil {
blender::bke::greasepencil::LayerGroup &parent_group);
/* Search functions. */
const blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name) const;
blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name);
const blender::bke::greasepencil::LayerGroup *find_layer_group_by_name(
blender::StringRefNull name) const;
blender::bke::greasepencil::LayerGroup *find_layer_group_by_name(blender::StringRefNull name);
const blender::bke::greasepencil::TreeNode *find_node_by_name(blender::StringRefNull name) const;
blender::bke::greasepencil::TreeNode *find_node_by_name(blender::StringRefNull name);
void rename_node(blender::bke::greasepencil::TreeNode &node, blender::StringRefNull new_name);

View File

@ -788,9 +788,12 @@ typedef struct bNodeTree {
void ensure_interface_cache() const;
/* Cached interface item lists. */
blender::Span<bNodeTreeInterfaceSocket *> interface_inputs() const;
blender::Span<bNodeTreeInterfaceSocket *> interface_outputs() const;
blender::Span<bNodeTreeInterfaceItem *> interface_items() const;
blender::Span<bNodeTreeInterfaceSocket *> interface_inputs();
blender::Span<const bNodeTreeInterfaceSocket *> interface_inputs() const;
blender::Span<bNodeTreeInterfaceSocket *> interface_outputs();
blender::Span<const bNodeTreeInterfaceSocket *> interface_outputs() const;
blender::Span<bNodeTreeInterfaceItem *> interface_items();
blender::Span<const bNodeTreeInterfaceItem *> interface_items() const;
#endif
} bNodeTree;