Geometry Nodes: Operators: Support more object types and modes #109526
|
@ -258,6 +258,24 @@ class NewGeometryNodeTreeAssign(Operator):
|
|||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NewGeometryNodeGroupTool(Operator):
|
||||
"""Create a new geometry node group for an tool"""
|
||||
bl_idname = "node.new_geometry_node_group_tool"
|
||||
bl_label = "New Geometry Node Tool Group"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.space_data.type == 'NODE_EDITOR' and context.space_data.geometry_nodes_type == 'TOOL'
|
||||
|
||||
def execute(self, context):
|
||||
group = geometry_node_group_empty_new()
|
||||
group.asset_mark()
|
||||
group.is_tool = True
|
||||
context.space_data.node_tree = group
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class SimulationZoneOperator:
|
||||
input_node_type = 'GeometryNodeSimulationInput'
|
||||
output_node_type = 'GeometryNodeSimulationOutput'
|
||||
|
@ -458,6 +476,7 @@ class RepeatZoneItemMoveOperator(RepeatZoneOperator, Operator):
|
|||
classes = (
|
||||
NewGeometryNodesModifier,
|
||||
NewGeometryNodeTreeAssign,
|
||||
NewGeometryNodeGroupTool,
|
||||
MoveModifierToNodes,
|
||||
SimulationZoneItemAddOperator,
|
||||
SimulationZoneItemRemoveOperator,
|
||||
|
|
|
@ -161,7 +161,9 @@ class NODE_HT_header(Header):
|
|||
else:
|
||||
row.template_ID(snode, "node_tree", new="node.new_geometry_nodes_modifier")
|
||||
else:
|
||||
layout.template_ID(snode, "node_tree", new="node.new_geometry_node_group_assign")
|
||||
layout.template_ID(snode, "node_tree", new="node.new_geometry_node_group_tool")
|
||||
if snode.node_tree and snode.node_tree.asset_data:
|
||||
layout.popover(panel="NODE_PT_geometry_node_asset_traits")
|
||||
else:
|
||||
# Custom node tree is edited as independent ID block
|
||||
NODE_MT_editor_menus.draw_collapsible(context, layout)
|
||||
|
@ -430,6 +432,33 @@ class NODE_PT_material_slots(Panel):
|
|||
row.operator("object.material_slot_deselect", text="Deselect")
|
||||
|
||||
|
||||
class NODE_PT_geometry_node_asset_traits(Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Asset"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
snode = context.space_data
|
||||
group = snode.node_tree
|
||||
|
||||
col = layout.column(heading="Type")
|
||||
col.prop(group, "is_tool")
|
||||
col = layout.column(heading="Mode")
|
||||
col.active = group.is_tool
|
||||
col.prop(group, "is_mode_edit")
|
||||
col.prop(group, "is_mode_sculpt")
|
||||
col = layout.column(heading="Geometry")
|
||||
col.active = group.is_tool
|
||||
col.prop(group, "is_type_mesh")
|
||||
col.prop(group, "is_type_curve")
|
||||
if context.preferences.experimental.use_new_point_cloud_type:
|
||||
col.prop(group, "is_type_point_cloud")
|
||||
|
||||
|
||||
class NODE_PT_node_color_presets(PresetPanel, Panel):
|
||||
"""Predefined node color"""
|
||||
bl_label = "Color Presets"
|
||||
|
@ -1236,6 +1265,7 @@ classes = (
|
|||
NODE_MT_context_menu,
|
||||
NODE_MT_view_pie,
|
||||
NODE_PT_material_slots,
|
||||
NODE_PT_geometry_node_asset_traits,
|
||||
NODE_PT_node_color_presets,
|
||||
NODE_PT_active_node_generic,
|
||||
NODE_PT_active_node_color,
|
||||
|
|
|
@ -1020,9 +1020,12 @@ class VIEW3D_MT_editor_menus(Menu):
|
|||
layout.menu("VIEW3D_MT_edit_mesh_edges")
|
||||
layout.menu("VIEW3D_MT_edit_mesh_faces")
|
||||
layout.menu("VIEW3D_MT_uv_map", text="UV")
|
||||
layout.template_node_operator_asset_root_items()
|
||||
elif mode_string in {'EDIT_CURVE', 'EDIT_SURFACE'}:
|
||||
layout.menu("VIEW3D_MT_edit_curve_ctrlpoints")
|
||||
layout.menu("VIEW3D_MT_edit_curve_segments")
|
||||
elif mode_string in {'EDIT_CURVES', 'EDIT_POINT_CLOUD'}:
|
||||
layout.template_node_operator_asset_root_items()
|
||||
elif mode_string == 'EDIT_GREASE_PENCIL':
|
||||
layout.menu("VIEW3D_MT_edit_greasepencil_stroke")
|
||||
|
||||
|
@ -1032,6 +1035,7 @@ class VIEW3D_MT_editor_menus(Menu):
|
|||
if mode_string == 'SCULPT':
|
||||
layout.menu("VIEW3D_MT_mask")
|
||||
layout.menu("VIEW3D_MT_face_sets")
|
||||
layout.template_node_operator_asset_root_items()
|
||||
if mode_string == 'SCULPT_CURVES':
|
||||
layout.menu("VIEW3D_MT_select_sculpt_curves")
|
||||
layout.menu("VIEW3D_MT_sculpt_curves")
|
||||
|
@ -1259,6 +1263,8 @@ class VIEW3D_MT_uv_map(Menu):
|
|||
|
||||
layout.operator("uv.reset")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="UV")
|
||||
|
||||
|
||||
# ********** View menus **********
|
||||
|
||||
|
@ -1771,6 +1777,8 @@ class VIEW3D_MT_select_edit_mesh(Menu):
|
|||
layout.operator("mesh.select_axis", text="Side of Active")
|
||||
layout.operator("mesh.select_mirror")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_select_edit_curve(Menu):
|
||||
bl_label = "Select"
|
||||
|
@ -2141,8 +2149,9 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
|||
class VIEW3D_MT_select_edit_point_cloud(Menu):
|
||||
bl_label = "Select"
|
||||
|
||||
def draw(_self, _context):
|
||||
pass
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_curves_select_more_less(Menu):
|
||||
|
@ -2175,6 +2184,8 @@ class VIEW3D_MT_select_edit_curves(Menu):
|
|||
|
||||
layout.menu("VIEW3D_MT_edit_curves_select_more_less")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_select_sculpt_curves(Menu):
|
||||
bl_label = "Select"
|
||||
|
@ -2215,6 +2226,8 @@ class VIEW3D_MT_mesh_add(Menu):
|
|||
layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID')
|
||||
layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY')
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path="Add")
|
||||
|
||||
|
||||
class VIEW3D_MT_curve_add(Menu):
|
||||
bl_idname = "VIEW3D_MT_curve_add"
|
||||
|
@ -3550,6 +3563,7 @@ class VIEW3D_MT_mask(Menu):
|
|||
|
||||
layout.menu("VIEW3D_MT_random_mask", text="Random Mask")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
class VIEW3D_MT_face_sets(Menu):
|
||||
bl_label = "Face Sets"
|
||||
|
@ -3608,6 +3622,8 @@ class VIEW3D_MT_face_sets(Menu):
|
|||
|
||||
props = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_sculpt_set_pivot(Menu):
|
||||
bl_label = "Sculpt Set Pivot"
|
||||
|
@ -4107,6 +4123,8 @@ class VIEW3D_MT_edit_mesh(Menu):
|
|||
|
||||
layout.menu("VIEW3D_MT_edit_mesh_delete")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_context_menu(Menu):
|
||||
bl_label = ""
|
||||
|
@ -4426,6 +4444,8 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
|
|||
|
||||
layout.operator("object.vertex_parent_set")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_edges(Menu):
|
||||
bl_label = "Edge"
|
||||
|
@ -4486,6 +4506,8 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
|
|||
layout.operator("mesh.mark_freestyle_edge").clear = False
|
||||
layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_faces_data(Menu):
|
||||
bl_label = "Face Data"
|
||||
|
@ -4571,6 +4593,8 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
|
|||
|
||||
layout.menu("VIEW3D_MT_edit_mesh_faces_data")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_normals_select_strength(Menu):
|
||||
bl_label = "Select by Face Strength"
|
||||
|
@ -5569,13 +5593,15 @@ class VIEW3D_MT_edit_curves(Menu):
|
|||
layout.menu("VIEW3D_MT_transform")
|
||||
layout.separator()
|
||||
layout.operator("curves.delete")
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_pointcloud(Menu):
|
||||
bl_label = "Point Cloud"
|
||||
|
||||
def draw(_self, _context):
|
||||
pass
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_object_mode_pie(Menu):
|
||||
|
|
|
@ -254,6 +254,11 @@ static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons
|
|||
}
|
||||
}
|
||||
|
||||
if (ntree_src->geometry_node_asset_traits) {
|
||||
ntree_dst->geometry_node_asset_traits = MEM_new<GeometryNodeAssetTraits>(
|
||||
__func__, *ntree_src->geometry_node_asset_traits);
|
||||
}
|
||||
|
||||
if (ntree_src->nested_node_refs) {
|
||||
ntree_dst->nested_node_refs = static_cast<bNestedNodeRef *>(
|
||||
MEM_malloc_arrayN(ntree_src->nested_node_refs_num, sizeof(bNestedNodeRef), __func__));
|
||||
|
@ -324,6 +329,8 @@ static void ntree_free_data(ID *id)
|
|||
BKE_libblock_free_data(&ntree->id, true);
|
||||
}
|
||||
|
||||
MEM_delete(ntree->geometry_node_asset_traits);
|
||||
|
||||
if (ntree->nested_node_refs) {
|
||||
MEM_freeN(ntree->nested_node_refs);
|
||||
}
|
||||
|
@ -704,6 +711,8 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
|
|||
BLO_write_string(writer, panel->name);
|
||||
}
|
||||
|
||||
BLO_write_struct(writer, GeometryNodeAssetTraits, ntree->geometry_node_asset_traits);
|
||||
|
||||
BLO_write_struct_array(
|
||||
writer, bNestedNodeRef, ntree->nested_node_refs_num, ntree->nested_node_refs);
|
||||
|
||||
|
@ -943,6 +952,7 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
|
|||
BLO_read_data_address(reader, &ntree->panels_array[i]->name);
|
||||
}
|
||||
|
||||
BLO_read_data_address(reader, &ntree->geometry_node_asset_traits);
|
||||
BLO_read_data_address(reader, &ntree->nested_node_refs);
|
||||
|
||||
/* TODO: should be dealt by new generic cache handling of IDs... */
|
||||
|
@ -1157,6 +1167,11 @@ static void node_tree_asset_pre_save(void *asset_ptr, AssetMetaData *asset_data)
|
|||
}
|
||||
BKE_asset_metadata_idprop_ensure(asset_data, inputs.release());
|
||||
BKE_asset_metadata_idprop_ensure(asset_data, outputs.release());
|
||||
if (node_tree.geometry_node_asset_traits) {
|
||||
auto property = idprop::create("geometry_node_asset_traits_flag",
|
||||
node_tree.geometry_node_asset_traits->flag);
|
||||
BKE_asset_metadata_idprop_ensure(asset_data, property.release());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
|
|
@ -546,24 +546,69 @@ static bool asset_menu_poll(const bContext *C, MenuType * /*mt*/)
|
|||
return CTX_wm_view3d(C);
|
||||
}
|
||||
|
||||
static asset::AssetItemTree &get_static_item_tree()
|
||||
static GeometryNodeAssetTraitFlag asset_flag_for_context(const eContextObjectMode ctx_mode)
|
||||
{
|
||||
static asset::AssetItemTree tree;
|
||||
return tree;
|
||||
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);
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return GeometryNodeAssetTraitFlag(0);
|
||||
}
|
||||
}
|
||||
|
||||
static asset::AssetItemTree *get_static_item_tree(const bContext &C)
|
||||
{
|
||||
switch (eContextObjectMode(CTX_data_mode_enum(&C))) {
|
||||
case CTX_MODE_EDIT_MESH: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
case CTX_MODE_EDIT_CURVES: {
|
||||
static asset::AssetItemTree tree;
|
||||
return &tree;
|
||||
}
|
||||
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;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static asset::AssetItemTree build_catalog_tree(const bContext &C)
|
||||
{
|
||||
const eContextObjectMode ctx_mode = eContextObjectMode(CTX_data_mode_enum(&C));
|
||||
AssetFilterSettings type_filter{};
|
||||
type_filter.id_types = FILTER_ID_NT;
|
||||
AssetTag operator_tag;
|
||||
STRNCPY(operator_tag.name, "Operator");
|
||||
BLI_addtail(&type_filter.tags, &operator_tag);
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(ctx_mode);
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
const IDProperty *traits_flag = BKE_asset_metadata_idprop_find(
|
||||
&meta_data, "geometry_node_asset_traits_flag");
|
||||
if (traits_flag == nullptr || (IDP_Int(traits_flag) & flag) != flag) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const AssetLibraryReference library = asset_system::all_library_reference();
|
||||
|
@ -580,6 +625,7 @@ static Set<std::string> get_builtin_menus(const ObjectType object_type, const eO
|
|||
Set<std::string> menus;
|
||||
switch (object_type) {
|
||||
case OB_CURVES:
|
||||
case OB_POINTCLOUD:
|
||||
menus.add_new("View");
|
||||
menus.add_new("Select");
|
||||
menus.add_new("Curves");
|
||||
|
@ -622,14 +668,17 @@ static Set<std::string> get_builtin_menus(const ObjectType object_type, const eO
|
|||
static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
|
||||
{
|
||||
bScreen &screen = *CTX_wm_screen(C);
|
||||
asset::AssetItemTree &tree = get_static_item_tree();
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*C);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
const PointerRNA menu_path_ptr = CTX_data_pointer_get(C, "asset_catalog_path");
|
||||
if (RNA_pointer_is_null(&menu_path_ptr)) {
|
||||
return;
|
||||
}
|
||||
const auto &menu_path = *static_cast<const asset_system::AssetCatalogPath *>(menu_path_ptr.data);
|
||||
const Span<asset_system::AssetRepresentation *> assets = tree.assets_per_path.lookup(menu_path);
|
||||
asset_system::AssetCatalogTreeItem *catalog_item = tree.catalogs.find_item(menu_path);
|
||||
const Span<asset_system::AssetRepresentation *> assets = tree->assets_per_path.lookup(menu_path);
|
||||
asset_system::AssetCatalogTreeItem *catalog_item = tree->catalogs.find_item(menu_path);
|
||||
BLI_assert(catalog_item != nullptr);
|
||||
|
||||
if (assets.is_empty() && !catalog_item->has_children()) {
|
||||
|
@ -693,8 +742,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();
|
||||
const asset_system::AssetCatalogTreeItem *item = tree.catalogs.find_root_item(catalog_path);
|
||||
asset::AssetItemTree *tree = get_static_item_tree(C);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
const asset_system::AssetCatalogTreeItem *item = tree->catalogs.find_root_item(catalog_path);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
@ -720,9 +772,12 @@ void ui_template_node_operator_asset_root_items(uiLayout &layout, bContext &C)
|
|||
if (!active_object) {
|
||||
return;
|
||||
}
|
||||
asset::AssetItemTree &tree = get_static_item_tree();
|
||||
tree = build_catalog_tree(C);
|
||||
if (tree.catalogs.is_empty()) {
|
||||
asset::AssetItemTree *tree = get_static_item_tree(C);
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
*tree = build_catalog_tree(C);
|
||||
if (tree->catalogs.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -735,7 +790,7 @@ void ui_template_node_operator_asset_root_items(uiLayout &layout, bContext &C)
|
|||
const Set<std::string> builtin_menus = get_builtin_menus(ObjectType(active_object->type),
|
||||
eObjectMode(active_object->mode));
|
||||
|
||||
tree.catalogs.foreach_root_item([&](asset_system::AssetCatalogTreeItem &item) {
|
||||
tree->catalogs.foreach_root_item([&](asset_system::AssetCatalogTreeItem &item) {
|
||||
if (builtin_menus.contains(item.get_name())) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct bNodeSocketRuntimeHandle bNodeSocketRuntimeHandle;
|
|||
|
||||
struct AnimData;
|
||||
struct Collection;
|
||||
struct GeometryNodeAssetTraits;
|
||||
struct ID;
|
||||
struct Image;
|
||||
struct ImBuf;
|
||||
|
@ -663,6 +664,8 @@ typedef struct bNodeTree {
|
|||
int nested_node_refs_num;
|
||||
bNestedNodeRef *nested_node_refs;
|
||||
|
||||
struct GeometryNodeAssetTraits *geometry_node_asset_traits;
|
||||
|
||||
/** Image representing what the node group does. */
|
||||
struct PreviewImage *preview;
|
||||
|
||||
|
@ -866,6 +869,20 @@ typedef struct bNodeSocketValueMaterial {
|
|||
struct Material *value;
|
||||
} bNodeSocketValueMaterial;
|
||||
|
||||
typedef struct GeometryNodeAssetTraits {
|
||||
int flag;
|
||||
} GeometryNodeAssetTraits;
|
||||
|
||||
typedef enum GeometryNodeAssetTraitFlag {
|
||||
GEO_NODE_ASSET_TOOL = (1 << 0),
|
||||
GEO_NODE_ASSET_EDIT = (1 << 1),
|
||||
GEO_NODE_ASSET_SCULPT = (1 << 2),
|
||||
GEO_NODE_ASSET_MESH = (1 << 3),
|
||||
GEO_NODE_ASSET_CURVE = (1 << 4),
|
||||
GEO_NODE_ASSET_POINT_CLOUD = (1 << 5),
|
||||
} GeometryNodeAssetTraitFlag;
|
||||
ENUM_OPERATORS(GeometryNodeAssetTraitFlag, GEO_NODE_ASSET_POINT_CLOUD);
|
||||
|
||||
/* Data structs, for `node->storage`. */
|
||||
|
||||
typedef enum CMPNodeMaskType {
|
||||
|
|
|
@ -2120,6 +2120,81 @@ static bool compare_main_operation_supported(const EnumPropertyItem *item)
|
|||
return !ELEM(item->value, NODE_COMPARE_COLOR_BRIGHTER, NODE_COMPARE_COLOR_DARKER);
|
||||
}
|
||||
|
||||
static bool geometry_node_asset_trait_flag_get(PointerRNA *ptr,
|
||||
const GeometryNodeAssetTraitFlag flag)
|
||||
{
|
||||
const bNodeTree *ntree = static_cast<const bNodeTree *>(ptr->data);
|
||||
if (!ntree->geometry_node_asset_traits) {
|
||||
return false;
|
||||
}
|
||||
return ntree->geometry_node_asset_traits->flag & flag;
|
||||
}
|
||||
|
||||
static void geometry_node_asset_trait_flag_set(PointerRNA *ptr,
|
||||
const GeometryNodeAssetTraitFlag flag,
|
||||
const bool value)
|
||||
{
|
||||
bNodeTree *ntree = static_cast<bNodeTree *>(ptr->data);
|
||||
if (!ntree->geometry_node_asset_traits) {
|
||||
ntree->geometry_node_asset_traits = MEM_new<GeometryNodeAssetTraits>(__func__);
|
||||
}
|
||||
SET_FLAG_FROM_TEST(ntree->geometry_node_asset_traits->flag, value, flag);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_tool_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_TOOL);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_tool_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_TOOL, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_mode_edit_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_EDIT);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_mode_edit_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_EDIT, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_mode_sculpt_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_SCULPT);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_mode_sculpt_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_SCULPT, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_type_mesh_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_MESH);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_type_mesh_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_MESH, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_type_curve_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_CURVE);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_type_curve_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_CURVE, value);
|
||||
}
|
||||
|
||||
static bool rna_GeometryNodeTree_is_type_point_cloud_get(PointerRNA *ptr)
|
||||
{
|
||||
return geometry_node_asset_trait_flag_get(ptr, GEO_NODE_ASSET_POINT_CLOUD);
|
||||
}
|
||||
static void rna_GeometryNodeTree_is_type_point_cloud_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_POINT_CLOUD, value);
|
||||
}
|
||||
|
||||
static bool compare_rgba_operation_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value,
|
||||
|
@ -12316,12 +12391,56 @@ static void rna_def_texture_nodetree(BlenderRNA *brna)
|
|||
static void rna_def_geometry_nodetree(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GeometryNodeTree", "NodeTree");
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Geometry Node Tree", "Node tree consisting of linked nodes used for geometries");
|
||||
RNA_def_struct_sdna(srna, "bNodeTree");
|
||||
RNA_def_struct_ui_icon(srna, ICON_NODETREE);
|
||||
|
||||
prop = RNA_def_property(srna, "is_tool", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_TOOL);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Tool", "The node group is used as a tool");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_GeometryNodeTree_is_tool_get", "rna_GeometryNodeTree_is_tool_set");
|
||||
|
||||
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);
|
||||
RNA_def_property_ui_text(prop, "Edit", "The node group is used in edit mode");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_GeometryNodeTree_is_mode_edit_get", "rna_GeometryNodeTree_is_mode_edit_set");
|
||||
|
||||
prop = RNA_def_property(srna, "is_mode_sculpt", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_SCULPT);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Sculpt", "The node group is used in sculpt mode");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_GeometryNodeTree_is_mode_sculpt_get", "rna_GeometryNodeTree_is_mode_sculpt_set");
|
||||
|
||||
prop = RNA_def_property(srna, "is_type_mesh", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_MESH);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Mesh", "The node group is used for meshes");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_GeometryNodeTree_is_type_mesh_get", "rna_GeometryNodeTree_is_type_mesh_set");
|
||||
|
||||
prop = RNA_def_property(srna, "is_type_curve", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_CURVE);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Curves", "The node group is used for curves");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_GeometryNodeTree_is_type_curve_get", "rna_GeometryNodeTree_is_type_curve_set");
|
||||
|
||||
prop = RNA_def_property(srna, "is_type_point_cloud", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GEO_NODE_ASSET_POINT_CLOUD);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Point Cloud", "The node group is used for point clouds");
|
||||
RNA_def_property_boolean_funcs(prop,
|
||||
"rna_GeometryNodeTree_is_type_point_cloud_get",
|
||||
"rna_GeometryNodeTree_is_type_point_cloud_set");
|
||||
}
|
||||
|
||||
static StructRNA *define_specific_node(BlenderRNA *brna,
|
||||
|
|
|
@ -59,6 +59,10 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
|||
{
|
||||
const GeoNodesLFUserData &user_data = *static_cast<const GeoNodesLFUserData *>(
|
||||
context.user_data);
|
||||
if (!user_data.modifier_data) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
const GeoNodesModifierData &modifier_data = *user_data.modifier_data;
|
||||
if (modifier_data.current_simulation_state == nullptr) {
|
||||
params.set_default_remaining_outputs();
|
||||
|
|
|
@ -546,6 +546,10 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
|||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
if (!user_data.modifier_data) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
GeoNodesModifierData &modifier_data = *user_data.modifier_data;
|
||||
EvalData &eval_data = *static_cast<EvalData *>(context.storage);
|
||||
BLI_SCOPED_DEFER([&]() { eval_data.is_first_evaluation = false; });
|
||||
|
|
|
@ -234,6 +234,18 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
|||
std::destroy_at(s);
|
||||
}
|
||||
|
||||
static const Object *get_self_object(const GeoNodesLFUserData &user_data)
|
||||
{
|
||||
if (user_data.modifier_data) {
|
||||
return user_data.modifier_data->self_object;
|
||||
}
|
||||
if (user_data.operator_data) {
|
||||
return user_data.operator_data->self_object;
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
Storage *storage = static_cast<Storage *>(context.storage);
|
||||
|
@ -251,7 +263,7 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
|||
const bNodeSocket &bsocket = node_.output_socket(output_bsocket_index);
|
||||
AnonymousAttributeIDPtr attribute_id = MEM_new<NodeAnonymousAttributeID>(
|
||||
__func__,
|
||||
*user_data->modifier_data->self_object,
|
||||
*this->get_self_object(*user_data),
|
||||
*user_data->compute_context,
|
||||
node_,
|
||||
bsocket.identifier,
|
||||
|
@ -838,6 +850,10 @@ class LazyFunctionForViewerInputUsage : public LazyFunction {
|
|||
{
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
if (!user_data->modifier_data) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
const ComputeContextHash &context_hash = user_data->compute_context->hash();
|
||||
const GeoNodesModifierData &modifier_data = *user_data->modifier_data;
|
||||
const Span<const lf::FunctionNode *> nodes_with_side_effects =
|
||||
|
@ -861,6 +877,10 @@ class LazyFunctionForSimulationInputsUsage : public LazyFunction {
|
|||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
if (!user_data.modifier_data) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
const GeoNodesModifierData &modifier_data = *user_data.modifier_data;
|
||||
|
||||
params.set_output(0,
|
||||
|
@ -1328,7 +1348,7 @@ class LazyFunctionForSimulationZone : public LazyFunction {
|
|||
|
||||
GeoNodesLFUserData zone_user_data = user_data;
|
||||
zone_user_data.compute_context = &compute_context;
|
||||
if (user_data.modifier_data->socket_log_contexts) {
|
||||
if (user_data.modifier_data && user_data.modifier_data->socket_log_contexts) {
|
||||
zone_user_data.log_socket_values = user_data.modifier_data->socket_log_contexts->contains(
|
||||
compute_context.hash());
|
||||
}
|
||||
|
@ -1641,7 +1661,7 @@ class LazyFunctionForRepeatZone : public LazyFunction {
|
|||
user_data.compute_context, repeat_output_bnode_, iteration};
|
||||
GeoNodesLFUserData body_user_data = user_data;
|
||||
body_user_data.compute_context = &body_compute_context;
|
||||
if (user_data.modifier_data->socket_log_contexts) {
|
||||
if (user_data.modifier_data && user_data.modifier_data->socket_log_contexts) {
|
||||
body_user_data.log_socket_values = user_data.modifier_data->socket_log_contexts->contains(
|
||||
body_compute_context.hash());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue