Mesh: Replace MLoop struct with generic attributes #104424

Merged
Hans Goudey merged 261 commits from refactor-mesh-corners-generic into main 2023-03-20 15:55:25 +01:00
41 changed files with 699 additions and 450 deletions
Showing only changes of commit 8e944a4416 - Show all commits

View File

@ -29,11 +29,11 @@
icon_modifier="#84b8ffff"
icon_shading="#ea7581ff"
icon_folder="#e3c16eff"
icon_border_intensity="0.85"
icon_border_intensity="1"
>
<wcol_regular>
<ThemeWidgetColors
outline="#b8b8b8"
outline="#4d4d4d"
inner="#dbdbdbff"
inner_sel="#668cccff"
item="#191919ff"
@ -48,7 +48,7 @@
</wcol_regular>
<wcol_tool>
<ThemeWidgetColors
outline="#b8b8b8"
outline="#4d4d4d"
inner="#dbdbdbff"
inner_sel="#5680c2ff"
item="#191919ff"
@ -63,7 +63,7 @@
</wcol_tool>
<wcol_toolbar_item>
<ThemeWidgetColors
outline="#363636"
outline="#4d4d4d"
inner="#434343ff"
inner_sel="#5680c2ff"
item="#e6e6e6cc"
@ -78,7 +78,7 @@
</wcol_toolbar_item>
<wcol_radio>
<ThemeWidgetColors
outline="#434343"
outline="#4d4d4d"
inner="#3b3b3bff"
inner_sel="#5680c2e6"
item="#ffffffff"
@ -93,7 +93,7 @@
</wcol_radio>
<wcol_text>
<ThemeWidgetColors
outline="#666666"
outline="#4d4d4d"
inner="#282828ff"
inner_sel="#333333ff"
item="#5680c2ff"
@ -108,7 +108,7 @@
</wcol_text>
<wcol_option>
<ThemeWidgetColors
outline="#373737"
outline="#4d4d4d"
inner="#3c3c3cff"
inner_sel="#5680c2ff"
item="#ffffffff"
@ -123,8 +123,8 @@
</wcol_option>
<wcol_toggle>
<ThemeWidgetColors
outline="#999999"
inner="#c0c0c0ff"
outline="#4d4d4d"
inner="#dbdbdbff"
inner_sel="#5680c2ff"
item="#191919ff"
text="#000000"
@ -138,7 +138,7 @@
</wcol_toggle>
<wcol_num>
<ThemeWidgetColors
outline="#b8b8b8"
outline="#4d4d4d"
inner="#d3d3d3ff"
inner_sel="#5680c2ff"
item="#80b1ffff"
@ -153,7 +153,7 @@
</wcol_num>
<wcol_numslider>
<ThemeWidgetColors
outline="#b8b8b8"
outline="#4d4d4d"
inner="#999999ff"
inner_sel="#999999ff"
item="#e6e6e6ff"
@ -168,8 +168,8 @@
</wcol_numslider>
<wcol_box>
<ThemeWidgetColors
outline="#959595"
inner="#cccccc80"
outline="#4d4d4d"
inner="#80808080"
inner_sel="#5680c2ff"
item="#191919ff"
text="#333333"
@ -183,7 +183,7 @@
</wcol_box>
<wcol_menu>
<ThemeWidgetColors
outline="#3b3b3b"
outline="#3d3d3d"
inner="#3b3b3bff"
inner_sel="#767676ff"
item="#808080ff"
@ -217,7 +217,7 @@
inner="#c0c0c0ff"
inner_sel="#cdcdcdff"
item="#727272ff"
text="#1a1a1a"
text="#4d4d4d"
text_sel="#1a1a1a"
show_shaded="FALSE"
shadetop="25"
@ -304,11 +304,11 @@
<wcol_list_item>
<ThemeWidgetColors
outline="#e6e6e6"
inner="#00000000"
inner_sel="#808080ff"
inner="#1a1a1a00"
inner_sel="#c0c0c0ff"
item="#1a1a1aff"
text="#1a1a1a"
text_sel="#ffffff"
text_sel="#000000"
show_shaded="FALSE"
shadetop="0"
shadedown="0"
@ -316,6 +316,21 @@
>
</ThemeWidgetColors>
</wcol_list_item>
<wcol_view_item>
<ThemeWidgetColors
outline="#e6e6e6"
inner="#c0c0c044"
inner_sel="#c0c0c0ff"
item="#1a1a1aff"
text="#1a1a1a"
text_sel="#000000"
show_shaded="FALSE"
shadetop="0"
shadedown="0"
roundness="0.4"
>
</ThemeWidgetColors>
</wcol_view_item>
<wcol_state>
<ThemeWidgetStateColors
inner_anim="#73be4c"
@ -334,8 +349,8 @@
</wcol_state>
<wcol_tab>
<ThemeWidgetColors
outline="#656565"
inner="#818181ff"
outline="#333333"
inner="#808080cc"
inner_sel="#b3b3b3ff"
item="#28292dff"
text="#1a1a1a"
@ -414,6 +429,7 @@
bone_locked_weight="#ff000080"
bundle_solid="#c8c8c8"
camera_path="#000000"
camera_passepartout="#000000"
skin_root="#b44d4d"
view_overlay="#000000"
transform="#ffffff"
@ -452,9 +468,9 @@
</gradients>
<panelcolors>
<ThemePanelColors
header="#b3b3b3ff"
back="#b3b3b3cc"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -519,9 +535,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -552,7 +568,7 @@
header="#adadadff"
header_text="#000000"
header_text_hi="#ffffff"
button="#999999e6"
button="#b3b3b3ff"
button_title="#1a1a1a"
button_text="#000000"
button_text_hi="#000000"
@ -565,9 +581,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -623,9 +639,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -698,9 +714,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -783,9 +799,9 @@
>
<panelcolors>
<ThemePanelColors
header="#b3b3b3ff"
back="#b3b3b3cc"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -843,14 +859,23 @@
>
<panelcolors>
<ThemePanelColors
header="#b3b3b3ff"
back="#b3b3b3cc"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
<ThemeSpaceListGeneric
list="#181818"
list_title="#ffffff"
list_text="#ffffff"
list_text_hi="#ffffff"
>
</ThemeSpaceListGeneric>
</space_list>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
@ -871,7 +896,7 @@
button_title="#000000"
button_text="#000000"
button_text_hi="#000000"
navigation_bar="#656565ff"
navigation_bar="#1d1d1dff"
execution_buts="#00000000"
tab_active="#6697e6"
tab_inactive="#535353"
@ -880,9 +905,9 @@
>
<panelcolors>
<ThemePanelColors
header="#b3b3b300"
back="#a3a3a3cc"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -927,9 +952,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -939,44 +964,44 @@
</text_editor>
<node_editor>
<ThemeNodeEditor
grid="#1B1B1B"
node_selected="#f15800"
node_active="#f15800"
wire="#191919"
wire_inner="#999999"
wire_select="#ffa733"
selected_text="#7f7070"
node_backdrop="#e6e6e6ff"
converter_node="#66c4ff"
color_node="#ffcb4d"
group_node="#59b36ab9"
group_socket_node="#dfc300"
frame_node="#9b9b9b60"
matte_node="#977474"
distor_node="#749797"
grid="#282828"
node_selected="#ed5700"
node_active="#ffffff"
wire="#1a1a1aff"
wire_inner="#8d8d8d"
wire_select="#ffffffb3"
selected_text="#7f7f7f"
node_backdrop="#666666ff"
converter_node="#12adff"
color_node="#cccc00"
group_node="#3b660a"
group_socket_node="#000000"
frame_node="#0f0f0fcc"
matte_node="#973c3c"
distor_node="#4c9797"
noodle_curving="4"
grid_levels="3"
dash_alpha="0.5"
input_node="#cb3d4a"
output_node="#cb3d4a"
filter_node="#6c696f"
vector_node="#9999ff"
texture_node="#ffc399"
shader_node="#ea7581"
script_node="#6c696f"
input_node="#ff3371"
output_node="#4d0017"
filter_node="#551a80"
vector_node="#4d4dff"
texture_node="#e66800"
shader_node="#24b524"
script_node="#084d4d"
pattern_node="#6c696f"
layout_node="#6c696f"
geometry_node="#00d7a4"
attribute_node="#3f5980"
geometry_node="#00d6a3"
attribute_node="#001566"
>
<space>
<ThemeSpaceGeneric
back="#353535"
title="#000000"
text="#000000"
back="#1d1d1d"
title="#eeeeee"
text="#e6e6e6"
text_hi="#ffffff"
header="#b3b3b3ff"
header_text="#000000"
header_text="#eeeeee"
header_text_hi="#ffffff"
button="#99999900"
button_title="#1a1a1a"
@ -991,9 +1016,9 @@
>
<panelcolors>
<ThemePanelColors
header="#b3b3b3ff"
back="#b3b3b3cc"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1013,8 +1038,8 @@
<outliner>
<ThemeOutliner
match="#337f33"
selected_highlight="#7a8e99"
active="#92aab7"
selected_highlight="#7a8499"
active="#929eb7"
selected_object="#ffddb3"
active_object="#ffffff"
edited_object="#0080624d"
@ -1042,9 +1067,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1091,9 +1116,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1125,9 +1150,9 @@
>
<panelcolors>
<ThemePanelColors
header="#b3b3b300"
back="#a3a3a3cc"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1137,26 +1162,26 @@
</preferences>
<console>
<ThemeConsole
line_output="#6080ff"
line_input="#ffffff"
line_info="#00aa00"
line_error="#dc6060"
cursor="#dc6060"
line_output="#71a8ff"
line_input="#f2f2f2"
line_info="#95d600"
line_error="#ff4d84"
cursor="#ff0000"
select="#ffffff30"
>
<space>
<ThemeSpaceGeneric
back="#000000"
title="#000000"
text="#000000"
back="#1d1d1d"
title="#eeeeee"
text="#e6e6e6"
text_hi="#ffffff"
header="#b3b3b3ff"
header_text="#000000"
header_text_hi="#ffffff"
button="#7272727f"
button_title="#000000"
button_text="#000000"
button_text_hi="#000000"
button="#30303000"
button_title="#ffffff"
button_text="#cccccc"
button_text_hi="#ffffff"
navigation_bar="#00000000"
execution_buts="#00000000"
tab_active="#6697e6"
@ -1166,9 +1191,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1231,9 +1256,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1274,9 +1299,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1292,7 +1317,7 @@
title="#ffffff"
text="#ffffff"
text_hi="#ffffff"
header="#adadadff"
header="#999999ff"
header_text="#1a1a1a"
header_text_hi="#ffffff"
button="#2f303500"
@ -1308,9 +1333,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1331,7 +1356,7 @@
header="#adadadff"
header_text="#000000"
header_text_hi="#ffffff"
button="#999999e6"
button="#b3b3b3ff"
button_title="#1a1a1a"
button_text="#000000"
button_text_hi="#000000"
@ -1344,9 +1369,9 @@
>
<panelcolors>
<ThemePanelColors
header="#42424200"
back="#00000028"
sub_back="#00000024"
header="#ccccccff"
back="#ccccccff"
sub_back="#0000000f"
>
</ThemePanelColors>
</panelcolors>
@ -1585,8 +1610,8 @@
shadow="3"
shadow_offset_x="0"
shadow_offset_y="-1"
shadow_alpha="0.3"
shadow_value="0.7"
shadow_alpha="1"
shadow_value="0.8"
>
</ThemeFontStyle>
</panel_title>
@ -1596,8 +1621,8 @@
shadow="3"
shadow_offset_x="0"
shadow_offset_y="-1"
shadow_alpha="0.3"
shadow_value="0.7"
shadow_alpha="0"
shadow_value="0.8"
>
</ThemeFontStyle>
</widget_label>
@ -1607,8 +1632,8 @@
shadow="1"
shadow_offset_x="0"
shadow_offset_y="-1"
shadow_alpha="0.3"
shadow_value="0.7"
shadow_alpha="0"
shadow_value="0.8"
>
</ThemeFontStyle>
</widget>

