nodebpy 0.12.0__tar.gz → 0.13.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nodebpy-0.12.0 → nodebpy-0.13.0}/PKG-INFO +1 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/pyproject.toml +1 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/__init__.py +0 -8
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/__init__.py +3 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/_utils.py +4 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/accessor.py +1 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/mixins.py +10 -2
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/node.py +29 -5
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/socket.py +62 -26
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/tree.py +7 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/__init__.py +29 -13
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/converter.py +1 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/input.py +197 -0
- nodebpy-0.13.0/src/nodebpy/nodes/compositor/manual.py +336 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/__init__.py +16 -2
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/geometry.py +0 -576
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/manual.py +749 -1
- nodebpy-0.13.0/src/nodebpy/nodes/geometry/utilities.py +69 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/zone.py +137 -5
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/__init__.py +18 -14
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/converter.py +1 -75
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/manual.py +2 -1
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/types.py +3 -0
- nodebpy-0.12.0/src/nodebpy/nodes/compositor/manual.py +0 -30
- nodebpy-0.12.0/src/nodebpy/nodes/shader/interface.py +0 -100
- {nodebpy-0.12.0 → nodebpy-0.13.0}/README.md +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/arrange.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/_registry.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/builder/interface.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/diagram.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/__init__.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/graph.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/ordering.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/ranking.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/realize.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/stacking.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/structs.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/sugiyama.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/x_coords.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/arrange/y_coords.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/config.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/lib/nodearrange/utils.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/__init__.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/color.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/distort.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/filter.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/group.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/interface.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/matte.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/output.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/compositor/vector.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/attribute.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/color.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/converter.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/grid.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/group.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/groups.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/input.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/interface.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/output.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/texture.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/geometry/vector.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/color.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/grid.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/group.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/input.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/output.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/script.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/shader.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/texture.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/nodes/shader/vector.py +0 -0
- {nodebpy-0.12.0 → nodebpy-0.13.0}/src/nodebpy/sockets.py +0 -0
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
from . import diagram, nodes, sockets
|
|
2
2
|
from .builder import (
|
|
3
|
-
CustomCompositorGroup,
|
|
4
|
-
CustomGeometryGroup,
|
|
5
|
-
CustomShaderGroup,
|
|
6
|
-
NodeGroupBuilder,
|
|
7
3
|
TreeBuilder,
|
|
8
4
|
)
|
|
9
5
|
from .nodes import compositor, geometry, shader
|
|
@@ -16,8 +12,4 @@ __all__ = [
|
|
|
16
12
|
"sockets",
|
|
17
13
|
"diagram",
|
|
18
14
|
"TreeBuilder",
|
|
19
|
-
"NodeGroupBuilder",
|
|
20
|
-
"GeometryNodeGroup",
|
|
21
|
-
"ShaderNodeGroup",
|
|
22
|
-
"CompositorNodeGroup",
|
|
23
15
|
]
|
|
@@ -67,7 +67,10 @@ def _resolve_promotion(
|
|
|
67
67
|
|
|
68
68
|
if other_prec > self_prec:
|
|
69
69
|
# Other side is dominant — swap so the linker wraps the vector/higher socket
|
|
70
|
-
|
|
70
|
+
if isinstance(other, NodeSocket):
|
|
71
|
+
other_socket = other
|
|
72
|
+
else:
|
|
73
|
+
other_socket = other._default_output_socket
|
|
71
74
|
return other_socket, self_socket, not reverse
|
|
72
75
|
|
|
73
76
|
return self_socket, other, reverse
|
|
@@ -28,7 +28,7 @@ class SocketAccessor:
|
|
|
28
28
|
|
|
29
29
|
def __init__(
|
|
30
30
|
self,
|
|
31
|
-
collection: bpy.types.NodeInputs | bpy.types.NodeOutputs,
|
|
31
|
+
collection: bpy.types.NodeInputs | bpy.types.NodeOutputs | list[NodeSocket],
|
|
32
32
|
direction: Literal["input", "output"],
|
|
33
33
|
):
|
|
34
34
|
self._direction = direction
|
|
@@ -100,9 +100,12 @@ class OperatorMixin:
|
|
|
100
100
|
)
|
|
101
101
|
|
|
102
102
|
def _apply_compare_operation(self, other: Any, operation: str) -> "Math":
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
socket, other, _ = _resolve_promotion(
|
|
104
|
+
self._default_output_socket, # type: ignore[attr-defined]
|
|
105
|
+
other,
|
|
106
|
+
False,
|
|
105
107
|
)
|
|
108
|
+
return _get_socket_linker(socket)._dispatch_compare(other, operation)
|
|
106
109
|
|
|
107
110
|
def __lt__(self, other: Any) -> "Compare":
|
|
108
111
|
return self._apply_compare_operation(other, "less_than")
|
|
@@ -236,6 +239,11 @@ class LinkingMixin:
|
|
|
236
239
|
else:
|
|
237
240
|
inputs = [target]
|
|
238
241
|
|
|
242
|
+
# NodeReroute adapts its type to whatever is linked — skip type matching
|
|
243
|
+
if getattr(getattr(target, "node", None), "bl_idname", None) == "NodeReroute":
|
|
244
|
+
if outputs and inputs:
|
|
245
|
+
return inputs[0], outputs[0]
|
|
246
|
+
|
|
239
247
|
for output in outputs:
|
|
240
248
|
compat_sockets = SOCKET_COMPATIBILITY.get(output.type, ())
|
|
241
249
|
for input in inputs:
|
|
@@ -15,10 +15,13 @@ from typing import (
|
|
|
15
15
|
|
|
16
16
|
import bpy
|
|
17
17
|
from bpy.types import (
|
|
18
|
+
CompositorNodeGroup,
|
|
18
19
|
CompositorNodeTree,
|
|
20
|
+
GeometryNodeGroup,
|
|
19
21
|
GeometryNodeTree,
|
|
20
22
|
Node,
|
|
21
23
|
NodeSocket,
|
|
24
|
+
ShaderNodeGroup,
|
|
22
25
|
ShaderNodeTree,
|
|
23
26
|
)
|
|
24
27
|
|
|
@@ -50,7 +53,7 @@ class BaseNode(_NodeLike, OperatorMixin, LinkingMixin):
|
|
|
50
53
|
_default_output_id: str | None = None
|
|
51
54
|
_placeholder_inputs: list[str]
|
|
52
55
|
|
|
53
|
-
def __init__(self, node:
|
|
56
|
+
def __init__(self, node: Node | None = None):
|
|
54
57
|
tree = (
|
|
55
58
|
TreeBuilder._tree_contexts[-1] if len(TreeBuilder._tree_contexts) else None
|
|
56
59
|
)
|
|
@@ -97,7 +100,7 @@ class BaseNode(_NodeLike, OperatorMixin, LinkingMixin):
|
|
|
97
100
|
return socket
|
|
98
101
|
|
|
99
102
|
@classmethod
|
|
100
|
-
def _from_node(cls, node:
|
|
103
|
+
def _from_node(cls, node: Node) -> Self:
|
|
101
104
|
builder = cls()
|
|
102
105
|
builder.tree.nodes.remove(builder.node)
|
|
103
106
|
builder.node = node
|
|
@@ -274,6 +277,12 @@ class NodeGroupBuilder(BaseNode, ABC, Generic[_T]):
|
|
|
274
277
|
self.node.show_options = False
|
|
275
278
|
self._establish_links(**kwargs)
|
|
276
279
|
|
|
280
|
+
@property
|
|
281
|
+
@abstractmethod
|
|
282
|
+
def node_tree(self) -> _T:
|
|
283
|
+
"""The internal node tree for this group node."""
|
|
284
|
+
...
|
|
285
|
+
|
|
277
286
|
@abstractmethod
|
|
278
287
|
def _setup_node_group(self) -> None:
|
|
279
288
|
"""Set ``self.node.node_tree`` and any node-type-specific properties.
|
|
@@ -304,7 +313,12 @@ class CustomGeometryGroup(NodeGroupBuilder[GeometryNodeTree]):
|
|
|
304
313
|
"""Node group in a Geometry Nodes tree."""
|
|
305
314
|
|
|
306
315
|
_bl_idname = "GeometryNodeGroup"
|
|
307
|
-
node:
|
|
316
|
+
node: GeometryNodeGroup
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def node_tree(self) -> GeometryNodeTree:
|
|
320
|
+
assert self.node.node_tree is not None
|
|
321
|
+
return self.node.node_tree
|
|
308
322
|
|
|
309
323
|
def _setup_node_group(self) -> None:
|
|
310
324
|
self.node.node_tree = self._get_or_create_group()
|
|
@@ -324,7 +338,12 @@ class CustomShaderGroup(NodeGroupBuilder[ShaderNodeTree]):
|
|
|
324
338
|
"""Node group in a Shader (Material) node tree."""
|
|
325
339
|
|
|
326
340
|
_bl_idname = "ShaderNodeGroup"
|
|
327
|
-
node:
|
|
341
|
+
node: ShaderNodeGroup
|
|
342
|
+
|
|
343
|
+
@property
|
|
344
|
+
def node_tree(self) -> ShaderNodeTree:
|
|
345
|
+
assert self.node.node_tree is not None
|
|
346
|
+
return self.node.node_tree
|
|
328
347
|
|
|
329
348
|
def _setup_node_group(self) -> None:
|
|
330
349
|
self.node.node_tree = self._get_or_create_group()
|
|
@@ -343,7 +362,12 @@ class CustomCompositorGroup(NodeGroupBuilder[CompositorNodeTree]):
|
|
|
343
362
|
"""Node group in a Compositor node tree."""
|
|
344
363
|
|
|
345
364
|
_bl_idname = "CompositorNodeGroup"
|
|
346
|
-
node:
|
|
365
|
+
node: CompositorNodeGroup
|
|
366
|
+
|
|
367
|
+
@property
|
|
368
|
+
def node_tree(self) -> CompositorNodeTree:
|
|
369
|
+
assert self.node.node_tree is not None
|
|
370
|
+
return self.node.node_tree
|
|
347
371
|
|
|
348
372
|
def _setup_node_group(self) -> None:
|
|
349
373
|
self.node.node_tree = self._get_or_create_group()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Iterator, overload
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Iterator, cast, overload
|
|
4
4
|
|
|
5
5
|
import bpy
|
|
6
6
|
from bpy.types import (
|
|
@@ -25,6 +25,7 @@ from bpy.types import (
|
|
|
25
25
|
NodeSocketShader,
|
|
26
26
|
NodeSocketString,
|
|
27
27
|
NodeSocketVector,
|
|
28
|
+
NodeTree,
|
|
28
29
|
)
|
|
29
30
|
from mathutils import Euler
|
|
30
31
|
|
|
@@ -55,7 +56,7 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
55
56
|
self.socket = socket
|
|
56
57
|
self.node = socket.node
|
|
57
58
|
self._default_output_id = socket.identifier
|
|
58
|
-
self._tree = TreeBuilder(socket.node.id_data)
|
|
59
|
+
self._tree = TreeBuilder(cast(NodeTree, socket.node.id_data))
|
|
59
60
|
|
|
60
61
|
@property
|
|
61
62
|
def tree(self) -> TreeBuilder:
|
|
@@ -100,7 +101,7 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
100
101
|
|
|
101
102
|
def _dispatch_math(
|
|
102
103
|
self, other: Any, operation: str, reverse: bool = False
|
|
103
|
-
) -> "
|
|
104
|
+
) -> "Math":
|
|
104
105
|
"""Scalar math dispatch (float). Uses the Math node."""
|
|
105
106
|
from ..nodes.geometry.converter import Math
|
|
106
107
|
|
|
@@ -108,7 +109,7 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
108
109
|
math_operation = "floored_modulo" if operation == "modulo" else operation
|
|
109
110
|
return getattr(Math, math_operation)(*values)
|
|
110
111
|
|
|
111
|
-
def _dispatch_unary(self, operation: str) -> "
|
|
112
|
+
def _dispatch_unary(self, operation: str) -> "Math":
|
|
112
113
|
"""Scalar unary dispatch (float). Uses the Math node."""
|
|
113
114
|
from ..nodes.geometry.converter import Math
|
|
114
115
|
|
|
@@ -118,7 +119,7 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
118
119
|
return Math.absolute(self.socket)
|
|
119
120
|
raise ValueError(f"Unknown unary operation: {operation}")
|
|
120
121
|
|
|
121
|
-
def _dispatch_floordiv(self, other: Any, reverse: bool = False) -> "
|
|
122
|
+
def _dispatch_floordiv(self, other: Any, reverse: bool = False) -> "Math":
|
|
122
123
|
"""Scalar floor division: divide then floor."""
|
|
123
124
|
from ..nodes.geometry.converter import Math
|
|
124
125
|
|
|
@@ -126,7 +127,7 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
126
127
|
divided = Math.divide(*values)
|
|
127
128
|
return Math.floor(divided)
|
|
128
129
|
|
|
129
|
-
def _dispatch_compare(self, other: Any, operation: str) -> "
|
|
130
|
+
def _dispatch_compare(self, other: Any, operation: str) -> "Compare | Math":
|
|
130
131
|
"""Scalar comparison dispatch."""
|
|
131
132
|
if isinstance(self._tree.tree, GeometryNodeTree):
|
|
132
133
|
from ..nodes.geometry.manual import Compare
|
|
@@ -140,9 +141,12 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
140
141
|
"greater_than": ("greater_than", False),
|
|
141
142
|
"less_equal": ("greater_than", True),
|
|
142
143
|
"greater_equal": ("less_than", True),
|
|
144
|
+
"equal": ("compare", False),
|
|
143
145
|
}
|
|
144
146
|
math_op, negate = _MATH_COMPARE_MAP[operation]
|
|
145
147
|
result = getattr(Math, math_op)(self.socket, other)
|
|
148
|
+
if operation == "equal":
|
|
149
|
+
result.i.value_002.default_value = 0.00001
|
|
146
150
|
if negate:
|
|
147
151
|
result = Math.subtract(1.0, result._default_output_socket)
|
|
148
152
|
return result
|
|
@@ -167,8 +171,8 @@ class Socket(_SocketLike, OperatorMixin, LinkingMixin):
|
|
|
167
171
|
def __gt__(self, other: Any) -> "Compare": ...
|
|
168
172
|
def __le__(self, other: Any) -> "Compare": ...
|
|
169
173
|
def __ge__(self, other: Any) -> "Compare": ...
|
|
170
|
-
def __eq__(self, other: Any) -> "Compare": ...
|
|
171
|
-
def __ne__(self, other: Any) -> "Compare": ...
|
|
174
|
+
def __eq__(self, other: Any) -> "Compare": ...
|
|
175
|
+
def __ne__(self, other: Any) -> "Compare": ...
|
|
172
176
|
|
|
173
177
|
|
|
174
178
|
# ---------------------------------------------------------------------------
|
|
@@ -308,7 +312,7 @@ class _VectorMixin:
|
|
|
308
312
|
|
|
309
313
|
return getattr(Compare.vector, operation)(self.socket, other)
|
|
310
314
|
else:
|
|
311
|
-
return Socket._dispatch_compare(self, other, operation)
|
|
315
|
+
return Socket._dispatch_compare(cast("Socket", self), other, operation)
|
|
312
316
|
|
|
313
317
|
if TYPE_CHECKING:
|
|
314
318
|
|
|
@@ -324,12 +328,10 @@ class _VectorMixin:
|
|
|
324
328
|
def __rfloordiv__(self, other: Any) -> "VectorMath": ...
|
|
325
329
|
def __neg__(self) -> "VectorMath": ...
|
|
326
330
|
def __abs__(self) -> "VectorMath": ...
|
|
327
|
-
def __lt__(self, other: Any) -> "Compare": ...
|
|
328
|
-
def __gt__(self, other: Any) -> "Compare": ...
|
|
329
|
-
def __le__(self, other: Any) -> "Compare": ...
|
|
330
|
-
def __ge__(self, other: Any) -> "Compare": ...
|
|
331
|
-
def __eq__(self, other: Any) -> "Compare": ... # type: ignore[override]
|
|
332
|
-
def __ne__(self, other: Any) -> "Compare": ... # type: ignore[override]
|
|
331
|
+
def __lt__(self, other: Any) -> "Compare[NodeSocketVector]": ...
|
|
332
|
+
def __gt__(self, other: Any) -> "Compare[NodeSocketVector]": ...
|
|
333
|
+
def __le__(self, other: Any) -> "Compare[NodeSocketVector]": ...
|
|
334
|
+
def __ge__(self, other: Any) -> "Compare[NodeSocketVector]": ...
|
|
333
335
|
|
|
334
336
|
|
|
335
337
|
_SEPARATE_COLOR_IDNAMES = (
|
|
@@ -356,7 +358,9 @@ class _ColorMixin:
|
|
|
356
358
|
return SeparateColor
|
|
357
359
|
|
|
358
360
|
def _separated_channel(self, channel: str) -> Socket:
|
|
361
|
+
assert self.socket.links is not None
|
|
359
362
|
for link in self.socket.links:
|
|
363
|
+
assert link.to_node is not None
|
|
360
364
|
if link.to_node.bl_idname in _SEPARATE_COLOR_IDNAMES:
|
|
361
365
|
return Socket(link.to_node.outputs[channel])
|
|
362
366
|
|
|
@@ -438,6 +442,40 @@ class _ColorMixin:
|
|
|
438
442
|
def __len__(self) -> int:
|
|
439
443
|
return 4
|
|
440
444
|
|
|
445
|
+
def _dispatch_math(
|
|
446
|
+
self, other: Any, operation: str, reverse: bool = False
|
|
447
|
+
) -> "BaseNode":
|
|
448
|
+
from ..nodes.geometry import VectorMath
|
|
449
|
+
|
|
450
|
+
values = (self.socket, other) if not reverse else (other, self.socket)
|
|
451
|
+
|
|
452
|
+
if operation == "multiply":
|
|
453
|
+
if isinstance(other, (int, float)):
|
|
454
|
+
return VectorMath.scale(self.socket, other)
|
|
455
|
+
elif isinstance(other, NodeSocket) and other.type in (
|
|
456
|
+
"VALUE",
|
|
457
|
+
"FLOAT",
|
|
458
|
+
"INT",
|
|
459
|
+
):
|
|
460
|
+
return VectorMath.scale(self.socket, other)
|
|
461
|
+
elif isinstance(other, (_SocketLike, _NodeLike)) and getattr(
|
|
462
|
+
other, "type", None
|
|
463
|
+
) in ("VALUE", "FLOAT", "INT"):
|
|
464
|
+
return VectorMath.scale(self.socket, other._default_output_socket)
|
|
465
|
+
else:
|
|
466
|
+
return VectorMath.multiply(*values)
|
|
467
|
+
else:
|
|
468
|
+
vector_method = getattr(VectorMath, operation, None)
|
|
469
|
+
assert vector_method is not None
|
|
470
|
+
if isinstance(other, (int, float)):
|
|
471
|
+
scalar_vector = (other, other, other)
|
|
472
|
+
return (
|
|
473
|
+
vector_method(self.socket, scalar_vector)
|
|
474
|
+
if not reverse
|
|
475
|
+
else vector_method(scalar_vector, self.socket)
|
|
476
|
+
)
|
|
477
|
+
return vector_method(*values)
|
|
478
|
+
|
|
441
479
|
|
|
442
480
|
class _IntegerMixin:
|
|
443
481
|
"""Integer-specific dispatch — uses IntegerMath in geometry trees."""
|
|
@@ -475,7 +513,7 @@ class _IntegerMixin:
|
|
|
475
513
|
|
|
476
514
|
values = (self.socket, other) if not reverse else (other, self.socket)
|
|
477
515
|
return getattr(IntegerMath, operation)(*values)
|
|
478
|
-
return Socket._dispatch_math(self, other, operation, reverse)
|
|
516
|
+
return Socket._dispatch_math(cast("Socket", self), other, operation, reverse)
|
|
479
517
|
|
|
480
518
|
def _dispatch_unary(self, operation: str) -> "BaseNode":
|
|
481
519
|
if self._is_geometry_tree:
|
|
@@ -485,7 +523,7 @@ class _IntegerMixin:
|
|
|
485
523
|
return IntegerMath.negate(self.socket)
|
|
486
524
|
elif operation == "absolute":
|
|
487
525
|
return IntegerMath.absolute(self.socket)
|
|
488
|
-
return Socket._dispatch_unary(self, operation)
|
|
526
|
+
return Socket._dispatch_unary(cast("Socket", self), operation)
|
|
489
527
|
|
|
490
528
|
def _dispatch_floordiv(self, other: Any, reverse: bool = False) -> "BaseNode":
|
|
491
529
|
if self._is_geometry_tree and self._other_is_integer(other):
|
|
@@ -493,14 +531,14 @@ class _IntegerMixin:
|
|
|
493
531
|
|
|
494
532
|
values = (self.socket, other) if not reverse else (other, self.socket)
|
|
495
533
|
return IntegerMath.divide_floor(*values)
|
|
496
|
-
return Socket._dispatch_floordiv(self, other, reverse)
|
|
534
|
+
return Socket._dispatch_floordiv(cast("Socket", self), other, reverse)
|
|
497
535
|
|
|
498
|
-
def _dispatch_compare(self, other: Any, operation: str) -> "
|
|
536
|
+
def _dispatch_compare(self, other: Any, operation: str) -> "Compare | Math":
|
|
499
537
|
if isinstance(self._tree.tree, GeometryNodeTree):
|
|
500
538
|
from ..nodes.geometry.manual import Compare
|
|
501
539
|
|
|
502
540
|
return getattr(Compare.integer, operation)(self.socket, other)
|
|
503
|
-
return Socket._dispatch_compare(self, other, operation)
|
|
541
|
+
return Socket._dispatch_compare(cast("Socket", self), other, operation)
|
|
504
542
|
|
|
505
543
|
if TYPE_CHECKING:
|
|
506
544
|
|
|
@@ -516,12 +554,10 @@ class _IntegerMixin:
|
|
|
516
554
|
def __rfloordiv__(self, other: Any) -> "IntegerMath": ...
|
|
517
555
|
def __neg__(self) -> "IntegerMath": ...
|
|
518
556
|
def __abs__(self) -> "IntegerMath": ...
|
|
519
|
-
def __lt__(self, other: Any) -> "Compare": ...
|
|
520
|
-
def __gt__(self, other: Any) -> "Compare": ...
|
|
521
|
-
def __le__(self, other: Any) -> "Compare": ...
|
|
522
|
-
def __ge__(self, other: Any) -> "Compare": ...
|
|
523
|
-
def __eq__(self, other: Any) -> "Compare": ... # type: ignore[override]
|
|
524
|
-
def __ne__(self, other: Any) -> "Compare": ... # type: ignore[override]
|
|
557
|
+
def __lt__(self, other: Any) -> "Compare[NodeSocketInt]": ...
|
|
558
|
+
def __gt__(self, other: Any) -> "Compare[NodeSocketInt]": ...
|
|
559
|
+
def __le__(self, other: Any) -> "Compare[NodeSocketInt]": ...
|
|
560
|
+
def __ge__(self, other: Any) -> "Compare[NodeSocketInt]": ...
|
|
525
561
|
|
|
526
562
|
|
|
527
563
|
# ---------------------------------------------------------------------------
|
|
@@ -823,8 +823,14 @@ class TreeBuilder(Generic[_TreeT]):
|
|
|
823
823
|
if not isinstance(socket2, NodeSocket):
|
|
824
824
|
socket2 = socket2.socket # type: ignore[attr-defined]
|
|
825
825
|
|
|
826
|
+
is_reroute = (
|
|
827
|
+
getattr(socket1.node, "bl_idname", None) == "NodeReroute"
|
|
828
|
+
or getattr(socket2.node, "bl_idname", None) == "NodeReroute"
|
|
829
|
+
)
|
|
826
830
|
if (
|
|
827
|
-
|
|
831
|
+
not is_reroute
|
|
832
|
+
and socket1.type not in SOCKET_COMPATIBILITY.get(socket2.type, ())
|
|
833
|
+
and socket1.type != "CUSTOM"
|
|
828
834
|
and socket2.type != "CUSTOM"
|
|
829
835
|
):
|
|
830
836
|
raise SocketError(
|
|
@@ -4,6 +4,9 @@ from .manual import (
|
|
|
4
4
|
MenuSwitch,
|
|
5
5
|
Frame,
|
|
6
6
|
tree,
|
|
7
|
+
Float,
|
|
8
|
+
Image,
|
|
9
|
+
Cryptomatte,
|
|
7
10
|
)
|
|
8
11
|
from ..geometry.color import (
|
|
9
12
|
Gamma,
|
|
@@ -41,6 +44,9 @@ from ..geometry.texture import (
|
|
|
41
44
|
WaveTexture,
|
|
42
45
|
WhiteNoiseTexture,
|
|
43
46
|
)
|
|
47
|
+
from ..geometry.utilities import (
|
|
48
|
+
Reroute,
|
|
49
|
+
)
|
|
44
50
|
from ..geometry.vector import (
|
|
45
51
|
RadialTiling,
|
|
46
52
|
VectorCurves,
|
|
@@ -80,6 +86,20 @@ from .filter import (
|
|
|
80
86
|
Pixelate,
|
|
81
87
|
VectorBlur,
|
|
82
88
|
)
|
|
89
|
+
from .input import (
|
|
90
|
+
BokehImage,
|
|
91
|
+
Color,
|
|
92
|
+
ImageCoordinates,
|
|
93
|
+
ImageInfo,
|
|
94
|
+
Mask,
|
|
95
|
+
MovieClip,
|
|
96
|
+
Normal,
|
|
97
|
+
RenderLayers,
|
|
98
|
+
SceneTime,
|
|
99
|
+
SequencerStripInfo,
|
|
100
|
+
TimeCurve,
|
|
101
|
+
TrackPosition,
|
|
102
|
+
)
|
|
83
103
|
from .matte import (
|
|
84
104
|
BoxMask,
|
|
85
105
|
ChannelKey,
|
|
@@ -103,7 +123,7 @@ from .converter import (
|
|
|
103
123
|
IndexSwitch,
|
|
104
124
|
Levels,
|
|
105
125
|
Mix,
|
|
106
|
-
|
|
126
|
+
RGBToBW,
|
|
107
127
|
RelativeToPixel,
|
|
108
128
|
SeparateColor,
|
|
109
129
|
SetAlpha,
|
|
@@ -129,17 +149,6 @@ from .distort import (
|
|
|
129
149
|
from .group import (
|
|
130
150
|
Group,
|
|
131
151
|
)
|
|
132
|
-
from .input import (
|
|
133
|
-
Color,
|
|
134
|
-
Mask,
|
|
135
|
-
MovieClip,
|
|
136
|
-
Normal,
|
|
137
|
-
RenderLayers,
|
|
138
|
-
SceneTime,
|
|
139
|
-
SequencerStripInfo,
|
|
140
|
-
TimeCurve,
|
|
141
|
-
TrackPosition,
|
|
142
|
-
)
|
|
143
152
|
from .vector import (
|
|
144
153
|
Normalize,
|
|
145
154
|
)
|
|
@@ -159,6 +168,7 @@ __all__ = (
|
|
|
159
168
|
"Blackbody",
|
|
160
169
|
"Blur",
|
|
161
170
|
"BokehBlur",
|
|
171
|
+
"BokehImage",
|
|
162
172
|
"Boolean",
|
|
163
173
|
"BoxMask",
|
|
164
174
|
"BrickTexture",
|
|
@@ -180,6 +190,7 @@ __all__ = (
|
|
|
180
190
|
"Convolve",
|
|
181
191
|
"CornerPin",
|
|
182
192
|
"Crop",
|
|
193
|
+
"Cryptomatte",
|
|
183
194
|
"Defocus",
|
|
184
195
|
"Denoise",
|
|
185
196
|
"DepthCombine",
|
|
@@ -196,6 +207,7 @@ __all__ = (
|
|
|
196
207
|
"FileOutput",
|
|
197
208
|
"Filter",
|
|
198
209
|
"Flip",
|
|
210
|
+
"Float",
|
|
199
211
|
"FloatCurve",
|
|
200
212
|
"Frame",
|
|
201
213
|
"GaborTexture",
|
|
@@ -208,6 +220,9 @@ __all__ = (
|
|
|
208
220
|
"HueCorrect",
|
|
209
221
|
"Huesaturationvalue",
|
|
210
222
|
"IDMask",
|
|
223
|
+
"Image",
|
|
224
|
+
"ImageCoordinates",
|
|
225
|
+
"ImageInfo",
|
|
211
226
|
"IndexSwitch",
|
|
212
227
|
"Inpaint",
|
|
213
228
|
"Integer",
|
|
@@ -235,10 +250,11 @@ __all__ = (
|
|
|
235
250
|
"PlaneTrackDeform",
|
|
236
251
|
"Posterize",
|
|
237
252
|
"RGBCurves",
|
|
238
|
-
"
|
|
253
|
+
"RGBToBW",
|
|
239
254
|
"RadialTiling",
|
|
240
255
|
"RelativeToPixel",
|
|
241
256
|
"RenderLayers",
|
|
257
|
+
"Reroute",
|
|
242
258
|
"Rotate",
|
|
243
259
|
"Scale",
|
|
244
260
|
"SceneTime",
|