nodebpy 520.5.1__tar.gz → 520.5.2__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.
Files changed (83) hide show
  1. nodebpy-520.5.2/PKG-INFO +79 -0
  2. nodebpy-520.5.2/README.md +63 -0
  3. {nodebpy-520.5.1 → nodebpy-520.5.2}/pyproject.toml +1 -1
  4. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/tree.py +2 -1
  5. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/export/__init__.py +2 -0
  6. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/export/codegen.py +1 -1
  7. {nodebpy-520.5.1/src/nodebpy → nodebpy-520.5.2/src/nodebpy/export}/web_render.py +1 -1
  8. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/_mixins.py +2 -2
  9. nodebpy-520.5.1/PKG-INFO +0 -159
  10. nodebpy-520.5.1/README.md +0 -143
  11. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/__init__.py +0 -0
  12. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/assets/__init__.py +0 -0
  13. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/assets/__main__.py +0 -0
  14. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/assets/_codegen.py +0 -0
  15. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/__init__.py +0 -0
  16. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/_registry.py +0 -0
  17. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/_utils.py +0 -0
  18. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/accessor.py +0 -0
  19. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/arrange.py +0 -0
  20. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/asset.py +0 -0
  21. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/items.py +0 -0
  22. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/mixins.py +0 -0
  23. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/node.py +0 -0
  24. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/builder/socket.py +0 -0
  25. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/export/diagram.py +0 -0
  26. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/__init__.py +0 -0
  27. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/__init__.py +0 -0
  28. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/graph.py +0 -0
  29. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/ordering.py +0 -0
  30. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/ranking.py +0 -0
  31. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/realize.py +0 -0
  32. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/stacking.py +0 -0
  33. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/structs.py +0 -0
  34. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/sugiyama.py +0 -0
  35. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/x_coords.py +0 -0
  36. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/arrange/y_coords.py +0 -0
  37. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/config.py +0 -0
  38. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/lib/nodearrange/utils.py +0 -0
  39. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/__init__.py +0 -0
  40. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/__init__.py +0 -0
  41. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/assets.py +0 -0
  42. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/color.py +0 -0
  43. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/converter.py +0 -0
  44. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/distort.py +0 -0
  45. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/filter.py +0 -0
  46. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/group.py +0 -0
  47. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/input.py +0 -0
  48. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/interface.py +0 -0
  49. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/manual.py +0 -0
  50. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/matte.py +0 -0
  51. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/output.py +0 -0
  52. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/compositor/vector.py +0 -0
  53. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/__init__.py +0 -0
  54. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/assets.py +0 -0
  55. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/attribute.py +0 -0
  56. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/color.py +0 -0
  57. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/converter.py +0 -0
  58. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/geometry.py +0 -0
  59. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/grid.py +0 -0
  60. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/group.py +0 -0
  61. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/groups.py +0 -0
  62. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/input.py +0 -0
  63. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/interface.py +0 -0
  64. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/manual.py +0 -0
  65. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/output.py +0 -0
  66. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/texture.py +0 -0
  67. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/utilities.py +0 -0
  68. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/vector.py +0 -0
  69. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/geometry/zone.py +0 -0
  70. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/__init__.py +0 -0
  71. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/assets.py +0 -0
  72. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/color.py +0 -0
  73. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/converter.py +0 -0
  74. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/grid.py +0 -0
  75. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/group.py +0 -0
  76. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/input.py +0 -0
  77. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/manual.py +0 -0
  78. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/output.py +0 -0
  79. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/script.py +0 -0
  80. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/shader.py +0 -0
  81. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/texture.py +0 -0
  82. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/nodes/shader/vector.py +0 -0
  83. {nodebpy-520.5.1 → nodebpy-520.5.2}/src/nodebpy/types.py +0 -0
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.3
2
+ Name: nodebpy
3
+ Version: 520.5.2
4
+ Summary: Build nodes trees in Blender more elegantly with code
5
+ Author: Brady Johnston
6
+ Author-email: Brady Johnston <brady.johnston@me.com>
7
+ License: GPL-3.0-or-later
8
+ Requires-Dist: bpy==5.2.* ; extra == 'bpy'
9
+ Requires-Dist: ruff>=0.14.11 ; extra == 'format'
10
+ Requires-Dist: networkx>=3.6.1 ; extra == 'networkx'
11
+ Requires-Python: >=3.13
12
+ Provides-Extra: bpy
13
+ Provides-Extra: format
14
+ Provides-Extra: networkx
15
+ Description-Content-Type: text/markdown
16
+
17
+ # nodebpy
18
+
19
+ [![Run
20
+ Tests](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml/badge.svg)](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml)
21
+ [![](https://codecov.io/gh/BradyAJohnston/nodebpy/graph/badge.svg?token=buThDQZUED)](https://codecov.io/gh/BradyAJohnston/nodebpy)
22
+
23
+ Build node trees in Blender more elegantly with Python code. Geometry Nodes, Shader Nodes and Compositor nodes are all fully supported, with type hints and IDE auto-completion throughout.
24
+
25
+ ```bash
26
+ pip install nodebpy
27
+ ```
28
+
29
+ > A text-based version of nodes should bring the convenience of writing code with IDE auto-completion, type hinting, with overall compactness and readability, while staying as close as possible to what building a node tree via the GUI feels like.
30
+
31
+ ```python
32
+ from nodebpy import geometry as g
33
+
34
+ with g.tree("AnotherTree", collapse=True) as tree:
35
+ rotation = (
36
+ g.RandomValue.vector(min=-1, seed=2)
37
+ >> g.AlignRotationToVector()
38
+ >> g.RotateRotation(rotate_by=g.AxisAngleToRotation(angle=0.3))
39
+ )
40
+
41
+ _ = (
42
+ tree.inputs.integer("Count", 10)
43
+ >> g.Points(position=g.RandomValue.vector(min=-1))
44
+ >> g.InstanceOnPoints(instance=g.Cube(), rotation=rotation)
45
+ >> g.SetPosition(
46
+ position=g.Position() * 2.0 + (0, 0.2, 0.3),
47
+ offset=(0, 0, 0.1),
48
+ )
49
+ >> g.RealizeInstances()
50
+ >> g.InstanceOnPoints(g.Cube(), instance=...)
51
+ >> tree.outputs.geometry("Instances")
52
+ )
53
+ ```
54
+
55
+ ![](docs/images/paste-1.png)
56
+
57
+ - Every node is a typed class named after the node it creates — 'Random Value' becomes `g.RandomValue()` — and node subtypes are class methods: `g.RandomValue.vector()`.
58
+ - Trees are built inside a `with g.tree(...):` context; instantiating a node class adds it to the current tree, and the tree's interface is declared with `tree.inputs.*` / `tree.outputs.*`.
59
+ - Nodes are linked with the `>>` operator, which picks the most compatible socket pair automatically (much like Node Wrangler's <kbd>Alt</kbd> + <kbd>Right Click</kbd> drag) — or address sockets explicitly through the `.i.*` / `.o.*` accessors.
60
+ - Python's arithmetic, comparison and boolean operators create the matching `Math` / `VectorMath` / `Compare` / `BooleanMath` nodes: `g.Value(1.0) * 2 + (0, 0, 1)`.
61
+ - Existing node trees — including ones wired up by hand in the GUI — can be exported back to `nodebpy` source with `to_python()`.
62
+
63
+ ## Documentation
64
+
65
+ Guides and the full node reference live at [bradyajohnston.github.io/nodebpy](https://bradyajohnston.github.io/nodebpy):
66
+
67
+ - [Writing node trees](https://bradyajohnston.github.io/nodebpy/introduction.html) — adding, linking and organising nodes
68
+ - [Math operators](https://bradyajohnston.github.io/nodebpy/operators.html) — arithmetic, comparison and boolean expressions as nodes
69
+ - [Node API design](https://bradyajohnston.github.io/nodebpy/node-api.html) — sockets, accessors, enum options and class methods
70
+ - [Custom node groups](https://bradyajohnston.github.io/nodebpy/custom-node-groups.html) and [asset node groups](https://bradyajohnston.github.io/nodebpy/assets.html) — reusable groups as Python classes
71
+ - [Nodes to code](https://bradyajohnston.github.io/nodebpy/nodes-to-code.html) — turn existing trees back into `nodebpy` code
72
+ - [Using `nodebpy` in your add-on](https://bradyajohnston.github.io/nodebpy/using.html) — installation, bundling and the Blender-tracking versioning scheme
73
+ - [Comparisons](https://bradyajohnston.github.io/nodebpy/comparisons.html) — how the API relates to [`geometry-script`](https://github.com/carson-katri/geometry-script), [`geonodes`](https://github.com/al1brn/geonodes), [NodeToPython](https://github.com/BrendanParmer/NodeToPython) and [TreeClipper](https://github.com/Algebraic-UG/tree_clipper)
74
+
75
+ Like [`databpy`](https://github.com/BradyAJohnston/databpy), this project started as an internal tool inside [`molecularnodes`](https://github.com/BradyAJohnston/MolecularNodes) before being broken out into its own robustly typed and tested package.
76
+
77
+ ## Contributing
78
+
79
+ Development setup, running the tests and regenerating the node classes (most of `src/nodebpy/nodes/` is auto-generated by the `gen/` package) are covered in [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -0,0 +1,63 @@
1
+ # nodebpy
2
+
3
+ [![Run
4
+ Tests](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml/badge.svg)](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml)
5
+ [![](https://codecov.io/gh/BradyAJohnston/nodebpy/graph/badge.svg?token=buThDQZUED)](https://codecov.io/gh/BradyAJohnston/nodebpy)
6
+
7
+ Build node trees in Blender more elegantly with Python code. Geometry Nodes, Shader Nodes and Compositor nodes are all fully supported, with type hints and IDE auto-completion throughout.
8
+
9
+ ```bash
10
+ pip install nodebpy
11
+ ```
12
+
13
+ > A text-based version of nodes should bring the convenience of writing code with IDE auto-completion, type hinting, with overall compactness and readability, while staying as close as possible to what building a node tree via the GUI feels like.
14
+
15
+ ```python
16
+ from nodebpy import geometry as g
17
+
18
+ with g.tree("AnotherTree", collapse=True) as tree:
19
+ rotation = (
20
+ g.RandomValue.vector(min=-1, seed=2)
21
+ >> g.AlignRotationToVector()
22
+ >> g.RotateRotation(rotate_by=g.AxisAngleToRotation(angle=0.3))
23
+ )
24
+
25
+ _ = (
26
+ tree.inputs.integer("Count", 10)
27
+ >> g.Points(position=g.RandomValue.vector(min=-1))
28
+ >> g.InstanceOnPoints(instance=g.Cube(), rotation=rotation)
29
+ >> g.SetPosition(
30
+ position=g.Position() * 2.0 + (0, 0.2, 0.3),
31
+ offset=(0, 0, 0.1),
32
+ )
33
+ >> g.RealizeInstances()
34
+ >> g.InstanceOnPoints(g.Cube(), instance=...)
35
+ >> tree.outputs.geometry("Instances")
36
+ )
37
+ ```
38
+
39
+ ![](docs/images/paste-1.png)
40
+
41
+ - Every node is a typed class named after the node it creates — 'Random Value' becomes `g.RandomValue()` — and node subtypes are class methods: `g.RandomValue.vector()`.
42
+ - Trees are built inside a `with g.tree(...):` context; instantiating a node class adds it to the current tree, and the tree's interface is declared with `tree.inputs.*` / `tree.outputs.*`.
43
+ - Nodes are linked with the `>>` operator, which picks the most compatible socket pair automatically (much like Node Wrangler's <kbd>Alt</kbd> + <kbd>Right Click</kbd> drag) — or address sockets explicitly through the `.i.*` / `.o.*` accessors.
44
+ - Python's arithmetic, comparison and boolean operators create the matching `Math` / `VectorMath` / `Compare` / `BooleanMath` nodes: `g.Value(1.0) * 2 + (0, 0, 1)`.
45
+ - Existing node trees — including ones wired up by hand in the GUI — can be exported back to `nodebpy` source with `to_python()`.
46
+
47
+ ## Documentation
48
+
49
+ Guides and the full node reference live at [bradyajohnston.github.io/nodebpy](https://bradyajohnston.github.io/nodebpy):
50
+
51
+ - [Writing node trees](https://bradyajohnston.github.io/nodebpy/introduction.html) — adding, linking and organising nodes
52
+ - [Math operators](https://bradyajohnston.github.io/nodebpy/operators.html) — arithmetic, comparison and boolean expressions as nodes
53
+ - [Node API design](https://bradyajohnston.github.io/nodebpy/node-api.html) — sockets, accessors, enum options and class methods
54
+ - [Custom node groups](https://bradyajohnston.github.io/nodebpy/custom-node-groups.html) and [asset node groups](https://bradyajohnston.github.io/nodebpy/assets.html) — reusable groups as Python classes
55
+ - [Nodes to code](https://bradyajohnston.github.io/nodebpy/nodes-to-code.html) — turn existing trees back into `nodebpy` code
56
+ - [Using `nodebpy` in your add-on](https://bradyajohnston.github.io/nodebpy/using.html) — installation, bundling and the Blender-tracking versioning scheme
57
+ - [Comparisons](https://bradyajohnston.github.io/nodebpy/comparisons.html) — how the API relates to [`geometry-script`](https://github.com/carson-katri/geometry-script), [`geonodes`](https://github.com/al1brn/geonodes), [NodeToPython](https://github.com/BrendanParmer/NodeToPython) and [TreeClipper](https://github.com/Algebraic-UG/tree_clipper)
58
+
59
+ Like [`databpy`](https://github.com/BradyAJohnston/databpy), this project started as an internal tool inside [`molecularnodes`](https://github.com/BradyAJohnston/MolecularNodes) before being broken out into its own robustly typed and tested package.
60
+
61
+ ## Contributing
62
+
63
+ Development setup, running the tests and regenerating the node classes (most of `src/nodebpy/nodes/` is auto-generated by the `gen/` package) are covered in [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nodebpy"
3
- version = "520.5.1"
3
+ version = "520.5.2"
4
4
  description = "Build nodes trees in Blender more elegantly with code"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -15,6 +15,7 @@ from bpy.types import (
15
15
  ShaderNodeTree,
16
16
  )
17
17
 
18
+
18
19
  from ..types import (
19
20
  SOCKET_COMPATIBILITY,
20
21
  FloatInterfaceSubtypes,
@@ -856,7 +857,7 @@ class TreeBuilder(Generic[_TreeT]):
856
857
  Mermaid ``_repr_markdown_`` fallback take over.
857
858
  """
858
859
  try:
859
- from ..web_render import to_web_render_html
860
+ from ..export import to_web_render_html
860
861
 
861
862
  return to_web_render_html(self)
862
863
  except Exception as e:
@@ -1,7 +1,9 @@
1
1
  from .codegen import to_python
2
2
  from .diagram import to_mermaid
3
+ from .web_render import to_web_render_html
3
4
 
4
5
  __all__ = [
5
6
  "to_python",
6
7
  "to_mermaid",
8
+ "to_web_render_html",
7
9
  ]
@@ -1389,7 +1389,7 @@ def _non_default_props(node, cls: type) -> dict[str, Any]:
1389
1389
  # (``Compare.float.less_than``). Parsing those bodies at runtime yields a
1390
1390
  # reverse table from node state to factory path, so generated code uses the
1391
1391
  # same idiomatic spellings users write — with no separate table to keep in
1392
- # sync with generate.py. Factories whose bodies are not statically analysable
1392
+ # sync with the generator. Factories whose bodies are not statically analysable
1393
1393
  # (positional args, helper indirection, **kwargs) are simply skipped and the
1394
1394
  # node falls back to the plain constructor.
1395
1395
  # ---------------------------------------------------------------------------
@@ -19,7 +19,7 @@ import uuid
19
19
  from typing import TYPE_CHECKING
20
20
 
21
21
  if TYPE_CHECKING:
22
- from .builder.tree import TreeBuilder
22
+ from ..builder.tree import TreeBuilder
23
23
 
24
24
  #: geonodes-web-render version served from the CDN. A semver range (`"0.3"`)
25
25
  #: lets esm.sh serve the latest matching patch, so web-render bug fixes ship to
@@ -1,8 +1,8 @@
1
1
  """Hand-written mixins attached to auto-generated node classes.
2
2
 
3
3
  These hold reusable behaviour that the code generator cannot derive on its own
4
- (ergonomic flag accessors, items helpers, …). ``generate.py`` wires them onto
5
- the generated classes via :class:`~generate.NodeCustomization`, so the bulky
4
+ (ergonomic flag accessors, items helpers, …). The ``gen`` package wires them
5
+ onto the generated classes via :class:`~gen.NodeCustomization`, so the bulky
6
6
  boilerplate (sockets, docstrings, property accessors) stays generated while the
7
7
  bespoke behaviour lives here.
8
8
  """
nodebpy-520.5.1/PKG-INFO DELETED
@@ -1,159 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: nodebpy
3
- Version: 520.5.1
4
- Summary: Build nodes trees in Blender more elegantly with code
5
- Author: Brady Johnston
6
- Author-email: Brady Johnston <brady.johnston@me.com>
7
- License: GPL-3.0-or-later
8
- Requires-Dist: bpy==5.2.* ; extra == 'bpy'
9
- Requires-Dist: ruff>=0.14.11 ; extra == 'format'
10
- Requires-Dist: networkx>=3.6.1 ; extra == 'networkx'
11
- Requires-Python: >=3.13
12
- Provides-Extra: bpy
13
- Provides-Extra: format
14
- Provides-Extra: networkx
15
- Description-Content-Type: text/markdown
16
-
17
- # nodebpy
18
-
19
- [![Run
20
- Tests](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml/badge.svg)](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml)
21
- [![](https://codecov.io/gh/BradyAJohnston/nodebpy/graph/badge.svg?token=buThDQZUED)](https://codecov.io/gh/BradyAJohnston/nodebpy)
22
-
23
- A package to build node trees in blender more elegantly with python code. Geometry Nodes, Shader Nodes and Compositor nodes are all fully supported. Look at the [documentation](https://bradyajohnston.github.io/nodebpy) for more examples.
24
-
25
- ## Creating Nodes With Code
26
-
27
- > A text-based version of nodes should bring the convenience of writing code with IDE auto-completion, type hinting, with overall compactness and readability, while staying as close as possible to what building a node tree via the GUI feels like.
28
-
29
- ```python
30
- from nodebpy import geometry as g
31
-
32
- with g.tree("AnotherTree", collapse=True) as tree:
33
- rotation = (
34
- g.RandomValue.vector(min=-1, seed=2)
35
- >> g.AlignRotationToVector()
36
- >> g.RotateRotation(rotate_by=g.AxisAngleToRotation(angle=0.3))
37
- )
38
-
39
- _ = (
40
- tree.inputs.integer("Count", 10)
41
- >> g.Points(position=g.RandomValue.vector(min=-1))
42
- >> g.InstanceOnPoints(instance=g.Cube(), rotation=rotation)
43
- >> g.SetPosition(
44
- position=g.Position() * 2.0 + (0, 0.2, 0.3),
45
- offset=(0, 0, 0.1),
46
- )
47
- >> g.RealizeInstances()
48
- >> g.InstanceOnPoints(g.Cube(), instance=...)
49
- >> tree.outputs.geometry("Instances")
50
- )
51
- ```
52
-
53
- ![](docs/images/paste-1.png)
54
-
55
- Nodes are created by instantiating their classes. The node tree they are added to is determined by the context the code is executed in (while inside `with g.tree():`). The interface for the node tree is created with `tree.inputs` and `tree.inputs`, adding the sockets and returning the input or output socket for linking with other nodes.
56
-
57
- Nodes are linked by overloading the `>>` operator, to link from the previous node on the left to the input on the right. Suitable socket pairs are automatically selected or explicitly supplied.
58
-
59
- The layout / arrangement of the node tree is not important to Blender's evaluation of it - but an automatic layout algorithm is potentially applied upon exiting the node tree context.
60
-
61
- ### `nodebpy` and the `>>` operator
62
-
63
- In `nodebpy` we use the `>>` operator to link from one node or socket into another.
64
- This should feel and behave much like the <kbd>Alt</kbd> + <kbd>Right Click</kbd> drag between nodes in [Node Wrangler](https://docs.blender.org/manual/en/latest/addons/node/node_wrangler.html). It will use some smart logic to match the most compatible sockets between the nodes, but if you ever want to be explicit you do so. The input and output sockets of a node are accessible as properties via the `i.*` and `o.*` prefixes, or you can use the `...` placeholder to specify the particular input to be user, or pass in the previous node as a named argument.
65
-
66
- ```py
67
- # vector output will be linked into the first vector input (position)
68
- g.Vector() >> g.SetPosition()
69
- # vector output will be linked into the offset input
70
- g.Vector() >> g.SetPosition(offset=...)
71
- g.SetPosition(offset=g.Vector())
72
- ```
73
-
74
- The `>>` operator will always look for the _most_ compatible sockets first (matching data types) before looking for other compatible but not identical socket data types to link.
75
- If a compatible match can't be found an error _will_ be thrown.
76
-
77
- ### Contexts
78
-
79
- What node tree or node tree interface we are currently editing is determined based on contexts.
80
- Instantiating a node class outside of a tree context will throw an error. The easiest way to enter and exit a tree context is to use the `with` statement.
81
-
82
- Each time you instantiate a node class, a new node will be created and added to the current tree.
83
- If these nodes are given as arguments to other nodes or used with the `>>` operator, they will be automatically linked to the appropriate sockets.
84
-
85
- ## Nodes
86
-
87
- Documentation for all of the nodes can be found in the [API Reference](https://bradyajohnston.github.io/nodebpy/reference/). This is mostly built automatically from the existing Blender node classes.
88
-
89
- Every node has all of it's input sockets and enum options exposed as arguments to the class constructor. Input sockets are prefixed with `.i.*` and output sockets are prefixed with `.o.*`. Properties that aren't exposed as sockets are available as class properties. Many properties are also available as class methods for convenience when constructing.
90
-
91
- The basic math operators also automatically add relevant nodes with their operations and values set.
92
-
93
- ```py
94
- # operation is exposed as a property
95
- math = g.Math(1.0, 2.0, operation='ADD')
96
- math.operation = "SUBTRACT"
97
-
98
- # operation can be chose as a class method
99
- math = g.Math.subtract(1.0, 2.0)
100
- math = g.Value(1.0) - 2.0
101
- math = g.Math.add(1.0, 2.0)
102
- math = g.Value(1.0) + 2.0
103
- # the 3.0 + 2.0 is evaluated as regular python code first,
104
- # so the result with be a Math.add(g.Value(1.0), 5.0)
105
- math = g.Value(1.0) 3.0 + 2.0
106
-
107
- # these are equivalent, the g.Math.multiply is automatically added
108
- g.Value(1.0) * 2
109
- g.Math.multiply(g.Value(1.0), 2.0)
110
- ```
111
-
112
- # Design Considerations
113
-
114
- The top priority of `nodebpy` has been type hinting and IDE auto-complete.
115
- Typical tooling that supports autoring regular python code should also support the authoring of node trees.
116
- Much like [`databpy`](https://github.com/BradyAJohnston/databpy), this started as an internal tool used inside of [`molecularnodes`](https://github.com/BradyAJohnston/molecularnodes) but has since been broken out into it's own separate project.
117
- This projects is robustly typed and tested, with the intent that it can be used internally for multiple other add-ons and projects.
118
-
119
- - Node classes are named after nodes 'Random Value' -> `RandomValue()`
120
- - Node 'subtypes' and methods should be accessible via dot (`.`) for easier IDE auto-complete and authoring:
121
- - `RandomValue(data_type="FLOAT_VECTOR")` -> `RandomValue.vector()`
122
- - Node properties are available on the top level, with inputs and outputs available behind `.i.*` and `.o.*` accessors
123
- - Inputs and outputs from a node are prefixed with `i.*` and `o.*`:
124
- - `AccumulateField().o.total` returns the output `Total` socket
125
- - `AccumulateField().i.value` returns the input `Value` socket
126
-
127
- ## Building
128
-
129
- Most of the code for classes are generated automatically with the `generate.py` script.
130
- Some nodes are manually specified in the `src/nodebpy/nodes/geometry/manual.py` if they require special handling.
131
-
132
- Run the build & format script as such:
133
-
134
- ```bash
135
- uv run generate.py && uvx ruff format && uvx ruff check --fix && uvx ty check --fix src
136
- ```
137
-
138
- ## Other Projects
139
-
140
- There are several other notable projects which have also attempted interfacing with node trees via code. They mostly fit into two categories of either storing & retrieving node trees via code (`.json` or the `bpy` API), or authoring of node trees with custom API and syntax. This project mostly fits in to the latter category.
141
-
142
-
143
-
144
- ### Storing node trees as code:
145
- Converting node trees to the python API calls or `.json` is great to have a robust storage method, but this approach falls down in human authorability / readability. These projects are great for storage but less useful when wanting to write / generate node trees froms scratch.
146
-
147
- - [NodeToPython](https://github.com/BrendanParmer/NodeToPython)
148
- - [TreeClipper](https://github.com/Algebraic-UG/tree_clipper) (used by this project for running tests & snapshots)
149
-
150
- ### Authoring node trees with code:
151
- Two previous projects have made similar approaches to authoring node trees. `geometry-script` also auto-generated most of it's type hinting, code and docs. It uses the approach of method chaining with the `.` operator, but obfuscates some of the non-linear way of building node trees.
152
-
153
- The other project `geonodes` uses a similar context system for creating and authoring node trees, but doesn't use the same method of exposing each individual node as it's own class that `nodebpy` does.
154
-
155
- I personally found both of their APIs to _not quite_ fit how I wanted to work, leading to the creation of `nodebpy`.
156
- In comparison, this project is also the only one that is also distributed on `PyPi` and insallable via `pip` for easier use in other projects.
157
-
158
- - [geometry-script](https://github.com/carson-katri/geometry-script),
159
- - [geonodes](https://github.com/al1brn/geonodes)
nodebpy-520.5.1/README.md DELETED
@@ -1,143 +0,0 @@
1
- # nodebpy
2
-
3
- [![Run
4
- Tests](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml/badge.svg)](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml)
5
- [![](https://codecov.io/gh/BradyAJohnston/nodebpy/graph/badge.svg?token=buThDQZUED)](https://codecov.io/gh/BradyAJohnston/nodebpy)
6
-
7
- A package to build node trees in blender more elegantly with python code. Geometry Nodes, Shader Nodes and Compositor nodes are all fully supported. Look at the [documentation](https://bradyajohnston.github.io/nodebpy) for more examples.
8
-
9
- ## Creating Nodes With Code
10
-
11
- > A text-based version of nodes should bring the convenience of writing code with IDE auto-completion, type hinting, with overall compactness and readability, while staying as close as possible to what building a node tree via the GUI feels like.
12
-
13
- ```python
14
- from nodebpy import geometry as g
15
-
16
- with g.tree("AnotherTree", collapse=True) as tree:
17
- rotation = (
18
- g.RandomValue.vector(min=-1, seed=2)
19
- >> g.AlignRotationToVector()
20
- >> g.RotateRotation(rotate_by=g.AxisAngleToRotation(angle=0.3))
21
- )
22
-
23
- _ = (
24
- tree.inputs.integer("Count", 10)
25
- >> g.Points(position=g.RandomValue.vector(min=-1))
26
- >> g.InstanceOnPoints(instance=g.Cube(), rotation=rotation)
27
- >> g.SetPosition(
28
- position=g.Position() * 2.0 + (0, 0.2, 0.3),
29
- offset=(0, 0, 0.1),
30
- )
31
- >> g.RealizeInstances()
32
- >> g.InstanceOnPoints(g.Cube(), instance=...)
33
- >> tree.outputs.geometry("Instances")
34
- )
35
- ```
36
-
37
- ![](docs/images/paste-1.png)
38
-
39
- Nodes are created by instantiating their classes. The node tree they are added to is determined by the context the code is executed in (while inside `with g.tree():`). The interface for the node tree is created with `tree.inputs` and `tree.inputs`, adding the sockets and returning the input or output socket for linking with other nodes.
40
-
41
- Nodes are linked by overloading the `>>` operator, to link from the previous node on the left to the input on the right. Suitable socket pairs are automatically selected or explicitly supplied.
42
-
43
- The layout / arrangement of the node tree is not important to Blender's evaluation of it - but an automatic layout algorithm is potentially applied upon exiting the node tree context.
44
-
45
- ### `nodebpy` and the `>>` operator
46
-
47
- In `nodebpy` we use the `>>` operator to link from one node or socket into another.
48
- This should feel and behave much like the <kbd>Alt</kbd> + <kbd>Right Click</kbd> drag between nodes in [Node Wrangler](https://docs.blender.org/manual/en/latest/addons/node/node_wrangler.html). It will use some smart logic to match the most compatible sockets between the nodes, but if you ever want to be explicit you do so. The input and output sockets of a node are accessible as properties via the `i.*` and `o.*` prefixes, or you can use the `...` placeholder to specify the particular input to be user, or pass in the previous node as a named argument.
49
-
50
- ```py
51
- # vector output will be linked into the first vector input (position)
52
- g.Vector() >> g.SetPosition()
53
- # vector output will be linked into the offset input
54
- g.Vector() >> g.SetPosition(offset=...)
55
- g.SetPosition(offset=g.Vector())
56
- ```
57
-
58
- The `>>` operator will always look for the _most_ compatible sockets first (matching data types) before looking for other compatible but not identical socket data types to link.
59
- If a compatible match can't be found an error _will_ be thrown.
60
-
61
- ### Contexts
62
-
63
- What node tree or node tree interface we are currently editing is determined based on contexts.
64
- Instantiating a node class outside of a tree context will throw an error. The easiest way to enter and exit a tree context is to use the `with` statement.
65
-
66
- Each time you instantiate a node class, a new node will be created and added to the current tree.
67
- If these nodes are given as arguments to other nodes or used with the `>>` operator, they will be automatically linked to the appropriate sockets.
68
-
69
- ## Nodes
70
-
71
- Documentation for all of the nodes can be found in the [API Reference](https://bradyajohnston.github.io/nodebpy/reference/). This is mostly built automatically from the existing Blender node classes.
72
-
73
- Every node has all of it's input sockets and enum options exposed as arguments to the class constructor. Input sockets are prefixed with `.i.*` and output sockets are prefixed with `.o.*`. Properties that aren't exposed as sockets are available as class properties. Many properties are also available as class methods for convenience when constructing.
74
-
75
- The basic math operators also automatically add relevant nodes with their operations and values set.
76
-
77
- ```py
78
- # operation is exposed as a property
79
- math = g.Math(1.0, 2.0, operation='ADD')
80
- math.operation = "SUBTRACT"
81
-
82
- # operation can be chose as a class method
83
- math = g.Math.subtract(1.0, 2.0)
84
- math = g.Value(1.0) - 2.0
85
- math = g.Math.add(1.0, 2.0)
86
- math = g.Value(1.0) + 2.0
87
- # the 3.0 + 2.0 is evaluated as regular python code first,
88
- # so the result with be a Math.add(g.Value(1.0), 5.0)
89
- math = g.Value(1.0) 3.0 + 2.0
90
-
91
- # these are equivalent, the g.Math.multiply is automatically added
92
- g.Value(1.0) * 2
93
- g.Math.multiply(g.Value(1.0), 2.0)
94
- ```
95
-
96
- # Design Considerations
97
-
98
- The top priority of `nodebpy` has been type hinting and IDE auto-complete.
99
- Typical tooling that supports autoring regular python code should also support the authoring of node trees.
100
- Much like [`databpy`](https://github.com/BradyAJohnston/databpy), this started as an internal tool used inside of [`molecularnodes`](https://github.com/BradyAJohnston/molecularnodes) but has since been broken out into it's own separate project.
101
- This projects is robustly typed and tested, with the intent that it can be used internally for multiple other add-ons and projects.
102
-
103
- - Node classes are named after nodes 'Random Value' -> `RandomValue()`
104
- - Node 'subtypes' and methods should be accessible via dot (`.`) for easier IDE auto-complete and authoring:
105
- - `RandomValue(data_type="FLOAT_VECTOR")` -> `RandomValue.vector()`
106
- - Node properties are available on the top level, with inputs and outputs available behind `.i.*` and `.o.*` accessors
107
- - Inputs and outputs from a node are prefixed with `i.*` and `o.*`:
108
- - `AccumulateField().o.total` returns the output `Total` socket
109
- - `AccumulateField().i.value` returns the input `Value` socket
110
-
111
- ## Building
112
-
113
- Most of the code for classes are generated automatically with the `generate.py` script.
114
- Some nodes are manually specified in the `src/nodebpy/nodes/geometry/manual.py` if they require special handling.
115
-
116
- Run the build & format script as such:
117
-
118
- ```bash
119
- uv run generate.py && uvx ruff format && uvx ruff check --fix && uvx ty check --fix src
120
- ```
121
-
122
- ## Other Projects
123
-
124
- There are several other notable projects which have also attempted interfacing with node trees via code. They mostly fit into two categories of either storing & retrieving node trees via code (`.json` or the `bpy` API), or authoring of node trees with custom API and syntax. This project mostly fits in to the latter category.
125
-
126
-
127
-
128
- ### Storing node trees as code:
129
- Converting node trees to the python API calls or `.json` is great to have a robust storage method, but this approach falls down in human authorability / readability. These projects are great for storage but less useful when wanting to write / generate node trees froms scratch.
130
-
131
- - [NodeToPython](https://github.com/BrendanParmer/NodeToPython)
132
- - [TreeClipper](https://github.com/Algebraic-UG/tree_clipper) (used by this project for running tests & snapshots)
133
-
134
- ### Authoring node trees with code:
135
- Two previous projects have made similar approaches to authoring node trees. `geometry-script` also auto-generated most of it's type hinting, code and docs. It uses the approach of method chaining with the `.` operator, but obfuscates some of the non-linear way of building node trees.
136
-
137
- The other project `geonodes` uses a similar context system for creating and authoring node trees, but doesn't use the same method of exposing each individual node as it's own class that `nodebpy` does.
138
-
139
- I personally found both of their APIs to _not quite_ fit how I wanted to work, leading to the creation of `nodebpy`.
140
- In comparison, this project is also the only one that is also distributed on `PyPi` and insallable via `pip` for easier use in other projects.
141
-
142
- - [geometry-script](https://github.com/carson-katri/geometry-script),
143
- - [geonodes](https://github.com/al1brn/geonodes)