nodebpy 520.17.0__tar.gz → 520.19.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-520.17.0 → nodebpy-520.19.0}/PKG-INFO +3 -1
- {nodebpy-520.17.0 → nodebpy-520.19.0}/pyproject.toml +6 -1
- nodebpy-520.19.0/src/nodebpy/__init__.py +26 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/assets/__init__.py +5 -2
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/assets/__main__.py +9 -5
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/assets/_codegen.py +5 -5
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/assets/_library.py +343 -61
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/__init__.py +14 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/_utils.py +36 -0
- nodebpy-520.17.0/src/nodebpy/builder/arrange.py → nodebpy-520.19.0/src/nodebpy/builder/layout.py +267 -33
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/node.py +1 -1
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/tree.py +325 -42
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/export/__init__.py +2 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/export/codegen.py +143 -49
- nodebpy-520.19.0/src/nodebpy/export/plot.py +225 -0
- nodebpy-520.19.0/src/nodebpy/lib/nodearrange/VENDORED.md +79 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/graph.py +38 -18
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/ordering.py +10 -8
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/realize.py +35 -27
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/stacking.py +11 -11
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/structs.py +45 -16
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/sugiyama.py +113 -33
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/x_coords.py +17 -10
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/y_coords.py +30 -25
- nodebpy-520.19.0/src/nodebpy/lib/nodearrange/config.py +57 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/utils.py +22 -20
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/manual.py +2 -1
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/manual.py +2 -1
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/manual.py +3 -2
- nodebpy-520.17.0/src/nodebpy/__init__.py +0 -14
- nodebpy-520.17.0/src/nodebpy/lib/nodearrange/config.py +0 -45
- {nodebpy-520.17.0 → nodebpy-520.19.0}/README.md +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/_registry.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/accessor.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/asset.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/items.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/mixins.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/builder/socket.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/export/diagram.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/export/parity.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/export/web_render.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/__init__.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/__init__.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/lib/nodearrange/arrange/ranking.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/__init__.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/_mixins.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/__init__.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/assets.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/color.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/converter.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/distort.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/filter.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/group.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/input.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/interface.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/matte.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/output.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/compositor/vector.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/__init__.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/assets.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/attribute.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/color.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/converter.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/geometry.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/grid.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/group.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/groups.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/input.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/interface.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/output.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/texture.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/utilities.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/vector.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/geometry/zone.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/__init__.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/assets.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/color.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/converter.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/grid.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/group.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/input.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/output.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/script.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/shader.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/texture.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/nodes/shader/vector.py +0 -0
- {nodebpy-520.17.0 → nodebpy-520.19.0}/src/nodebpy/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: nodebpy
|
|
3
|
-
Version: 520.
|
|
3
|
+
Version: 520.19.0
|
|
4
4
|
Summary: Build nodes trees in Blender more elegantly with code
|
|
5
5
|
Author: Brady Johnston
|
|
6
6
|
Author-email: Brady Johnston <brady.johnston@me.com>
|
|
@@ -8,10 +8,12 @@ License: GPL-3.0-or-later
|
|
|
8
8
|
Requires-Dist: bpy==5.2.* ; extra == 'bpy'
|
|
9
9
|
Requires-Dist: ruff>=0.14.11 ; extra == 'format'
|
|
10
10
|
Requires-Dist: networkx>=3.6.1 ; extra == 'networkx'
|
|
11
|
+
Requires-Dist: matplotlib>=3.8 ; extra == 'plot'
|
|
11
12
|
Requires-Python: >=3.13
|
|
12
13
|
Provides-Extra: bpy
|
|
13
14
|
Provides-Extra: format
|
|
14
15
|
Provides-Extra: networkx
|
|
16
|
+
Provides-Extra: plot
|
|
15
17
|
Description-Content-Type: text/markdown
|
|
16
18
|
|
|
17
19
|
# nodebpy
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nodebpy"
|
|
3
|
-
version = "520.
|
|
3
|
+
version = "520.19.0"
|
|
4
4
|
description = "Build nodes trees in Blender more elegantly with code"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -16,6 +16,9 @@ nodebpy = "nodebpy:main"
|
|
|
16
16
|
networkx = [
|
|
17
17
|
"networkx>=3.6.1",
|
|
18
18
|
]
|
|
19
|
+
plot = [
|
|
20
|
+
"matplotlib>=3.8",
|
|
21
|
+
]
|
|
19
22
|
bpy = [
|
|
20
23
|
"bpy==5.2.*",
|
|
21
24
|
]
|
|
@@ -46,6 +49,7 @@ dev = [
|
|
|
46
49
|
"griffe<2.0.0",
|
|
47
50
|
"ty==0.0.74",
|
|
48
51
|
"types-networkx>=3.6.1.20260728",
|
|
52
|
+
"matplotlib>=3.11.2",
|
|
49
53
|
]
|
|
50
54
|
|
|
51
55
|
# The bpy stubs mark most collections/pointers as `| None` and cannot type
|
|
@@ -67,3 +71,4 @@ ignore = ["SIM117", "RUF059"]
|
|
|
67
71
|
[tool.ruff.lint.per-file-ignores]
|
|
68
72
|
"tests/test_codegen.py" = ["S102"]
|
|
69
73
|
"tests/test_assets.py" = ["S102"]
|
|
74
|
+
"tests/test_layout_snapshot.py" = ["S102"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from . import builder, export, nodes, types
|
|
2
|
+
from .builder import (
|
|
3
|
+
ArrangeMethod,
|
|
4
|
+
SimpleOptions,
|
|
5
|
+
SugiyamaOptions,
|
|
6
|
+
TreeBuilder,
|
|
7
|
+
arrange,
|
|
8
|
+
default_sugiyama_options,
|
|
9
|
+
)
|
|
10
|
+
from .nodes import compositor, geometry, shader
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"ArrangeMethod",
|
|
14
|
+
"SimpleOptions",
|
|
15
|
+
"SugiyamaOptions",
|
|
16
|
+
"TreeBuilder",
|
|
17
|
+
"arrange",
|
|
18
|
+
"builder",
|
|
19
|
+
"compositor",
|
|
20
|
+
"default_sugiyama_options",
|
|
21
|
+
"export",
|
|
22
|
+
"geometry",
|
|
23
|
+
"nodes",
|
|
24
|
+
"shader",
|
|
25
|
+
"types",
|
|
26
|
+
]
|
|
@@ -10,12 +10,14 @@ compositor}.assets`` and are re-exported alongside the built-in nodes.
|
|
|
10
10
|
``dump_library`` and ``build_library`` round-trip a ``.blend`` asset library
|
|
11
11
|
through Python source: every asset is dumped to its own ``.py`` file (the
|
|
12
12
|
version-controlled source of truth) and the ``.blend`` is rebuilt from them
|
|
13
|
-
(``python -m nodebpy.assets dump/build``).
|
|
13
|
+
(``python -m nodebpy.assets dump/build``). ``plot_library`` renders node
|
|
14
|
+
groups from a ``.blend`` to PNG images by name or wildcard
|
|
15
|
+
(``python -m nodebpy.assets plot``), for review outside Blender.
|
|
14
16
|
"""
|
|
15
17
|
|
|
16
18
|
from ..builder import AssetLibrary, BundledLibrary, PackageLibrary
|
|
17
19
|
from ._codegen import generate_asset_api, generate_asset_modules
|
|
18
|
-
from ._library import build_library, dump_library
|
|
20
|
+
from ._library import build_library, dump_library, plot_library
|
|
19
21
|
|
|
20
22
|
__all__ = [
|
|
21
23
|
"AssetLibrary",
|
|
@@ -25,4 +27,5 @@ __all__ = [
|
|
|
25
27
|
"dump_library",
|
|
26
28
|
"generate_asset_api",
|
|
27
29
|
"generate_asset_modules",
|
|
30
|
+
"plot_library",
|
|
28
31
|
]
|
|
@@ -77,9 +77,12 @@ def parse_args() -> argparse.Namespace: # pragma: no cover - CLI wrapper
|
|
|
77
77
|
".blend to per-asset .py source files\n"
|
|
78
78
|
" build <source-dir> <blend> rebuild the .blend asset library "
|
|
79
79
|
"from dumped .py source files\n"
|
|
80
|
+
" plot <blend> <output-dir> [names ...]\n"
|
|
81
|
+
" render node groups (wildcards "
|
|
82
|
+
"supported) to PNG images\n"
|
|
80
83
|
"\n"
|
|
81
|
-
"See 'python -m nodebpy.assets dump --help'
|
|
82
|
-
"'
|
|
84
|
+
"See 'python -m nodebpy.assets dump --help', '… build --help' "
|
|
85
|
+
"and '… plot --help' for their options."
|
|
83
86
|
),
|
|
84
87
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
85
88
|
)
|
|
@@ -124,9 +127,10 @@ def parse_args() -> argparse.Namespace: # pragma: no cover - CLI wrapper
|
|
|
124
127
|
|
|
125
128
|
|
|
126
129
|
def main() -> None: # pragma: no cover - CLI wrapper
|
|
127
|
-
# The dump/build subcommands (blend ↔ .py round-trip
|
|
128
|
-
# parser; everything else keeps the original flag-based
|
|
129
|
-
|
|
130
|
+
# The dump/build/plot subcommands (blend ↔ .py round-trip, PNG renders)
|
|
131
|
+
# have their own parser; everything else keeps the original flag-based
|
|
132
|
+
# interface.
|
|
133
|
+
if len(sys.argv) > 1 and sys.argv[1] in ("dump", "build", "plot"):
|
|
130
134
|
from ._library import main as library_main
|
|
131
135
|
|
|
132
136
|
library_main(sys.argv[1:])
|
|
@@ -290,7 +290,7 @@ def _introspect(library: AssetLibrary, names: set[str] | None) -> list[_AssetCla
|
|
|
290
290
|
def _library_source(library: AssetLibrary) -> str:
|
|
291
291
|
"""Source expression that reconstructs ``library`` in the generated module."""
|
|
292
292
|
if isinstance(library, BundledLibrary):
|
|
293
|
-
return f"BundledLibrary({library.filename
|
|
293
|
+
return f"BundledLibrary({_fmt(library.filename)})"
|
|
294
294
|
from ..builder import PackageLibrary
|
|
295
295
|
|
|
296
296
|
if isinstance(library, PackageLibrary):
|
|
@@ -298,7 +298,7 @@ def _library_source(library: AssetLibrary) -> str:
|
|
|
298
298
|
# so the generated module imports cleanly and stays cross-platform even
|
|
299
299
|
# when ``relative`` was passed as a ``Path``.
|
|
300
300
|
relative = Path(library.relative).as_posix()
|
|
301
|
-
return f"PackageLibrary(__file__, {relative
|
|
301
|
+
return f"PackageLibrary(__file__, {_fmt(relative)})"
|
|
302
302
|
raise TypeError(f"Cannot serialise asset library: {library!r}")
|
|
303
303
|
|
|
304
304
|
|
|
@@ -355,8 +355,8 @@ def _render_class(cls: _AssetClass, docstrings: bool = False) -> str:
|
|
|
355
355
|
return f"""class {cls.class_name}({base}):
|
|
356
356
|
{docstring}
|
|
357
357
|
|
|
358
|
-
_name = {cls.asset_name
|
|
359
|
-
_asset_name = {cls.asset_name
|
|
358
|
+
_name = {_fmt(cls.asset_name)}
|
|
359
|
+
_asset_name = {_fmt(cls.asset_name)}
|
|
360
360
|
_library = {cls.library_source}
|
|
361
361
|
|
|
362
362
|
{inputs_cls}
|
|
@@ -451,7 +451,7 @@ def interface_parts(
|
|
|
451
451
|
if library_source:
|
|
452
452
|
base = asset_group_base(cls.tree_idname).__name__
|
|
453
453
|
attr_lines = [
|
|
454
|
-
f"_asset_name = {cls.asset_name
|
|
454
|
+
f"_asset_name = {_fmt(cls.asset_name)}",
|
|
455
455
|
f"_library = {library_source}",
|
|
456
456
|
]
|
|
457
457
|
|