Geometry Nodes: Support node tools in object mode #114819
|
@ -55,11 +55,13 @@ def geometry_node_group_empty_tool_new(context):
|
|||
else:
|
||||
group.is_type_mesh = True
|
||||
|
||||
mode = context.object.mode if context.object else 'EDIT'
|
||||
mode = context.object.mode if context.object else 'OBJECT'
|
||||
if mode in {'SCULPT', 'SCULPT_CURVES'}:
|
||||
group.is_mode_sculpt = True
|
||||
else:
|
||||
elif mode == 'EDIT':
|
||||
group.is_mode_edit = True
|
||||
else:
|
||||
group.is_mode_object = True
|
||||
|
||||
return group
|
||||
|
||||
|
|
|
@ -472,6 +472,7 @@ class NODE_PT_geometry_node_tool_mode(Panel):
|
|||
group = snode.node_tree
|
||||
|
||||
modes = (
|
||||
("is_mode_object", "Object Mode", 'OBJECT_DATAMODE'),
|
||||
("is_mode_edit", "Edit Mode", 'EDITMODE_HLT'),
|
||||
("is_mode_sculpt", "Sculpt Mode", 'SCULPTMODE_HLT'),
|
||||
)
|
||||
|
|
|
@ -1169,9 +1169,12 @@ class VIEW3D_MT_editor_menus(Menu):
|
|||
layout.menu("VIEW3D_MT_select_sculpt_curves")
|
||||
layout.menu("VIEW3D_MT_sculpt_curves")
|
||||
layout.template_node_operator_asset_root_items()
|
||||
else:
|
||||
layout.template_node_operator_asset_root_items()
|
||||
|
||||
else:
|
||||
layout.menu("VIEW3D_MT_object")
|
||||
layout.template_node_operator_asset_root_items()
|
||||
|
||||
|
||||
# ********** Menu **********
|
||||
|
@ -2743,6 +2746,8 @@ class VIEW3D_MT_object(Menu):
|
|||
layout.operator("object.delete", text="Delete").use_global = False
|
||||
layout.operator("object.delete", text="Delete Global").use_global = True
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="Object")
|
||||
|
||||
|
||||
class VIEW3D_MT_object_animation(Menu):
|
||||
bl_label = "Animation"
|
||||
|
@ -3021,6 +3026,8 @@ class VIEW3D_MT_object_context_menu(Menu):
|
|||
layout.operator_context = 'EXEC_REGION_WIN'
|
||||
layout.operator("object.delete", text="Delete").use_global = False
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="Object")
|
||||
|
||||
|
||||
class VIEW3D_MT_object_shading(Menu):
|
||||
# XXX, this menu is a place to store shading operator in object mode
|
||||
|
@ -3098,6 +3105,8 @@ class VIEW3D_MT_object_apply(Menu):
|
|||
text="Parent Inverse",
|
||||
text_ctxt=i18n_contexts.default)
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="Object/Apply")
|
||||
|
||||
|
||||
class VIEW3D_MT_object_parent(Menu):
|
||||
bl_label = "Parent"
|
||||
|
@ -3180,6 +3189,7 @@ class VIEW3D_MT_object_quick_effects(Menu):
|
|||
layout.operator("object.quick_explode")
|
||||
layout.operator("object.quick_smoke")
|
||||
layout.operator("object.quick_liquid")
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="Object/Quick Effects")
|
||||
|
||||
|
||||
class VIEW3D_MT_object_showhide(Menu):
|
||||
|
@ -3271,6 +3281,8 @@ class VIEW3D_MT_object_convert(Menu):
|
|||
|
||||
if ob and ob.type == 'CURVES':
|
||||
layout.operator("curves.convert_to_particle_system", text="Particle System")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="Object/Convert")
|
||||
|
||||
|
||||
class VIEW3D_MT_make_links(Menu):
|
||||
|
|
|
@ -287,6 +287,39 @@ static IDProperty *replace_inputs_evaluated_data_blocks(const IDProperty &op_pro
|
|||
return properties;
|
||||
}
|
||||
|
||||
static bool object_has_editable_data(const Main &bmain, const Object &object)
|
||||
{
|
||||
if (!ELEM(object.type, OB_CURVES, OB_POINTCLOUD, OB_MESH)) {
|
||||
return false;
|
||||
}
|
||||
if (!BKE_id_is_editable(&bmain, static_cast<const ID *>(object.data))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static Vector<Object *> gather_supported_objects(const bContext &C,
|
||||
const Main &bmain,
|
||||
const eObjectMode mode)
|
||||
{
|
||||
Vector<Object *> objects;
|
||||
Set<const ID *> unique_object_data;
|
||||
CTX_DATA_BEGIN (&C, Object *, object, selected_objects) {
|
||||
if (object->mode != mode) {
|
||||
continue;
|
||||
}
|
||||
if (!unique_object_data.add(static_cast<const ID *>(object->data))) {
|
||||
continue;
|
||||
}
|
||||
if (!object_has_editable_data(bmain, *object)) {
|
||||
continue;
|
||||
}
|
||||
objects.append(object);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
return objects;
|
||||
}
|
||||
|
||||
static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
@ -296,9 +329,6 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
|||
if (!active_object) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (active_object->mode == OB_MODE_OBJECT) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
const eObjectMode mode = eObjectMode(active_object->mode);
|
||||
|
||||
const bNodeTree *node_tree_orig = get_node_group(*C, *op->ptr, op->reports);
|
||||
|
@ -306,13 +336,10 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
uint objects_len = 0;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
|
||||
scene, view_layer, CTX_wm_view3d(C), &objects_len, mode);
|
||||
BLI_SCOPED_DEFER([&]() { MEM_SAFE_FREE(objects); });
|
||||
const Vector<Object *> objects = gather_supported_objects(*C, *bmain, mode);
|
||||
|
||||
Depsgraph *depsgraph = build_depsgraph_from_indirect_ids(
|
||||
*bmain, *scene, *view_layer, *node_tree_orig, {objects, objects_len}, *op->properties);
|
||||
*bmain, *scene, *view_layer, *node_tree_orig, objects, *op->properties);
|
||||
DEG_evaluate_on_refresh(depsgraph);
|
||||
BLI_SCOPED_DEFER([&]() { DEG_graph_free(depsgraph); });
|
||||
|
||||
|
@ -348,11 +375,9 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
|||
|
||||
OperatorComputeContext compute_context(op->type->idname);
|
||||
|
||||
for (Object *object : Span(objects, objects_len)) {
|
||||
if (!ELEM(object->type, OB_CURVES, OB_POINTCLOUD, OB_MESH)) {
|
||||
continue;
|
||||
}
|
||||
for (Object *object : objects) {
|
||||
nodes::GeoNodesOperatorData operator_eval_data{};
|
||||
operator_eval_data.mode = mode;
|
||||
operator_eval_data.depsgraph = depsgraph;
|
||||
operator_eval_data.self_object = DEG_get_evaluated_object(depsgraph, object);
|
||||
operator_eval_data.scene = DEG_get_evaluated_scene(depsgraph);
|
||||
|
@ -600,72 +625,138 @@ static bool asset_menu_poll(const bContext *C, MenuType * /*mt*/)
|
|||
return CTX_wm_view3d(C);
|
||||
}
|
||||
|
||||
static GeometryNodeAssetTraitFlag asset_flag_for_context(const eContextObjectMode ctx_mode)
|
||||
static GeometryNodeAssetTraitFlag asset_flag_for_context(const ObjectType type,
|
||||
const eObjectMode mode)
|
||||
{
|
||||
switch (ctx_mode) {
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_EDIT | GEO_NODE_ASSET_MESH);
|
||||
case CTX_MODE_EDIT_CURVES:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_EDIT | GEO_NODE_ASSET_CURVE);
|
||||
case CTX_MODE_EDIT_POINT_CLOUD:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_EDIT | GEO_NODE_ASSET_POINT_CLOUD);
|
||||
case CTX_MODE_SCULPT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_SCULPT | GEO_NODE_ASSET_MESH);
|
||||
case CTX_MODE_SCULPT_CURVES:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_SCULPT | GEO_NODE_ASSET_CURVE);
|
||||
switch (type) {
|
||||
case OB_MESH: {
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_OBJECT | GEO_NODE_ASSET_MESH);
|
||||
case OB_MODE_EDIT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_EDIT | GEO_NODE_ASSET_MESH);
|
||||
case OB_MODE_SCULPT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_SCULPT | GEO_NODE_ASSET_MESH);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_CURVES: {
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_OBJECT | GEO_NODE_ASSET_CURVE);
|
||||
case OB_MODE_EDIT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_EDIT | GEO_NODE_ASSET_CURVE);
|
||||
case OB_MODE_SCULPT_CURVES:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_SCULPT | GEO_NODE_ASSET_CURVE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_POINTCLOUD: {
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_OBJECT | GEO_NODE_ASSET_POINT_CLOUD);
|
||||
case OB_MODE_EDIT:
|
||||
return (GEO_NODE_ASSET_TOOL | GEO_NODE_ASSET_EDIT | GEO_NODE_ASSET_POINT_CLOUD);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return GeometryNodeAssetTraitFlag(0);
|
||||
break;
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return GeometryNodeAssetTraitFlag(0);
|
||||
}
|
||||
|
||||
static asset::AssetItemTree *get_static_item_tree(const eContextObjectMode mode)
|
||||
static GeometryNodeAssetTraitFlag asset_flag_for_context(const Object &active_object)
|
||||
{
|
||||
switch (mode) {
|
||||
case CTX_MODE_EDIT_MESH: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
return asset_flag_for_context(ObjectType(active_object.type), eObjectMode(active_object.mode));
|
||||
}
|
||||
|
||||
static asset::AssetItemTree *get_static_item_tree(const ObjectType type, const eObjectMode mode)
|
||||
{
|
||||
switch (type) {
|
||||
case OB_MESH: {
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case OB_MODE_EDIT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case OB_MODE_SCULPT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
case CTX_MODE_EDIT_CURVES: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
case OB_CURVES: {
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case OB_MODE_EDIT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case OB_MODE_SCULPT_CURVES: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
case CTX_MODE_EDIT_POINT_CLOUD: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case CTX_MODE_SCULPT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case CTX_MODE_SCULPT_CURVES: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
case OB_POINTCLOUD: {
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case OB_MODE_EDIT: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static asset::AssetItemTree *get_static_item_tree(const bContext &C)
|
||||
static asset::AssetItemTree *get_static_item_tree(const Object &active_object)
|
||||
{
|
||||
return get_static_item_tree(eContextObjectMode(CTX_data_mode_enum(&C)));
|
||||
return get_static_item_tree(ObjectType(active_object.type), eObjectMode(active_object.mode));
|
||||
}
|
||||
|
||||
void clear_operator_asset_trees()
|
||||
{
|
||||
for (const int mode : IndexRange(CTX_MODE_NUM)) {
|
||||
if (asset::AssetItemTree *tree = get_static_item_tree(eContextObjectMode(mode)))
|
||||
*tree = {};
|
||||
for (const ObjectType type : {OB_MESH, OB_CURVES, OB_POINTCLOUD}) {
|
||||
for (const eObjectMode mode : {OB_MODE_OBJECT, OB_MODE_EDIT, OB_MODE_SCULPT_CURVES}) {
|
||||
if (asset::AssetItemTree *tree = get_static_item_tree(type, mode)) {
|
||||
*tree = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static asset::AssetItemTree build_catalog_tree(const bContext &C)
|
||||
static asset::AssetItemTree build_catalog_tree(const bContext &C, const Object &active_object)
|
||||
{
|
||||
const eContextObjectMode ctx_mode = eContextObjectMode(CTX_data_mode_enum(&C));
|
||||
AssetFilterSettings type_filter{};
|
||||
type_filter.id_types = FILTER_ID_NT;
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(ctx_mode);
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(active_object);
|
||||
auto meta_data_filter = [&](const AssetMetaData &meta_data) {
|
||||
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type");
|
||||
if (tree_type == nullptr || IDP_Int(tree_type) != NTREE_GEOMETRY) {
|
||||
|
@ -703,6 +794,15 @@ static Set<std::string> get_builtin_menus(const ObjectType object_type, const eO
|
|||
break;
|
||||
case OB_MESH:
|
||||
switch (mode) {
|
||||
case OB_MODE_OBJECT:
|
||||
menus.add_new("View");
|
||||
menus.add_new("Select");
|
||||
menus.add_new("Add");
|
||||
menus.add_new("Object");
|
||||
menus.add_new("Object/Apply");
|
||||
menus.add_new("Object/Convert");
|
||||
menus.add_new("Object/Quick Effects");
|
||||
break;
|
||||
case OB_MODE_EDIT:
|
||||
menus.add_new("View");
|
||||
menus.add_new("Select");
|
||||
|
@ -752,7 +852,7 @@ static void catalog_assets_draw(const bContext *C, Menu *menu)
|
|||
if (!active_object) {
|
||||
return;
|
||||
}
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*C);
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*active_object);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
@ -822,9 +922,11 @@ MenuType node_group_operator_assets_menu()
|
|||
static bool unassigned_local_poll(const bContext &C)
|
||||
{
|
||||
Main &bmain = *CTX_data_main(&C);
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(
|
||||
eContextObjectMode(CTX_data_mode_enum(&C)));
|
||||
|
||||
const Object *active_object = CTX_data_active_object(&C);
|
||||
if (!active_object) {
|
||||
return false;
|
||||
}
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(*active_object);
|
||||
LISTBASE_FOREACH (const bNodeTree *, group, &bmain.nodetrees) {
|
||||
/* Assets are displayed in other menus, and non-local data-blocks aren't added to this menu. */
|
||||
if (group->id.library_weak_reference || group->id.asset_data) {
|
||||
|
@ -841,7 +943,11 @@ static bool unassigned_local_poll(const bContext &C)
|
|||
|
||||
static void catalog_assets_draw_unassigned(const bContext *C, Menu *menu)
|
||||
{
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*C);
|
||||
const Object *active_object = CTX_data_active_object(C);
|
||||
if (!active_object) {
|
||||
return;
|
||||
}
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*active_object);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
@ -860,8 +966,7 @@ static void catalog_assets_draw_unassigned(const bContext *C, Menu *menu)
|
|||
asset::operator_asset_reference_props_set(*asset, props_ptr);
|
||||
}
|
||||
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(
|
||||
eContextObjectMode(CTX_data_mode_enum(C)));
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(*active_object);
|
||||
|
||||
bool first = true;
|
||||
bool add_separator = !tree->unassigned_assets.is_empty();
|
||||
|
@ -919,7 +1024,11 @@ void ui_template_node_operator_asset_menu_items(uiLayout &layout,
|
|||
const StringRef catalog_path)
|
||||
{
|
||||
bScreen &screen = *CTX_wm_screen(&C);
|
||||
asset::AssetItemTree *tree = get_static_item_tree(C);
|
||||
const Object *active_object = CTX_data_active_object(&C);
|
||||
if (!active_object) {
|
||||
return;
|
||||
}
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*active_object);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
@ -948,12 +1057,12 @@ void ui_template_node_operator_asset_root_items(uiLayout &layout, const bContext
|
|||
if (!active_object) {
|
||||
return;
|
||||
}
|
||||
asset::AssetItemTree *tree = get_static_item_tree(C);
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*active_object);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
if (tree->assets_per_path.size() == 0) {
|
||||
*tree = build_catalog_tree(C);
|
||||
*tree = build_catalog_tree(C, *active_object);
|
||||
}
|
||||
|
||||
asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available(
|
||||
|
|
|
@ -931,8 +931,9 @@ typedef enum GeometryNodeAssetTraitFlag {
|
|||
GEO_NODE_ASSET_CURVE = (1 << 4),
|
||||
GEO_NODE_ASSET_POINT_CLOUD = (1 << 5),
|
||||
GEO_NODE_ASSET_MODIFIER = (1 << 6),
|
||||
GEO_NODE_ASSET_OBJECT = (1 << 7),
|
||||
} GeometryNodeAssetTraitFlag;
|
||||
ENUM_OPERATORS(GeometryNodeAssetTraitFlag, GEO_NODE_ASSET_MODIFIER);
|
||||
ENUM_OPERATORS(GeometryNodeAssetTraitFlag, GEO_NODE_ASSET_OBJECT);
|
||||
|
||||
/* Data structs, for `node->storage`. */
|
||||
|
||||
|
|
|
@ -1802,6 +1802,15 @@ static void rna_GeometryNodeTree_is_modifier_set(PointerRNA *ptr, bool value)
|
|||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_MODIFIER, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_mode_object_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_OBJECT);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_mode_object_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_OBJECT, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_mode_edit_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_EDIT);
|
||||
|
@ -10272,6 +10281,14 @@ static void rna_def_geometry_nodetree(BlenderRNA *brna)
|
|||
prop, "rna_GeometryNodeTree_is_modifier_get", "rna_GeometryNodeTree_is_modifier_set");
|
||||
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update_asset");
|
||||
|
||||
prop = RNA_def_property(srna, "is_mode_object", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_EDIT);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Edit", "The node group is used in object mode");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_GeometryNodeTree_is_mode_object_get", "rna_GeometryNodeTree_is_mode_object_set");
|
||||
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update_asset");
|
||||
|
||||
prop = RNA_def_property(srna, "is_mode_edit", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_EDIT);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
|
|
@ -166,6 +166,7 @@ struct GeoNodesModifierData {
|
|||
};
|
||||
|
||||
struct GeoNodesOperatorData {
|
||||
eObjectMode mode;
|
||||
/** The object currently effected by the operator. */
|
||||
const Object *self_object = nullptr;
|
||||
/** Current evaluated depsgraph. */
|
||||
|
|
|
@ -53,7 +53,12 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
if (!check_tool_context_and_error(params)) {
|
||||
return;
|
||||
}
|
||||
params.set_output("Selection", Field<bool>(std::make_shared<ToolSelectionFieldInput>()));
|
||||
if (params.user_data()->operator_data->mode == OB_MODE_OBJECT) {
|
||||
params.set_output("Selection", true);
|
||||
}
|
||||
else {
|
||||
params.set_output("Selection", Field<bool>(std::make_shared<ToolSelectionFieldInput>()));
|
||||
}
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
|
|
|
@ -37,6 +37,11 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
if (!check_tool_context_and_error(params)) {
|
||||
return;
|
||||
}
|
||||
if (params.user_data()->operator_data->mode == OB_MODE_OBJECT) {
|
||||
params.error_message_add(NodeWarningType::Error,
|
||||
"Selection control is not supported in object mode");
|
||||
return;
|
||||
}
|
||||
const Field<bool> selection = params.extract_input<Field<bool>>("Selection");
|
||||
const eAttrDomain domain = eAttrDomain(params.node().custom1);
|
||||
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
|
||||
|
|
Loading…
Reference in New Issue