View File

@ -5631,6 +5631,8 @@ def km_curves(params):
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
("curves.delete", {"type": 'X', "value": 'PRESS'}, None),
("curves.delete", {"type": 'DEL', "value": 'PRESS'}, None),
("curves.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("curves.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
])
return keymap

View File

@ -111,6 +111,7 @@ class QuickFur(ObjectModeOperator, Operator):
bpy.ops.wm.append(directory=assets_directory,
filename=name,
use_recursive=True,
clear_asset_data=True,
do_reuse_local_id=True)
generate_group = bpy.data.node_groups["Generate Hair Curves"]
interpolate_group = bpy.data.node_groups["Interpolate Hair Curves"]

View File

@ -604,7 +604,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
colliding_names = []
for collection in (
# Built-in names.
{"shade_smooth": None, "normal": None, "crease": None},
{"shade_smooth": None, "crease": None},
mesh.attributes,
None if ob is None else ob.vertex_groups,
):

View File

@ -2044,6 +2044,16 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
layout.operator("paint.vert_select_linked", text="Select Linked")
class VIEW3D_MT_edit_curves_select_more_less(Menu):
bl_label = "Select More/Less"
def draw(self, _context):
layout = self.layout
layout.operator("curves.select_more", text="More")
layout.operator("curves.select_less", text="Less")
class VIEW3D_MT_select_edit_curves(Menu):
bl_label = "Select"
@ -2053,10 +2063,17 @@ class VIEW3D_MT_select_edit_curves(Menu):
layout.operator("curves.select_all", text="All").action = 'SELECT'
layout.operator("curves.select_all", text="None").action = 'DESELECT'
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
layout.separator()
layout.operator("curves.select_random", text="Random")
layout.operator("curves.select_end", text="Endpoints")
layout.operator("curves.select_linked", text="Linked")
layout.separator()
layout.menu("VIEW3D_MT_edit_curves_select_more_less")
class VIEW3D_MT_select_sculpt_curves(Menu):
bl_label = "Select"
@ -8046,6 +8063,7 @@ classes = (
VIEW3D_MT_select_gpencil,
VIEW3D_MT_select_paint_mask,
VIEW3D_MT_select_paint_mask_vertex,
VIEW3D_MT_edit_curves_select_more_less,
VIEW3D_MT_select_edit_curves,
VIEW3D_MT_select_sculpt_curves,
VIEW3D_MT_mesh_add,

View File

@ -41,10 +41,10 @@ struct PropertyRNA;
*/
void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user);
/**
* Remove the given NLA track from the set of NLA tracks, free the track's data,
* and the track itself.
* Remove & Frees all NLA strips from the given NLA track,
* then frees (doesn't remove) the track itself.
*/
void BKE_nlatrack_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user);
void BKE_nlatrack_free(struct NlaTrack *nlt, bool do_id_user);
/**
* Free the elements of type NLA Tracks provided in the given list, but do not free
* the list itself since that is not free-standing
@ -95,6 +95,17 @@ struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt,
struct NlaTrack *prev,
bool is_liboverride);
/**
* Removes the given NLA track from the list of tracks provided.
*/
void BKE_nlatrack_remove(ListBase *tracks, struct NlaTrack *nlt);
/**
* Remove the given NLA track from the list of NLA tracks, free the track's data,
* and the track itself.
*/
void BKE_nlatrack_remove_and_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user);
/**
* Create a NLA Strip referencing the given Action.
*/

View File

@ -316,9 +316,6 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons
GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const
{
if (writable_ != Writable) {
return {};
}
CustomData *custom_data = custom_data_access_.get_custom_data(owner);
if (custom_data == nullptr) {
return {};
@ -905,10 +902,8 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
BLI_assert(src);
bke::GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
id, meta_data.domain, meta_data.data_type);
if (dst) {
/* Writing the the legacy "normal" attribute will fail. */
attributes.append({std::move(src), meta_data, std::move(dst)});
}
BLI_assert(dst);
attributes.append({std::move(src), meta_data, std::move(dst)});
return true;
});

View File

@ -37,10 +37,6 @@ class BuiltinAttributeProvider {
Creatable,
NonCreatable,
};
enum WritableEnum {
Writable,
Readonly,
};
enum DeletableEnum {
Deletable,
NonDeletable,
@ -51,7 +47,6 @@ class BuiltinAttributeProvider {
const eAttrDomain domain_;
const eCustomDataType data_type_;
const CreatableEnum createable_;
const WritableEnum writable_;
const DeletableEnum deletable_;
const AttributeValidator validator_;
@ -60,14 +55,12 @@ class BuiltinAttributeProvider {
const eAttrDomain domain,
const eCustomDataType data_type,
const CreatableEnum createable,
const WritableEnum writable,
const DeletableEnum deletable,
AttributeValidator validator = {})
: name_(std::move(name)),
domain_(domain),
data_type_(data_type),
createable_(createable),
writable_(writable),
deletable_(deletable),
validator_(validator)
{
@ -205,20 +198,14 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
const eCustomDataType attribute_type,
const eCustomDataType stored_type,
const CreatableEnum creatable,
const WritableEnum writable,
const DeletableEnum deletable,
const CustomDataAccessInfo custom_data_access,
const AsReadAttribute as_read_attribute,
const AsWriteAttribute as_write_attribute,
const UpdateOnChange update_on_write,
const AttributeValidator validator = {})
: BuiltinAttributeProvider(std::move(attribute_name),
domain,
attribute_type,
creatable,
writable,
deletable,
validator),
: BuiltinAttributeProvider(
std::move(attribute_name), domain, attribute_type, creatable, deletable, validator),
stored_type_(stored_type),
custom_data_access_(custom_data_access),
as_read_attribute_(as_read_attribute),

View File

@ -375,7 +375,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_FLOAT3,
CD_PROP_FLOAT3,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
@ -387,7 +386,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_FLOAT,
CD_PROP_FLOAT,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
@ -399,7 +397,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int>,
@ -411,7 +408,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_FLOAT,
CD_PROP_FLOAT,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
@ -423,7 +419,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_FLOAT3,
CD_PROP_FLOAT3,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float3>,
@ -435,7 +430,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_FLOAT3,
CD_PROP_FLOAT3,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float3>,
@ -453,7 +447,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT8,
CD_PROP_INT8,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int8_t>,
@ -466,7 +459,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT8,
CD_PROP_INT8,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int8_t>,
@ -479,7 +471,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_FLOAT,
CD_PROP_FLOAT,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
@ -495,7 +486,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT8,
CD_PROP_INT8,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
@ -514,7 +504,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT8,
CD_PROP_INT8,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
@ -533,7 +522,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT8,
CD_PROP_INT8,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
@ -552,7 +540,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT8,
CD_PROP_INT8,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
@ -569,7 +556,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int>,
@ -582,7 +568,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
CD_PROP_BOOL,
CD_PROP_BOOL,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<bool>,

View File

@ -129,7 +129,7 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider
public:
InstancePositionAttributeProvider()
: BuiltinAttributeProvider(
"position", ATTR_DOMAIN_INSTANCE, CD_PROP_FLOAT3, NonCreatable, Writable, NonDeletable)
"position", ATTR_DOMAIN_INSTANCE, CD_PROP_FLOAT3, NonCreatable, NonDeletable)
{
}
@ -200,7 +200,6 @@ static ComponentAttributeProviders create_attribute_providers_for_instances()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
instance_custom_data_access,
make_array_read_attribute<int>,

View File

@ -1121,48 +1121,6 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
}
};
/**
* This provider makes face normals available as a read-only float3 attribute.
*/
class NormalAttributeProvider final : public BuiltinAttributeProvider {
public:
NormalAttributeProvider()
: BuiltinAttributeProvider(
"normal", ATTR_DOMAIN_FACE, CD_PROP_FLOAT3, NonCreatable, Readonly, NonDeletable)
{
}
GVArray try_get_for_read(const void *owner) const final
{
const Mesh *mesh = static_cast<const Mesh *>(owner);
if (mesh == nullptr || mesh->totpoly == 0) {
return {};
}
return VArray<float3>::ForSpan({(float3 *)BKE_mesh_poly_normals_ensure(mesh), mesh->totpoly});
}
GAttributeWriter try_get_for_write(void * /*owner*/) const final
{
return {};
}
bool try_delete(void * /*owner*/) const final
{
return false;
}
bool try_create(void * /*owner*/, const AttributeInit & /*initializer*/) const final
{
return false;
}
bool exists(const void *owner) const final
{
const Mesh *mesh = static_cast<const Mesh *>(owner);
return mesh->totpoly != 0;
}
};
/**
* In this function all the attribute providers for a mesh component are created. Most data in this
* function is statically allocated, because it does not change over time.
@ -1206,21 +1164,17 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_FLOAT3,
CD_PROP_FLOAT3,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static NormalAttributeProvider normal;
static BuiltinCustomDataLayerProvider id("id",
ATTR_DOMAIN_POINT,
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int>,
@ -1239,7 +1193,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
face_access,
make_array_read_attribute<int>,
@ -1258,7 +1211,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
corner_access,
make_array_read_attribute<int>,
@ -1270,7 +1222,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
corner_access,
make_array_read_attribute<int>,
@ -1284,7 +1235,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_BOOL,
CD_MPOLY,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
face_access,
make_derived_read_attribute<MPoly, bool, get_shade_smooth>,
@ -1296,7 +1246,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_BOOL,
CD_PROP_BOOL,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
edge_access,
make_array_read_attribute<bool>,
@ -1309,7 +1258,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
CD_PROP_FLOAT,
CD_CREASE,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
edge_access,
make_array_read_attribute<float>,
@ -1329,7 +1277,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
&material_index,
&shade_smooth,
&sharp_edge,
&normal,
&crease},
{&corner_custom_data,
&vertex_groups,

View File

@ -142,7 +142,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
CD_PROP_FLOAT3,
CD_PROP_FLOAT3,
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
@ -153,7 +152,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
CD_PROP_FLOAT,
CD_PROP_FLOAT,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
@ -164,7 +162,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
CD_PROP_INT32,
CD_PROP_INT32,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int>,

View File

@ -91,7 +91,7 @@ void BKE_nlastrip_free(NlaStrip *strip, const bool do_id_user)
MEM_freeN(strip);
}
void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
void BKE_nlatrack_free(NlaTrack *nlt, const bool do_id_user)
{
NlaStrip *strip, *stripn;
@ -107,12 +107,7 @@ void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
}
/* free NLA track itself now */
if (tracks) {
BLI_freelinkN(tracks, nlt);
}
else {
MEM_freeN(nlt);
}
MEM_freeN(nlt);
}
void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user)
@ -127,7 +122,7 @@ void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user)
/* free tracks one by one */
for (nlt = tracks->first; nlt; nlt = nltn) {
nltn = nlt->next;
BKE_nlatrack_free(tracks, nlt, do_id_user);
BKE_nlatrack_remove_and_free(tracks, nlt, do_id_user);
}
/* clear the list's pointers to be safe */
@ -514,6 +509,20 @@ void BKE_nla_strip_foreach_id(NlaStrip *strip, LibraryForeachIDData *data)
}
}
/* Removing ------------------------------------------ */
void BKE_nlatrack_remove(ListBase *tracks, struct NlaTrack *nlt)
{
BLI_assert(tracks);
BLI_remlink(tracks, nlt);
}
void BKE_nlatrack_remove_and_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user)
{
BKE_nlatrack_remove(tracks, nlt);
BKE_nlatrack_free(nlt, do_id_user);
}
/* *************************************************** */
/* NLA Evaluation <-> Editing Stuff */

