I was experimenting with python scripting and came across registering addons. According to Blender Add-on Tutorial, the register and unregister functions are called when activating and deactivating the addon. I tried this but it seemed that the register function is ignored during activation!
To replicate, copy following script and save it into the addons folder.
bl_info = {
"name": "Example",
"category": "Node",
"location": "Node Editor",
}
import bpy
from bpy.types import NodeTree, Node, NodeSocket
import nodeitems_utils
from nodeitems_utils import NodeItem, NodeCategory
class MyCustomTree(NodeTree):
bl_idname = 'CustomTreeType'
bl_label = "Custom Node Tree"
bl_icon = 'NODETREE'
class MyCustomSocket(NodeSocket):
bl_idname = 'CustomSocketType'
bl_label = "Custom Node Socket"
my_items = (
('DOWN', "Down", "Where your feet are"),
('UP', "Up", "Where your head should be"),
('LEFT', "Left", "Not right"),
('RIGHT', "Right", "Not left"),
)
my_enum_prop: bpy.props.EnumProperty(
name="Direction",
description="Just an example",
items=my_items,
default='UP',
)
def draw(self, context, layout, node, text):
if self.is_output or self.is_linked:
layout.label(text=text)
else:
layout.prop(self, "my_enum_prop", text=text)
def draw_color(self, context, node):
return (1.0, 0.4, 0.216, 0.5)
class MyCustomTreeNode:
@classmethod
def poll(cls, ntree):
return ntree.bl_idname == 'CustomTreeType'
class MyCustomNode(MyCustomTreeNode, Node):
bl_idname = 'CustomNodeType'
bl_label = "Custom Node"
my_string_prop: bpy.props.StringProperty()
my_float_prop: bpy.props.FloatProperty(default=3.1415926)
def init(self, context):
self.inputs.new('CustomSocketType', "Hello")
self.inputs.new('NodeSocketFloat', "World")
self.inputs.new('NodeSocketVector', "!")
self.outputs.new('NodeSocketColor', "How")
self.outputs.new('NodeSocketColor', "are")
self.outputs.new('NodeSocketFloat', "you")
def draw_buttons(self, context, layout):
layout.label(text="Node settings")
layout.prop(self, "my_float_prop")
def draw_buttons_ext(self, context, layout):
layout.prop(self, "my_float_prop")
layout.prop(self, "my_string_prop")
def draw_label(self):
return "Example"
class MyNodeCategory(NodeCategory):
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CustomTreeType'
node_categories = [
MyNodeCategory('SOMENODES', "Some Nodes", items=[
NodeItem("CustomNodeType"),
]),
MyNodeCategory('OTHERNODES', "Other Nodes", items=[
NodeItem("CustomNodeType", label="Node A", settings={
"my_string_prop": repr("Lorem ipsum dolor sit amet"),
"my_float_prop": repr(1.0),
}),
NodeItem("CustomNodeType", label="Node B", settings={
"my_string_prop": repr("consectetur adipisicing elit"),
"my_float_prop": repr(2.0),
}),
]),
]
classes = (
MyCustomTree,
MyCustomSocket,
MyCustomNode,
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
nodeitems_utils.register_node_categories('CUSTOM_NODES', node_categories)
def unregister():
nodeitems_utils.unregister_node_categories('CUSTOM_NODES')
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
if __name__ == "__main__":
register()
To determine the success of the addon, after activation, there should be a "Custom Node Tree" editor.