View File

@ -91,4 +91,29 @@ TEST(nla_track, BKE_nlatrack_remove_strip)
EXPECT_EQ(-1, BLI_findindex(&track.strips, &strip2));
}
TEST(nla_track, BKE_nlatrack_remove_and_free)
{
AnimData adt{};
NlaTrack *track1;
NlaTrack *track2;
// Add NLA tracks to the Animation Data.
track1 = BKE_nlatrack_add(&adt, NULL, false);
track2 = BKE_nlatrack_add(&adt, track1, false);
// ensure we have 2 tracks in the track.
EXPECT_EQ(2, BLI_listbase_count(&adt.nla_tracks));
BKE_nlatrack_remove_and_free(&adt.nla_tracks, track2, false);
EXPECT_EQ(1, BLI_listbase_count(&adt.nla_tracks));
// ensure the correct track was removed.
EXPECT_EQ(-1, BLI_findindex(&adt.nla_tracks, track2));
// free the rest of the tracks, and ensure they are removed.
BKE_nlatrack_remove_and_free(&adt.nla_tracks, track1, false);
EXPECT_EQ(0, BLI_listbase_count(&adt.nla_tracks));
EXPECT_EQ(-1, BLI_findindex(&adt.nla_tracks, track1));
}
} // namespace blender::bke::tests

View File

@ -322,11 +322,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_bmesh_merge(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
}
const Vector<MeshToBMeshLayerInfo> vert_info = mesh_to_bm_copy_info_calc(mesh_vdata, bm->vdata);
const Vector<MeshToBMeshLayerInfo> edge_info = mesh_to_bm_copy_info_calc(mesh_edata, bm->edata);
const Vector<MeshToBMeshLayerInfo> poly_info = mesh_to_bm_copy_info_calc(mesh_pdata, bm->pdata);
const Vector<MeshToBMeshLayerInfo> loop_info = mesh_to_bm_copy_info_calc(mesh_ldata, bm->ldata);
/* -------------------------------------------------------------------- */
/* Shape Key */
int tot_shape_keys = 0;
@ -411,6 +406,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
}
const Vector<MeshToBMeshLayerInfo> vert_info = mesh_to_bm_copy_info_calc(mesh_vdata, bm->vdata);
const Vector<MeshToBMeshLayerInfo> edge_info = mesh_to_bm_copy_info_calc(mesh_edata, bm->edata);
const Vector<MeshToBMeshLayerInfo> poly_info = mesh_to_bm_copy_info_calc(mesh_pdata, bm->pdata);
const Vector<MeshToBMeshLayerInfo> loop_info = mesh_to_bm_copy_info_calc(mesh_ldata, bm->ldata);
if (is_new) {
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);

View File

@ -23,6 +23,7 @@ set(INC
set(SRC
intern/curves_add.cc
intern/curves_data.cc
intern/curves_edit.cc
intern/curves_ops.cc
intern/curves_selection.cc
intern/curves_undo.cc

View File

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edcurves
*/
#include "BLI_index_mask_ops.hh"
#include "BKE_curves.hh"
#include "ED_curves.h"
namespace blender::ed::curves {
bool remove_selection(bke::CurvesGeometry &curves, const eAttrDomain selection_domain)
{
const bke::AttributeAccessor attributes = curves.attributes();
const VArray<bool> selection = attributes.lookup_or_default<bool>(
".selection", selection_domain, true);
const int domain_size_orig = attributes.domain_size(selection_domain);
Vector<int64_t> indices;
const IndexMask mask = index_mask_ops::find_indices_from_virtual_array(
selection.index_range(), selection, 4096, indices);
switch (selection_domain) {
case ATTR_DOMAIN_POINT:
curves.remove_points(mask);
break;
case ATTR_DOMAIN_CURVE:
curves.remove_curves(mask);
break;
default:
BLI_assert_unreachable();
}
return attributes.domain_size(selection_domain) != domain_size_orig;
}
} // namespace blender::ed::curves

View File

@ -1008,6 +1008,60 @@ static void CURVES_OT_select_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int select_more_exec(bContext *C, wmOperator * /*op*/)
{
VectorSet<Curves *> unique_curves = get_unique_editable_curves(*C);
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_adjacent(curves, false);
/* 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);
}
return OPERATOR_FINISHED;
}
static void CURVES_OT_select_more(wmOperatorType *ot)
{
ot->name = "Select More";
ot->idname = __func__;
ot->description = "Grow the selection by one point";
ot->exec = select_more_exec;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int select_less_exec(bContext *C, wmOperator * /*op*/)
{
VectorSet<Curves *> unique_curves = get_unique_editable_curves(*C);
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_adjacent(curves, 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);
}
return OPERATOR_FINISHED;
}
static void CURVES_OT_select_less(wmOperatorType *ot)
{
ot->name = "Select Less";
ot->idname = __func__;
ot->description = "Shrink the selection by one point";
ot->exec = select_less_exec;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
namespace surface_set {
static bool surface_set_poll(bContext *C)
@ -1097,24 +1151,7 @@ static int delete_exec(bContext *C, wmOperator * /*op*/)
{
for (Curves *curves_id : get_unique_editable_curves(*C)) {
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
const eAttrDomain domain = eAttrDomain(curves_id->selection_domain);
const bke::AttributeAccessor attributes = curves.attributes();
const VArray<bool> selection = attributes.lookup_or_default<bool>(".selection", domain, false);
const int domain_size_orig = attributes.domain_size(domain);
Vector<int64_t> indices;
const IndexMask mask = index_mask_ops::find_indices_from_virtual_array(
selection.index_range(), selection, 4096, indices);
switch (domain) {
case ATTR_DOMAIN_POINT:
curves.remove_points(mask);
break;
case ATTR_DOMAIN_CURVE:
curves.remove_curves(mask);
break;
default:
BLI_assert_unreachable();
}
if (attributes.domain_size(domain) != domain_size_orig) {
if (remove_selection(curves, eAttrDomain(curves_id->selection_domain))) {
DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id);
}
@ -1150,6 +1187,8 @@ void ED_operatortypes_curves()
WM_operatortype_append(CURVES_OT_select_random);
WM_operatortype_append(CURVES_OT_select_end);
WM_operatortype_append(CURVES_OT_select_linked);
WM_operatortype_append(CURVES_OT_select_more);
WM_operatortype_append(CURVES_OT_select_less);
WM_operatortype_append(CURVES_OT_surface_set);
WM_operatortype_append(CURVES_OT_delete);
}

View File

@ -267,6 +267,85 @@ void select_linked(bke::CurvesGeometry &curves)
selection.finish();
}
void select_adjacent(bke::CurvesGeometry &curves, const bool deselect)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
const VArray<bool> cyclic = curves.cyclic();
if (deselect) {
invert_selection(selection.span);
}
if (selection.span.type().is<bool>()) {
MutableSpan<bool> selection_typed = selection.span.typed<bool>();
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
const IndexRange points = points_by_curve[curve_i];
/* Handle all cases in the forward direction. */
for (int point_i = points.first(); point_i < points.last(); point_i++) {
if (!selection_typed[point_i] && selection_typed[point_i + 1]) {
selection_typed[point_i] = true;
}
}
/* Handle all cases in the backwards direction. */
for (int point_i = points.last(); point_i > points.first(); point_i--) {
if (!selection_typed[point_i] && selection_typed[point_i - 1]) {
selection_typed[point_i] = true;
}
}
/* Handle cyclic curve case. */
if (cyclic[curve_i]) {
if (selection_typed[points.first()] != selection_typed[points.last()]) {
selection_typed[points.first()] = true;
selection_typed[points.last()] = true;
}
}
}
});
}
else if (selection.span.type().is<float>()) {
MutableSpan<float> selection_typed = selection.span.typed<float>();
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
const IndexRange points = points_by_curve[curve_i];
/* Handle all cases in the forward direction. */
for (int point_i = points.first(); point_i < points.last(); point_i++) {
if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i + 1] > 0.0f)) {
selection_typed[point_i] = 1.0f;
}
}
/* Handle all cases in the backwards direction. */
for (int point_i = points.last(); point_i > points.first(); point_i--) {
if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i - 1] > 0.0f)) {
selection_typed[point_i] = 1.0f;
}
}
/* Handle cyclic curve case. */
if (cyclic[curve_i]) {
if (selection_typed[points.first()] != selection_typed[points.last()]) {
selection_typed[points.first()] = 1.0f;
selection_typed[points.last()] = 1.0f;
}
}
}
});
}
if (deselect) {
invert_selection(selection.span);
}
selection.finish();
}
void select_random(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
uint32_t random_seed,

View File

@ -135,6 +135,11 @@ void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points);
*/
void select_linked(bke::CurvesGeometry &curves);
/**
* (De)select all the adjacent points of the current selected points.
*/
void select_adjacent(bke::CurvesGeometry &curves, bool deselect);
/**
* Select random points or curves.
*
@ -185,5 +190,17 @@ bool select_circle(const ViewContext &vc,
eSelectOp sel_op);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Editing
* \{ */
/**
* Remove (dissolve) selected curves or points based on the ".selection" attribute.
* \returns true if any point or curve was removed.
*/
bool remove_selection(bke::CurvesGeometry &curves, eAttrDomain selection_domain);
/** \} */
} // namespace blender::ed::curves
#endif

View File

@ -239,6 +239,17 @@ enum {
UI_BUT_OVERRIDDEN = 1u << 31u,
};
/** #uiBut.dragflag */
enum {
/** By default only the left part of a button triggers dragging. A questionable design to make
* the icon but not other parts of the button draggable. Set this flag so the entire button can
* be dragged. */
UI_BUT_DRAG_FULL_BUT = (1 << 0),
/* --- Internal flags. --- */
UI_BUT_DRAGPOIN_FREE = (1 << 1),
};
/* Default font size for normal text. */
#define UI_DEFAULT_TEXT_POINTS 11.0f
@ -881,6 +892,9 @@ bool UI_but_flag_is_set(uiBut *but, int flag);
void UI_but_drawflag_enable(uiBut *but, int flag);
void UI_but_drawflag_disable(uiBut *but, int flag);
void UI_but_dragflag_enable(uiBut *but, int flag);
void UI_but_dragflag_disable(uiBut *but, int flag);
void UI_but_disable(uiBut *but, const char *disabled_hint);
void UI_but_type_set_menu_from_pulldown(uiBut *but);
@ -1789,9 +1803,12 @@ void UI_but_drag_set_id(uiBut *but, struct ID *id);
/**
* Set an image to display while dragging. This works for any drag type (`WM_DRAG_XXX`).
* Not to be confused with #UI_but_drag_set_image(), which sets up dragging of an image.
*
* Sets #UI_BUT_DRAG_FULL_BUT so the full button can be dragged.
*/
void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale);
/**
* Sets #UI_BUT_DRAG_FULL_BUT so the full button can be dragged.
* \param asset: May be passed from a temporary variable, drag data only stores a copy of this.
*/
void UI_but_drag_set_asset(uiBut *but,
@ -1808,6 +1825,8 @@ void UI_but_drag_set_name(uiBut *but, const char *name);
* Value from button itself.
*/
void UI_but_drag_set_value(uiBut *but);
/** Sets #UI_BUT_DRAG_FULL_BUT so the full button can be dragged. */
void UI_but_drag_set_image(
uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, bool use_free);

View File

@ -4224,6 +4224,10 @@ static uiBut *ui_def_but(uiBlock *block,
but->flag |= UI_BUT_UNDO;
}
if (ELEM(but->type, UI_BTYPE_COLOR)) {
but->dragflag |= UI_BUT_DRAG_FULL_BUT;
}
BLI_addtail(&block->buttons, but);
if (block->curlayout) {
@ -5890,6 +5894,16 @@ void UI_but_drawflag_disable(uiBut *but, int flag)
but->drawflag &= ~flag;
}
void UI_but_dragflag_enable(uiBut *but, int flag)
{
but->dragflag |= flag;
}
void UI_but_dragflag_disable(uiBut *but, int flag)
{
but->dragflag &= ~flag;
}
void UI_but_disable(uiBut *but, const char *disabled_hint)
{
UI_but_flag_enable(but, UI_BUT_DISABLED);

View File

@ -24,6 +24,7 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, const float scale)
{
but->imb = imb;
but->imb_scale = scale;
UI_but_dragflag_enable(but, UI_BUT_DRAG_FULL_BUT);
}
void UI_but_drag_set_asset(uiBut *but,

View File

@ -86,11 +86,6 @@ enum {
/* WARNING: rest of #uiBut.flag in UI_interface.h */
};
/** #uiBut.dragflag */
enum {
UI_BUT_DRAGPOIN_FREE = (1 << 0),
};
/** #uiBut.pie_dir */
enum RadialDirection {
UI_RADIAL_NONE = -1,

View File

@ -247,7 +247,7 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv
BLI_rcti_rctf_copy(&rect, &but->rect);
if (but->imb || but->type == UI_BTYPE_COLOR) {
if (but->dragflag & UI_BUT_DRAG_FULL_BUT) {
/* use button size itself */
}
else if (but->drawflag & UI_BUT_ICON_LEFT) {

View File

@ -92,15 +92,9 @@ void attribute_search_add_items(StringRefNull str,
StringSearch *search = BLI_string_search_new();
for (const GeometryAttributeInfo *item : infos) {
/* Don't show the legacy "normal" attribute. */
if (item->name == "normal" && item->domain == ATTR_DOMAIN_FACE) {
continue;
}
if (!bke::allow_procedural_attribute_access(item->name)) {
continue;
}
BLI_string_search_add(search, item->name.c_str(), (void *)item, 0);
}

View File

@ -1540,8 +1540,13 @@ void ED_mesh_split_faces(Mesh *mesh)
const Span<int> corner_verts = mesh->corner_verts();
const Span<int> corner_edges = mesh->corner_edges();
const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI);
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray<bool> mesh_sharp_edges = attributes.lookup_or_default<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE, false);
Array<bool> sharp_edges(mesh->totedge);
mesh_sharp_edges.materialize(sharp_edges);
Array<bool> sharp_edges(mesh->totedge, false);
BKE_edges_sharp_from_angle_set(mesh->totedge,
corner_verts.data(),
corner_edges.data(),

View File

@ -832,6 +832,36 @@ static Brush *brush_tool_toggle(Main *bmain, Paint *paint, Brush *brush_orig, co
return nullptr;
}
/** The name of the active tool is "builtin_brush." concatenated with the returned string. */
static blender::StringRefNull curves_active_tool_name_get(const eBrushCurvesSculptTool tool)
{
switch (tool) {
case CURVES_SCULPT_TOOL_COMB:
return "comb";
case CURVES_SCULPT_TOOL_DELETE:
return "delete";
case CURVES_SCULPT_TOOL_SNAKE_HOOK:
return "snake_hook";
case CURVES_SCULPT_TOOL_ADD:
return "add";
case CURVES_SCULPT_TOOL_GROW_SHRINK:
return "grow_shrink";
case CURVES_SCULPT_TOOL_SELECTION_PAINT:
return "selection_paint";
case CURVES_SCULPT_TOOL_PINCH:
return "pinch";
case CURVES_SCULPT_TOOL_SMOOTH:
return "smooth";
case CURVES_SCULPT_TOOL_PUFF:
return "puff";
case CURVES_SCULPT_TOOL_DENSITY:
return "density";
case CURVES_SCULPT_TOOL_SLIDE:
return "slide";
}
return "";
}
static bool brush_generic_tool_set(bContext *C,
Main *bmain,
Paint *paint,
@ -869,8 +899,14 @@ static bool brush_generic_tool_set(bContext *C,
* tool_name again. */
int tool_result = brush_tool(brush, paint->runtime.tool_offset);
ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C);
const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
RNA_enum_name_from_value(items, tool_result, &tool_name);
if (paint_mode == PAINT_MODE_SCULPT_CURVES) {
tool_name = curves_active_tool_name_get(eBrushCurvesSculptTool(tool)).c_str();
}
else {
const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
RNA_enum_name_from_value(items, tool_result, &tool_name);
}
char tool_id[MAX_NAME];
SNPRINTF(tool_id, "builtin_brush.%s", tool_name);
@ -921,8 +957,14 @@ static int brush_select_exec(bContext *C, wmOperator *op)
if (paint == nullptr) {
return OPERATOR_CANCELLED;
}
const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
RNA_enum_name_from_value(items, tool, &tool_name);
if (paint_mode == PAINT_MODE_SCULPT_CURVES) {
tool_name = curves_active_tool_name_get(eBrushCurvesSculptTool(tool)).c_str();
}
else {
const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
RNA_enum_name_from_value(items, tool, &tool_name);
}
if (brush_generic_tool_set(C, bmain, paint, tool, tool_name, create_missing, toggle)) {
return OPERATOR_FINISHED;

View File

@ -590,7 +590,7 @@ void ED_animedit_unlink_action(
if (nlt->strips.first == NULL) {
BLI_assert(nstrip == NULL);
BKE_nlatrack_free(&adt->nla_tracks, nlt, true);
BKE_nlatrack_remove_and_free(&adt->nla_tracks, nlt, true);
}
}
}

View File

@ -793,7 +793,7 @@ static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
}
break;
case NC_ID:
if (wmn->action == NA_RENAME) {
if (ELEM(wmn->action, NA_RENAME, NA_EDITED)) {
ED_area_tag_redraw(area);
}
break;

View File

@ -128,16 +128,55 @@ static void draw_tile_background(const rcti *draw_rect, int colorid, int shade)
UI_draw_roundbox_aa(&draw_rect_fl, true, 5.0f, color);
}
static void file_draw_icon(const SpaceFile *sfile,
uiBlock *block,
const FileDirEntry *file,
const char *path,
const rcti *tile_draw_rect,
int icon,
int width,
int height,
bool drag,
bool dimmed)
static void file_but_enable_drag(uiBut *but,
const SpaceFile *sfile,
const FileDirEntry *file,
const char *path,
ImBuf *preview_image,
int icon,
float scale)
{
ID *id;
if ((id = filelist_file_get_id(file))) {
UI_but_drag_set_id(but, id);
if (preview_image) {
UI_but_drag_attach_image(but, preview_image, scale);
}
}
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
(file->typeflag & FILE_TYPE_ASSET) != 0) {
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
BLI_assert(import_method > -1);
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
import_method,
icon,
preview_image,
scale);
}
}
else if (preview_image) {
UI_but_drag_set_image(but, BLI_strdup(path), icon, preview_image, scale, true);
}
else {
/* path is no more static, cannot give it directly to but... */
UI_but_drag_set_path(but, BLI_strdup(path), true);
}
}
static uiBut *file_add_icon_but(const SpaceFile *sfile,
uiBlock *block,
const char *path,
const rcti *tile_draw_rect,
int icon,
int width,
int height,
bool dimmed)
{
uiBut *but;
@ -151,42 +190,7 @@ static void file_draw_icon(const SpaceFile *sfile,
block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, a1, a2, NULL);
UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path), MEM_freeN);
if (drag) {
/* TODO: duplicated from file_draw_preview(). */
ID *id;
if ((id = filelist_file_get_id(file))) {
UI_but_drag_set_id(but, id);
ImBuf *preview_image = filelist_file_getimage(file);
if (preview_image) {
UI_but_drag_attach_image(but, preview_image, UI_DPI_FAC);
}
}
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
(file->typeflag & FILE_TYPE_ASSET) != 0) {
ImBuf *preview_image = filelist_file_getimage(file);
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
BLI_assert(asset_params != NULL);
const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
BLI_assert(import_method > -1);
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
import_method,
icon,
preview_image,
UI_DPI_FAC);
}
}
else {
/* path is no more static, cannot give it directly to but... */
UI_but_drag_set_path(but, BLI_strdup(path), true);
}
}
return but;
}
static void file_draw_string(int sx,
@ -297,21 +301,50 @@ void file_calc_previews(const bContext *C, ARegion *region)
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
}
static void file_draw_preview(const SpaceFile *sfile,
uiBlock *block,
const FileDirEntry *file,
const char *path,
static void file_add_preview_drag_but(const SpaceFile *sfile,
uiBlock *block,
FileLayout *layout,
const FileDirEntry *file,
const char *path,
const rcti *tile_draw_rect,
ImBuf *preview_image,
const int icon,
const float scale)
{
/* Invisible button for dragging. */
rcti drag_rect = *tile_draw_rect;
/* A bit smaller than the full tile, to increase the gap between items that users can drag from
* for box select. */
BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y);
uiBut *but = uiDefBut(block,
UI_BTYPE_LABEL,
0,
"",
drag_rect.xmin,
drag_rect.ymin,
BLI_rcti_size_x(&drag_rect),
BLI_rcti_size_y(&drag_rect),
NULL,
0.0,
0.0,
0,
0,
NULL);
file_but_enable_drag(but, sfile, file, path, preview_image, icon, scale);
}
static void file_draw_preview(const FileDirEntry *file,
const rcti *tile_draw_rect,
const float icon_aspect,
ImBuf *imb,
const int icon,
FileLayout *layout,
const bool is_icon,
const bool drag,
const bool dimmed,
const bool is_link)
const bool is_link,
float *r_scale)
{
uiBut *but;
float fx, fy;
float dx, dy;
int xco, yco;
@ -528,62 +561,11 @@ static void file_draw_preview(const SpaceFile *sfile,
immUnbindProgram();
}
/* Invisible button for dragging. */
rcti drag_rect = *tile_draw_rect;
/* A bit smaller than the full tile, to increase the gap between items that users can drag from
* for box select. */
BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y);
but = uiDefBut(block,
UI_BTYPE_LABEL,
0,
"",
drag_rect.xmin,
drag_rect.ymin,
BLI_rcti_size_x(&drag_rect),
BLI_rcti_size_y(&drag_rect),
NULL,
0.0,
0.0,
0,
0,
NULL);
/* Drag-region. */
if (drag) {
ID *id;
if ((id = filelist_file_get_id(file))) {
UI_but_drag_set_id(but, id);
UI_but_drag_attach_image(but, imb, scale);
}
/* path is no more static, cannot give it directly to but... */
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
(file->typeflag & FILE_TYPE_ASSET) != 0) {
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
BLI_assert(asset_params != NULL);
const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
BLI_assert(import_method > -1);
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
import_method,
icon,
imb,
scale);
}
}
else {
UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true);
}
}
GPU_blend(GPU_BLEND_NONE);
if (r_scale) {
*r_scale = scale;
}
}
static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
@ -1036,31 +1018,36 @@ void file_draw_list(const bContext *C, ARegion *region)
is_icon = 1;
}
file_draw_preview(sfile,
block,
file,
path,
float scale = 0;
file_draw_preview(file,
&tile_draw_rect,
thumb_icon_aspect,
imb,
icon,
layout,
is_icon,
do_drag,
is_hidden,
is_link);
is_link,
/* Returns the scale which is needed below. */
&scale);
if (do_drag) {
file_add_preview_drag_but(
sfile, block, layout, file, path, &tile_draw_rect, imb, icon, scale);
}
}
else {
file_draw_icon(sfile,
block,
file,
path,
&tile_draw_rect,
filelist_geticon(files, i, true),
ICON_DEFAULT_WIDTH_SCALE,
ICON_DEFAULT_HEIGHT_SCALE,
do_drag,
is_hidden);
const int icon = filelist_geticon(files, i, true);
uiBut *icon_but = file_add_icon_but(sfile,
block,
path,
&tile_draw_rect,
icon,
ICON_DEFAULT_WIDTH_SCALE,
ICON_DEFAULT_HEIGHT_SCALE,
is_hidden);
if (do_drag) {
file_but_enable_drag(icon_but, sfile, file, path, NULL, icon, UI_DPI_FAC);
}
icon_ofs += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
}

View File

@ -736,7 +736,7 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
}
/* call delete on this track - deletes all strips too */
BKE_nlatrack_free(&adt->nla_tracks, nlt, true);
BKE_nlatrack_remove_and_free(&adt->nla_tracks, nlt, true);
ale->update = ANIM_UPDATE_DEPS;
}
}

View File

@ -60,7 +60,7 @@ bool space_node_view_flag(
int tot = 0;
bool has_frame = false;
if (snode.edittree) {
LISTBASE_FOREACH (const bNode *, node, &snode.edittree->nodes) {
for (const bNode *node : snode.edittree->all_nodes()) {
if ((node->flag & node_flag) == node_flag) {
BLI_rctf_union(&cur_new, &node->runtime->totr);
tot++;

View File

@ -821,7 +821,7 @@ static void node_region_listener(const wmRegionListenerParams *params)
}
break;
case NC_ID:
if (wmn->action == NA_RENAME) {
if (ELEM(wmn->action, NA_RENAME, NA_EDITED)) {
ED_region_tag_redraw(region);
}
break;

View File

@ -842,7 +842,6 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate(
attributes_to_propagate.remove("position");
attributes_to_propagate.remove(".corner_vert");
attributes_to_propagate.remove(".corner_edge");
attributes_to_propagate.remove("normal");
attributes_to_propagate.remove("shade_smooth");
r_create_id = attributes_to_propagate.pop_try("id").has_value();
r_create_material_index = attributes_to_propagate.pop_try("material_index").has_value();

View File

@ -593,7 +593,7 @@ static void rna_NlaTrack_remove(
return;
}
BKE_nlatrack_free(&adt->nla_tracks, track, true);
BKE_nlatrack_remove_and_free(&adt->nla_tracks, track, true);
RNA_POINTER_INVALIDATE(track_ptr);
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL);

View File

@ -93,7 +93,7 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
class SocketSearchOp {
public:
std::string socket_name;
const StringRef socket_name;
eNodeSocketDatatype data_type;
NodeCompareOperation operation;
NodeCompareMode mode = NODE_COMPARE_MODE_ELEMENT;
@ -107,40 +107,62 @@ class SocketSearchOp {
}
};
static std::optional<eNodeSocketDatatype> get_compare_type_for_operation(
const eNodeSocketDatatype type, const NodeCompareOperation operation)
{
switch (type) {
case SOCK_BOOLEAN:
if (ELEM(operation, NODE_COMPARE_COLOR_BRIGHTER, NODE_COMPARE_COLOR_DARKER)) {
return SOCK_RGBA;
}
return SOCK_INT;
case SOCK_INT:
case SOCK_FLOAT:
case SOCK_VECTOR:
if (ELEM(operation, NODE_COMPARE_COLOR_BRIGHTER, NODE_COMPARE_COLOR_DARKER)) {
return SOCK_RGBA;
}
return type;
case SOCK_RGBA:
if (!ELEM(operation,
NODE_COMPARE_COLOR_BRIGHTER,
NODE_COMPARE_COLOR_DARKER,
NODE_COMPARE_EQUAL,
NODE_COMPARE_NOT_EQUAL)) {
return SOCK_VECTOR;
}
return type;
case SOCK_STRING:
if (!ELEM(operation, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL)) {
return std::nullopt;
}
return type;
default:
BLI_assert_unreachable();
return std::nullopt;
}
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const eNodeSocketDatatype type = static_cast<eNodeSocketDatatype>(params.other_socket().type);
if (!ELEM(type, SOCK_BOOLEAN, SOCK_FLOAT, SOCK_RGBA, SOCK_VECTOR, SOCK_INT, SOCK_STRING)) {
const eNodeSocketDatatype type = eNodeSocketDatatype(params.other_socket().type);
if (!ELEM(type, SOCK_INT, SOCK_BOOLEAN, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_STRING)) {
return;
}
const eNodeSocketDatatype mode_type = (type == SOCK_BOOLEAN) ? SOCK_INT : type;
const bool string_type = (type == SOCK_STRING);
const std::string socket_name = params.in_out() == SOCK_IN ? "A" : "Result";
const StringRef socket_name = params.in_out() == SOCK_IN ? "A" : "Result";
for (const EnumPropertyItem *item = rna_enum_node_compare_operation_items;
item->identifier != nullptr;
item++) {
if (item->name != nullptr && item->identifier[0] != '\0') {
if (!string_type &&
ELEM(item->value, NODE_COMPARE_COLOR_BRIGHTER, NODE_COMPARE_COLOR_DARKER)) {
params.add_item(IFACE_(item->name),
SocketSearchOp{socket_name,
SOCK_RGBA,
static_cast<NodeCompareOperation>(item->value)});
}
else if ((!string_type) ||
(string_type && ELEM(item->value, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL))) {
params.add_item(IFACE_(item->name),
SocketSearchOp{socket_name,
mode_type,
static_cast<NodeCompareOperation>(item->value)});
const NodeCompareOperation operation = NodeCompareOperation(item->value);
if (const std::optional<eNodeSocketDatatype> fixed_type = get_compare_type_for_operation(
type, operation)) {
params.add_item(IFACE_(item->name), SocketSearchOp{socket_name, *fixed_type, operation});
}
}
}
/* Add Angle socket. */
if (!string_type && params.in_out() == SOCK_IN) {
if (params.in_out() != SOCK_IN && type != SOCK_STRING) {
params.add_item(
IFACE_("Angle"),
SocketSearchOp{

View File

@ -485,9 +485,6 @@ static void extrude_mesh_edges(Mesh &mesh,
}
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
return true; /* Impossible to write the "normal" attribute. */
}
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
@ -888,9 +885,6 @@ static void extrude_mesh_face_regions(Mesh &mesh,
}
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
return true; /* Impossible to write the "normal" attribute. */
}
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
@ -1185,9 +1179,6 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
}
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
return true; /* Impossible to write the "normal" attribute. */
}
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);

View File

@ -78,16 +78,14 @@ bool node_group_poll_instance(const bNode *node,
const bNodeTree *nodetree,
const char **disabled_hint)
{
if (node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) {
const bNodeTree *grouptree = (const bNodeTree *)node->id;
if (grouptree) {
return nodeGroupPoll(nodetree, grouptree, disabled_hint);
}
return true; /* without a linked node tree, group node is always ok */
if (!node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) {
return false;
}
return false;
const bNodeTree *grouptree = reinterpret_cast<const bNodeTree *>(node->id);
if (!grouptree) {
return true;
}
return nodeGroupPoll(nodetree, grouptree, disabled_hint);
}
bool nodeGroupPoll(const bNodeTree *nodetree,
@ -114,10 +112,9 @@ bool nodeGroupPoll(const bNodeTree *nodetree,
return false;
}
LISTBASE_FOREACH (const bNode *, node, &grouptree->nodes) {
for (const bNode *node : grouptree->all_nodes()) {
if (node->typeinfo->poll_instance &&
!node->typeinfo->poll_instance(
const_cast<bNode *>(node), const_cast<bNodeTree *>(nodetree), r_disabled_hint)) {
!node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) {
return false;
}
}

View File

@ -141,6 +141,9 @@ static int wm_link_append_flag(wmOperator *op)
if (RNA_boolean_get(op->ptr, "do_reuse_local_id")) {
flag |= BLO_LIBLINK_APPEND_LOCAL_ID_REUSE;
}
if (RNA_boolean_get(op->ptr, "clear_asset_data")) {
flag |= BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR;
}
}
if (RNA_boolean_get(op->ptr, "instance_collections")) {
flag |= BLO_LIBLINK_COLLECTION_INSTANCE;
@ -400,6 +403,12 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
"Re-Use Local Data",
"Try to re-use previously matching appended data-blocks instead of appending a new copy");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
prop = RNA_def_boolean(ot->srna,
"clear_asset_data",
false,
"Clear Asset Data",
"Don't add asset meta-data or tags from the original data-block");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
prop = RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select new objects");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);

View File

@ -141,7 +141,7 @@ wmKeyMap *WM_keymap_guess_from_context(const bContext *C)
km_id = "Grease Pencil Stroke Vertex Mode";
break;
case CTX_MODE_SCULPT_CURVES:
km_id = "Curves Sculpt";
km_id = "Sculpt Curves";
break;
}
}