nodebpy 520.34.0__tar.gz → 520.35.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.34.0 → nodebpy-520.35.0}/PKG-INFO +2 -1
- {nodebpy-520.34.0 → nodebpy-520.35.0}/README.md +1 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/pyproject.toml +2 -1
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/__init__.py +2 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/asset.py +52 -6
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/codegen.py +63 -22
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/color.py +13 -10
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/filter.py +4 -4
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/manual.py +3 -3
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/output.py +2 -2
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/converter.py +12 -12
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/geometry.py +1 -1
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/input.py +2 -4
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/interface.py +13 -11
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/texture.py +14 -12
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/converter.py +4 -4
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/input.py +2 -2
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/output.py +12 -8
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/texture.py +5 -5
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/__main__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/assets/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/assets/__main__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/assets/_codegen.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/assets/_library.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/assets/_pipeline.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/assets/_textconv.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/_registry.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/_socket_order.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/_utils.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/accessor.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/items.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/mixins.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/node.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/socket.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/builder/tree.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/_floats.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/diagram.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/parity.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/plot.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/export/web_render.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/DESIGN.md +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/api.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/apply.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/balancing.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/build.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/common.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/config.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/digraph.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/dna.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/edits.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/extract.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/long_links.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/model.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/node_size.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/ordering.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/packing.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/pipeline.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/placement.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/priority.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/ranking.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/realize.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/reroutes.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/routing.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/snapping.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/spacing.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/stacking.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/sugiyama.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/layout/zones.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/live.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/_mixins.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/assets.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/converter.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/distort.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/group.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/input.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/interface.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/matte.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/compositor/vector.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/assets.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/attribute.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/color.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/grid.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/group.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/groups.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/manual.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/output.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/utilities.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/vector.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/geometry/zone.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/__init__.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/assets.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/color.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/grid.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/group.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/manual.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/script.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/shader.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/nodes/shader/vector.py +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.0}/src/nodebpy/py.typed +0 -0
- {nodebpy-520.34.0 → nodebpy-520.35.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.35.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>
|
|
@@ -20,6 +20,7 @@ Description-Content-Type: text/markdown
|
|
|
20
20
|
[](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml)
|
|
22
22
|
[](https://codecov.io/gh/BradyAJohnston/nodebpy)
|
|
23
|
+
[](https://app.codspeed.io/BradyAJohnston/nodebpy?utm_source=badge)
|
|
23
24
|
|
|
24
25
|
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.
|
|
25
26
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://github.com/BradyAJohnston/nodebpy/actions/workflows/tests.yml)
|
|
5
5
|
[](https://codecov.io/gh/BradyAJohnston/nodebpy)
|
|
6
|
+
[](https://app.codspeed.io/BradyAJohnston/nodebpy?utm_source=badge)
|
|
6
7
|
|
|
7
8
|
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
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nodebpy"
|
|
3
|
-
version = "520.
|
|
3
|
+
version = "520.35.0"
|
|
4
4
|
description = "Build nodes trees in Blender more elegantly with code"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -49,6 +49,7 @@ dev = [
|
|
|
49
49
|
"ty==0.0.74",
|
|
50
50
|
"matplotlib>=3.11.2",
|
|
51
51
|
"databpy>=0.9.0",
|
|
52
|
+
"pytest-codspeed>=5.0.3",
|
|
52
53
|
]
|
|
53
54
|
|
|
54
55
|
# The bpy stubs mark most collections/pointers as `| None` and cannot type
|
|
@@ -16,6 +16,7 @@ from .asset import (
|
|
|
16
16
|
PackageLibrary,
|
|
17
17
|
asset_group_base,
|
|
18
18
|
build_from_source,
|
|
19
|
+
link_assets,
|
|
19
20
|
)
|
|
20
21
|
from .items import Item, ItemsMixin, MenuItem
|
|
21
22
|
from .mixins import LinkingMixin, OperatorMixin
|
|
@@ -162,5 +163,6 @@ __all__ = [
|
|
|
162
163
|
"default_split_inputs",
|
|
163
164
|
"default_sugiyama_options",
|
|
164
165
|
"denormalize_name",
|
|
166
|
+
"link_assets",
|
|
165
167
|
"normalize_name",
|
|
166
168
|
]
|
|
@@ -127,22 +127,67 @@ class _AssetGroupMixin:
|
|
|
127
127
|
cls = type(self)
|
|
128
128
|
if _build_from_source_depth and cls._has_build_source():
|
|
129
129
|
return super()._create_group() # ty: ignore[unresolved-attribute]
|
|
130
|
+
group = link_assets(cls).get(cls)
|
|
131
|
+
if group is None: # no library on disk, build from the recipe instead
|
|
132
|
+
return super()._create_group() # ty: ignore[unresolved-attribute]
|
|
133
|
+
return group
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def link_assets(*groups: type[_AssetGroupMixin]) -> dict[type, Any]:
|
|
137
|
+
"""Link several asset groups, reading each asset library once.
|
|
138
|
+
|
|
139
|
+
Creating an asset group reads its whole ``.blend`` library, which costs the
|
|
140
|
+
same however few groups are taken from it. Linking the groups a tree is about
|
|
141
|
+
to use up front, in one read per library, avoids paying that for each one;
|
|
142
|
+
the groups' nodes then reuse the linked trees.
|
|
143
|
+
|
|
144
|
+
Groups already in the file (same name and tree type) are reused, and groups
|
|
145
|
+
that would build from their ``_build_group`` source (inside
|
|
146
|
+
:func:`build_from_source`, or with no library on disk) are skipped.
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
dict
|
|
151
|
+
The node tree for each linked or reused group class.
|
|
152
|
+
|
|
153
|
+
Raises
|
|
154
|
+
------
|
|
155
|
+
FileNotFoundError
|
|
156
|
+
A group without a build recipe has no library on disk.
|
|
157
|
+
KeyError
|
|
158
|
+
A library does not contain the requested group.
|
|
159
|
+
"""
|
|
160
|
+
trees: dict[type, Any] = {}
|
|
161
|
+
to_link: dict[str, list[type[_AssetGroupMixin]]] = {}
|
|
162
|
+
for cls in groups:
|
|
163
|
+
if _build_from_source_depth and cls._has_build_source():
|
|
164
|
+
continue
|
|
130
165
|
existing = bpy.data.node_groups.get(cls._asset_name)
|
|
131
166
|
if existing is not None and existing.bl_idname == cls._tree_idname:
|
|
132
|
-
|
|
167
|
+
trees[cls] = existing
|
|
168
|
+
continue
|
|
133
169
|
path = cls._library.path()
|
|
134
170
|
if not os.path.exists(path):
|
|
135
171
|
if cls._has_build_source():
|
|
136
|
-
|
|
172
|
+
continue
|
|
137
173
|
raise FileNotFoundError(f"Asset library not found: {path}")
|
|
174
|
+
to_link.setdefault(path, []).append(cls)
|
|
175
|
+
|
|
176
|
+
for path, classes in to_link.items():
|
|
177
|
+
names = list(dict.fromkeys(cls._asset_name for cls in classes))
|
|
138
178
|
with bpy.data.libraries.load(path, link=True, pack=True, assets_only=True) as ( # ty: ignore[invalid-context-manager]
|
|
139
179
|
src,
|
|
140
180
|
dst,
|
|
141
181
|
):
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
for name in names:
|
|
183
|
+
if name not in src.node_groups:
|
|
184
|
+
raise KeyError(f"Node group {name!r} not found in {path}")
|
|
185
|
+
# a copy: Blender swaps the names in this list for the linked trees
|
|
186
|
+
dst.node_groups = list(names)
|
|
187
|
+
linked = dict(zip(names, dst.node_groups))
|
|
188
|
+
for cls in classes:
|
|
189
|
+
trees[cls] = linked[cls._asset_name]
|
|
190
|
+
return trees
|
|
146
191
|
|
|
147
192
|
|
|
148
193
|
class AssetGeometryGroup(_AssetGroupMixin, CustomGeometryGroup):
|
|
@@ -179,6 +224,7 @@ __all__ = [
|
|
|
179
224
|
"PackageLibrary",
|
|
180
225
|
"asset_group_base",
|
|
181
226
|
"build_from_source",
|
|
227
|
+
"link_assets",
|
|
182
228
|
]
|
|
183
229
|
|
|
184
230
|
# Public alias for the mixin, for type hints / isinstance in generated code.
|
|
@@ -1102,9 +1102,6 @@ class EmitContext:
|
|
|
1102
1102
|
pending_lines: list[str] = field(default_factory=list)
|
|
1103
1103
|
zones: dict[str, _ZoneState] = field(default_factory=dict)
|
|
1104
1104
|
collector: _GroupCollector | None = None
|
|
1105
|
-
# Statements emitted after the body — menu interface defaults whose enum is
|
|
1106
|
-
# only populated once the consuming MenuSwitch has been created and linked.
|
|
1107
|
-
iface_deferred: list[str] = field(default_factory=list)
|
|
1108
1105
|
|
|
1109
1106
|
def input_link(self, node: Node, identifier: str) -> _Link | None:
|
|
1110
1107
|
"""The effective link into ``node``'s socket ``identifier``, if any."""
|
|
@@ -1558,11 +1555,65 @@ def _non_default_props(node, cls: type) -> dict[str, Any]:
|
|
|
1558
1555
|
current = getattr(node, rna_name)
|
|
1559
1556
|
except AttributeError:
|
|
1560
1557
|
continue
|
|
1558
|
+
if rna_name == "is_active_output":
|
|
1559
|
+
if current and _has_sibling_output(node):
|
|
1560
|
+
result[name] = True
|
|
1561
|
+
continue
|
|
1562
|
+
if rna_name in _DERIVED_PROPS:
|
|
1563
|
+
continue
|
|
1564
|
+
if param.default is None:
|
|
1565
|
+
# left to Blender unless passed, so compare with what Blender sets
|
|
1566
|
+
# on a new node in this kind of tree (Noise Texture is 2D in the
|
|
1567
|
+
# compositor and 3D elsewhere)
|
|
1568
|
+
fresh = _fresh_property(node, rna_name)
|
|
1569
|
+
if fresh is not _UNKNOWN and current == fresh:
|
|
1570
|
+
continue
|
|
1571
|
+
result[name] = current
|
|
1572
|
+
continue
|
|
1561
1573
|
if current != param.default:
|
|
1562
1574
|
result[name] = current
|
|
1563
1575
|
return result
|
|
1564
1576
|
|
|
1565
1577
|
|
|
1578
|
+
_UNKNOWN = object()
|
|
1579
|
+
_FRESH_PROPERTIES: dict[tuple[str, str, str], object] = {}
|
|
1580
|
+
|
|
1581
|
+
|
|
1582
|
+
def _fresh_property(node, rna_name: str) -> object:
|
|
1583
|
+
"""``rna_name`` on a freshly added node of this type in this kind of tree."""
|
|
1584
|
+
tree_idname = getattr(getattr(node, "id_data", None), "bl_idname", "")
|
|
1585
|
+
key = (tree_idname, node.bl_idname, rna_name)
|
|
1586
|
+
if key not in _FRESH_PROPERTIES:
|
|
1587
|
+
|
|
1588
|
+
def probe(probe_tree) -> object:
|
|
1589
|
+
return getattr(probe_tree.nodes.new(node.bl_idname), rna_name)
|
|
1590
|
+
|
|
1591
|
+
_FRESH_PROPERTIES[key] = _with_probe_tree(tree_idname, probe, _UNKNOWN)
|
|
1592
|
+
return _FRESH_PROPERTIES[key]
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
# Properties RNA computes from the node's sockets rather than storing: Color
|
|
1596
|
+
# Balance's white points are its temperature and tint inputs, which are
|
|
1597
|
+
# exported as sockets already.
|
|
1598
|
+
_DERIVED_PROPS = frozenset({"input_whitepoint", "output_whitepoint"})
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
def _has_sibling_output(node) -> bool:
|
|
1602
|
+
"""Whether the tree holds another output node of the same type.
|
|
1603
|
+
|
|
1604
|
+
Constructors leave ``is_active_output`` to Blender, which makes the first
|
|
1605
|
+
output of each type active, so it only needs spelling out when there is a
|
|
1606
|
+
choice. Setting it to True deactivates the others, so the active output is
|
|
1607
|
+
rebuilt whatever order the nodes are created in.
|
|
1608
|
+
"""
|
|
1609
|
+
tree = getattr(node, "id_data", None)
|
|
1610
|
+
if tree is None:
|
|
1611
|
+
return False
|
|
1612
|
+
return any(
|
|
1613
|
+
other.bl_idname == node.bl_idname and other != node for other in tree.nodes
|
|
1614
|
+
)
|
|
1615
|
+
|
|
1616
|
+
|
|
1566
1617
|
# ---------------------------------------------------------------------------
|
|
1567
1618
|
# Factory reverse-mapping
|
|
1568
1619
|
#
|
|
@@ -3730,16 +3781,13 @@ def _emit_interface(
|
|
|
3730
3781
|
# A socket no effective link touches (e.g. a panel-toggle input, or one
|
|
3731
3782
|
# only read through the modifier UI) still needs its declaration, but the
|
|
3732
3783
|
# variable is never referenced again — prefix it so the generated module
|
|
3733
|
-
# passes lint (F841).
|
|
3734
|
-
# its deferred ``var.default_value = …`` line reads the variable.
|
|
3784
|
+
# passes lint (F841).
|
|
3735
3785
|
if direction == "inputs":
|
|
3736
3786
|
used = any(
|
|
3737
3787
|
link.from_node.bl_idname == "NodeGroupInput"
|
|
3738
3788
|
and link.from_socket.identifier == item.identifier
|
|
3739
3789
|
for link in ctx.links
|
|
3740
3790
|
)
|
|
3741
|
-
if not used and item.socket_type == "NodeSocketMenu":
|
|
3742
|
-
used = bool(getattr(item, "default_value", None))
|
|
3743
3791
|
else:
|
|
3744
3792
|
used = any(
|
|
3745
3793
|
link.to_node.bl_idname == "NodeGroupOutput"
|
|
@@ -3785,11 +3833,12 @@ def _emit_interface(
|
|
|
3785
3833
|
and (factory_default is None or _eq(default, factory_default))
|
|
3786
3834
|
):
|
|
3787
3835
|
default = None
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3836
|
+
# A menu default is emitted inline: the builder defers applying it to
|
|
3837
|
+
# context exit, once the MenuSwitch defining its enum items is linked.
|
|
3838
|
+
# An empty one (no linked MenuSwitch) has nothing to restore.
|
|
3839
|
+
if item.socket_type == "NodeSocketMenu" and not default:
|
|
3840
|
+
default = None
|
|
3841
|
+
if default is not None:
|
|
3793
3842
|
args.append(_fmt(default))
|
|
3794
3843
|
description = getattr(item, "description", "")
|
|
3795
3844
|
if description:
|
|
@@ -4312,7 +4361,6 @@ def _assemble_tree_body(emission: _TreeEmission) -> list[str]:
|
|
|
4312
4361
|
emission.body_lines,
|
|
4313
4362
|
emission.out_lines,
|
|
4314
4363
|
)
|
|
4315
|
-
deferred = emission.deferred_lines
|
|
4316
4364
|
lines = list(iface_lines)
|
|
4317
4365
|
if iface_lines and (body or out_lines):
|
|
4318
4366
|
lines.append("")
|
|
@@ -4321,11 +4369,7 @@ def _assemble_tree_body(emission: _TreeEmission) -> list[str]:
|
|
|
4321
4369
|
if body:
|
|
4322
4370
|
lines.append("")
|
|
4323
4371
|
lines.extend(out_lines)
|
|
4324
|
-
if
|
|
4325
|
-
if iface_lines or body or out_lines:
|
|
4326
|
-
lines.append("")
|
|
4327
|
-
lines.extend(deferred)
|
|
4328
|
-
if not (iface_lines or body or out_lines or deferred):
|
|
4372
|
+
if not (iface_lines or body or out_lines):
|
|
4329
4373
|
lines.append(" pass")
|
|
4330
4374
|
return lines
|
|
4331
4375
|
|
|
@@ -4340,7 +4384,6 @@ class _TreeEmission:
|
|
|
4340
4384
|
body_lines: list[str]
|
|
4341
4385
|
out_lines: list[str]
|
|
4342
4386
|
used_aliases: set[str]
|
|
4343
|
-
deferred_lines: list[str] = field(default_factory=list)
|
|
4344
4387
|
|
|
4345
4388
|
|
|
4346
4389
|
@dataclass
|
|
@@ -4962,9 +5005,7 @@ def _emit_tree(node_tree, collector: _GroupCollector) -> _TreeEmission:
|
|
|
4962
5005
|
source = ctx.upstream_expr(link, pipeline=True)
|
|
4963
5006
|
out_lines.extend(_stmt_lines(BinOp(">>", source, out_ref.require_expr())))
|
|
4964
5007
|
|
|
4965
|
-
return _TreeEmission(
|
|
4966
|
-
iface_lines, body, out_lines, ctx.used_aliases, ctx.iface_deferred
|
|
4967
|
-
)
|
|
5008
|
+
return _TreeEmission(iface_lines, body, out_lines, ctx.used_aliases)
|
|
4968
5009
|
|
|
4969
5010
|
|
|
4970
5011
|
# ---------------------------------------------------------------------------
|
|
@@ -386,8 +386,8 @@ class ColorBalance(BaseNode):
|
|
|
386
386
|
output_temperature: InputFloat = 6500.0,
|
|
387
387
|
output_tint: InputFloat = 10.0,
|
|
388
388
|
*,
|
|
389
|
-
input_whitepoint: tuple[float, float, float]
|
|
390
|
-
output_whitepoint: tuple[float, float, float]
|
|
389
|
+
input_whitepoint: tuple[float, float, float] | None = None,
|
|
390
|
+
output_whitepoint: tuple[float, float, float] | None = None,
|
|
391
391
|
):
|
|
392
392
|
super().__init__()
|
|
393
393
|
key_args = {
|
|
@@ -411,9 +411,12 @@ class ColorBalance(BaseNode):
|
|
|
411
411
|
"Output Temperature": output_temperature,
|
|
412
412
|
"Output Tint": output_tint,
|
|
413
413
|
}
|
|
414
|
-
|
|
415
|
-
self.output_whitepoint = output_whitepoint
|
|
414
|
+
|
|
416
415
|
self._establish_links(**key_args)
|
|
416
|
+
if input_whitepoint is not None:
|
|
417
|
+
self.input_whitepoint = input_whitepoint
|
|
418
|
+
if output_whitepoint is not None:
|
|
419
|
+
self.output_whitepoint = output_whitepoint
|
|
417
420
|
|
|
418
421
|
@classmethod
|
|
419
422
|
def lift_gamma_gain(
|
|
@@ -427,8 +430,8 @@ class ColorBalance(BaseNode):
|
|
|
427
430
|
base_gain: InputFloat = 1.0,
|
|
428
431
|
color_gain: InputColor = (1.0, 1.0, 1.0, 1.0),
|
|
429
432
|
*,
|
|
430
|
-
input_whitepoint: tuple[float, float, float]
|
|
431
|
-
output_whitepoint: tuple[float, float, float]
|
|
433
|
+
input_whitepoint: tuple[float, float, float] | None = None,
|
|
434
|
+
output_whitepoint: tuple[float, float, float] | None = None,
|
|
432
435
|
) -> "ColorBalance":
|
|
433
436
|
"""Create Color Balance node with type 'Lift/Gamma/Gain'."""
|
|
434
437
|
return cls(
|
|
@@ -457,8 +460,8 @@ class ColorBalance(BaseNode):
|
|
|
457
460
|
base_slope: InputFloat = 1.0,
|
|
458
461
|
color_slope: InputColor = (1.0, 1.0, 1.0, 1.0),
|
|
459
462
|
*,
|
|
460
|
-
input_whitepoint: tuple[float, float, float]
|
|
461
|
-
output_whitepoint: tuple[float, float, float]
|
|
463
|
+
input_whitepoint: tuple[float, float, float] | None = None,
|
|
464
|
+
output_whitepoint: tuple[float, float, float] | None = None,
|
|
462
465
|
) -> "ColorBalance":
|
|
463
466
|
"""Create Color Balance node with type 'Offset/Power/Slope (ASC-CDL)'."""
|
|
464
467
|
return cls(
|
|
@@ -485,8 +488,8 @@ class ColorBalance(BaseNode):
|
|
|
485
488
|
output_temperature: InputFloat = 6500.0,
|
|
486
489
|
output_tint: InputFloat = 10.0,
|
|
487
490
|
*,
|
|
488
|
-
input_whitepoint: tuple[float, float, float]
|
|
489
|
-
output_whitepoint: tuple[float, float, float]
|
|
491
|
+
input_whitepoint: tuple[float, float, float] | None = None,
|
|
492
|
+
output_whitepoint: tuple[float, float, float] | None = None,
|
|
490
493
|
) -> "ColorBalance":
|
|
491
494
|
"""Create Color Balance node with type 'White Point'."""
|
|
492
495
|
return cls(
|
|
@@ -616,10 +616,10 @@ class Defocus(BaseNode):
|
|
|
616
616
|
"OCTAGON", "HEPTAGON", "HEXAGON", "PENTAGON", "SQUARE", "TRIANGLE", "CIRCLE"
|
|
617
617
|
] = "CIRCLE",
|
|
618
618
|
angle: float = 0.0,
|
|
619
|
-
f_stop: float =
|
|
620
|
-
blur_max: float =
|
|
621
|
-
use_zbuffer: bool =
|
|
622
|
-
z_scale: float =
|
|
619
|
+
f_stop: float = 128.0,
|
|
620
|
+
blur_max: float = 16.0,
|
|
621
|
+
use_zbuffer: bool = False,
|
|
622
|
+
z_scale: float = 1.0,
|
|
623
623
|
):
|
|
624
624
|
super().__init__()
|
|
625
625
|
key_args = {"Image": image, "Z": z}
|
|
@@ -117,11 +117,11 @@ class Image(BaseNode):
|
|
|
117
117
|
def __init__(
|
|
118
118
|
self,
|
|
119
119
|
image: Image | None = None,
|
|
120
|
-
frame_duration: int =
|
|
121
|
-
frame_start: int =
|
|
120
|
+
frame_duration: int = 1,
|
|
121
|
+
frame_start: int = 1,
|
|
122
122
|
frame_offset: int = 0,
|
|
123
123
|
use_cyclic: bool = False,
|
|
124
|
-
use_auto_refresh: bool =
|
|
124
|
+
use_auto_refresh: bool = True,
|
|
125
125
|
layer: str | None = None,
|
|
126
126
|
view: str | None = None,
|
|
127
127
|
):
|
|
@@ -38,8 +38,8 @@ class FileOutput(BaseNode):
|
|
|
38
38
|
self,
|
|
39
39
|
directory: str = "",
|
|
40
40
|
file_name: str = "",
|
|
41
|
-
save_as_render: bool =
|
|
42
|
-
use_file_extension: bool =
|
|
41
|
+
save_as_render: bool = True,
|
|
42
|
+
use_file_extension: bool = True,
|
|
43
43
|
):
|
|
44
44
|
super().__init__()
|
|
45
45
|
key_args = {}
|
|
@@ -5212,7 +5212,7 @@ class MapRange(BaseNode):
|
|
|
5212
5212
|
to_max_float3: InputVector = (1.0, 1.0, 1.0),
|
|
5213
5213
|
steps_float3: InputVector = (4.0, 4.0, 4.0),
|
|
5214
5214
|
*,
|
|
5215
|
-
clamp: bool =
|
|
5215
|
+
clamp: bool = True,
|
|
5216
5216
|
interpolation_type: Literal[
|
|
5217
5217
|
"LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"
|
|
5218
5218
|
] = "LINEAR",
|
|
@@ -5247,7 +5247,7 @@ class MapRange(BaseNode):
|
|
|
5247
5247
|
to_min: InputFloat = 0.0,
|
|
5248
5248
|
to_max: InputFloat = 1.0,
|
|
5249
5249
|
*,
|
|
5250
|
-
clamp: bool =
|
|
5250
|
+
clamp: bool = True,
|
|
5251
5251
|
data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
|
|
5252
5252
|
) -> "MapRange":
|
|
5253
5253
|
"""Create Map Range with operation 'Linear'. Linear interpolation between From Min and From Max values"""
|
|
@@ -5272,7 +5272,7 @@ class MapRange(BaseNode):
|
|
|
5272
5272
|
to_max: InputFloat = 1.0,
|
|
5273
5273
|
steps: InputFloat = 4.0,
|
|
5274
5274
|
*,
|
|
5275
|
-
clamp: bool =
|
|
5275
|
+
clamp: bool = True,
|
|
5276
5276
|
data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
|
|
5277
5277
|
) -> "MapRange":
|
|
5278
5278
|
"""Create Map Range with operation 'Stepped Linear'. Stepped linear interpolation between From Min and From Max values"""
|
|
@@ -5297,7 +5297,7 @@ class MapRange(BaseNode):
|
|
|
5297
5297
|
to_min: InputFloat = 0.0,
|
|
5298
5298
|
to_max: InputFloat = 1.0,
|
|
5299
5299
|
*,
|
|
5300
|
-
clamp: bool =
|
|
5300
|
+
clamp: bool = True,
|
|
5301
5301
|
data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
|
|
5302
5302
|
) -> "MapRange":
|
|
5303
5303
|
"""Create Map Range with operation 'Smooth Step'. Smooth Hermite edge interpolation between From Min and From Max values"""
|
|
@@ -5321,7 +5321,7 @@ class MapRange(BaseNode):
|
|
|
5321
5321
|
to_min: InputFloat = 0.0,
|
|
5322
5322
|
to_max: InputFloat = 1.0,
|
|
5323
5323
|
*,
|
|
5324
|
-
clamp: bool =
|
|
5324
|
+
clamp: bool = True,
|
|
5325
5325
|
data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
|
|
5326
5326
|
) -> "MapRange":
|
|
5327
5327
|
"""Create Map Range with operation 'Smoother Step'. Smoother Hermite edge interpolation between From Min and From Max values"""
|
|
@@ -5345,7 +5345,7 @@ class MapRange(BaseNode):
|
|
|
5345
5345
|
to_min: InputFloat = 0.0,
|
|
5346
5346
|
to_max: InputFloat = 1.0,
|
|
5347
5347
|
*,
|
|
5348
|
-
clamp: bool =
|
|
5348
|
+
clamp: bool = True,
|
|
5349
5349
|
interpolation_type: Literal[
|
|
5350
5350
|
"LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"
|
|
5351
5351
|
] = "LINEAR",
|
|
@@ -5371,7 +5371,7 @@ class MapRange(BaseNode):
|
|
|
5371
5371
|
to_min: InputVector = (0.0, 0.0, 0.0),
|
|
5372
5372
|
to_max: InputVector = (1.0, 1.0, 1.0),
|
|
5373
5373
|
*,
|
|
5374
|
-
clamp: bool =
|
|
5374
|
+
clamp: bool = True,
|
|
5375
5375
|
interpolation_type: Literal[
|
|
5376
5376
|
"LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"
|
|
5377
5377
|
] = "LINEAR",
|
|
@@ -6335,7 +6335,7 @@ class Mix(BaseNode):
|
|
|
6335
6335
|
"COLOR",
|
|
6336
6336
|
"VALUE",
|
|
6337
6337
|
] = "MIX",
|
|
6338
|
-
clamp_factor: bool =
|
|
6338
|
+
clamp_factor: bool = True,
|
|
6339
6339
|
clamp_result: bool = False,
|
|
6340
6340
|
):
|
|
6341
6341
|
super().__init__()
|
|
@@ -6387,7 +6387,7 @@ class Mix(BaseNode):
|
|
|
6387
6387
|
"COLOR",
|
|
6388
6388
|
"VALUE",
|
|
6389
6389
|
] = "MIX",
|
|
6390
|
-
clamp_factor: bool =
|
|
6390
|
+
clamp_factor: bool = True,
|
|
6391
6391
|
clamp_result: bool = False,
|
|
6392
6392
|
) -> "Mix":
|
|
6393
6393
|
"""Create Mix with operation 'Float'."""
|
|
@@ -6431,7 +6431,7 @@ class Mix(BaseNode):
|
|
|
6431
6431
|
"COLOR",
|
|
6432
6432
|
"VALUE",
|
|
6433
6433
|
] = "MIX",
|
|
6434
|
-
clamp_factor: bool =
|
|
6434
|
+
clamp_factor: bool = True,
|
|
6435
6435
|
clamp_result: bool = False,
|
|
6436
6436
|
) -> "Mix":
|
|
6437
6437
|
"""Create Mix with operation 'Vector'."""
|
|
@@ -6475,7 +6475,7 @@ class Mix(BaseNode):
|
|
|
6475
6475
|
"COLOR",
|
|
6476
6476
|
"VALUE",
|
|
6477
6477
|
] = "MIX",
|
|
6478
|
-
clamp_factor: bool =
|
|
6478
|
+
clamp_factor: bool = True,
|
|
6479
6479
|
clamp_result: bool = False,
|
|
6480
6480
|
) -> "Mix":
|
|
6481
6481
|
"""Create Mix with operation 'Color'."""
|
|
@@ -6519,7 +6519,7 @@ class Mix(BaseNode):
|
|
|
6519
6519
|
"COLOR",
|
|
6520
6520
|
"VALUE",
|
|
6521
6521
|
] = "MIX",
|
|
6522
|
-
clamp_factor: bool =
|
|
6522
|
+
clamp_factor: bool = True,
|
|
6523
6523
|
clamp_result: bool = False,
|
|
6524
6524
|
) -> "Mix":
|
|
6525
6525
|
"""Create Mix with operation 'Rotation'."""
|
|
@@ -542,9 +542,7 @@ class Color(BaseNode):
|
|
|
542
542
|
@property
|
|
543
543
|
def o(self) -> _Outputs: ...
|
|
544
544
|
|
|
545
|
-
def __init__(
|
|
546
|
-
self, value: tuple[float, float, float, float] = (0.735, 0.735, 0.735, 1.0)
|
|
547
|
-
):
|
|
545
|
+
def __init__(self, value: tuple[float, float, float, float] = (0.5, 0.5, 0.5, 1.0)):
|
|
548
546
|
super().__init__()
|
|
549
547
|
key_args = {}
|
|
550
548
|
self.value = value
|
|
@@ -2300,7 +2298,7 @@ class Integer(BaseNode):
|
|
|
2300
2298
|
@property
|
|
2301
2299
|
def o(self) -> _Outputs: ...
|
|
2302
2300
|
|
|
2303
|
-
def __init__(self, integer: int =
|
|
2301
|
+
def __init__(self, integer: int = 0):
|
|
2304
2302
|
super().__init__()
|
|
2305
2303
|
key_args = {}
|
|
2306
2304
|
self.integer = integer
|
|
@@ -442,11 +442,13 @@ class GroupOutput(BaseNode):
|
|
|
442
442
|
@property
|
|
443
443
|
def o(self) -> _Outputs: ...
|
|
444
444
|
|
|
445
|
-
def __init__(self, is_active_output: bool =
|
|
445
|
+
def __init__(self, is_active_output: bool | None = None):
|
|
446
446
|
super().__init__()
|
|
447
447
|
key_args = {}
|
|
448
|
-
|
|
448
|
+
|
|
449
449
|
self._establish_links(**key_args)
|
|
450
|
+
if is_active_output is not None:
|
|
451
|
+
self.is_active_output = is_active_output
|
|
450
452
|
|
|
451
453
|
@property
|
|
452
454
|
def is_active_output(self) -> bool:
|
|
@@ -595,15 +597,15 @@ class TransformGizmo(BaseNode):
|
|
|
595
597
|
position: InputVector = (0.0, 0.0, 0.0),
|
|
596
598
|
rotation: InputRotation = (0.0, 0.0, 0.0),
|
|
597
599
|
*,
|
|
598
|
-
use_translation_x: bool =
|
|
599
|
-
use_translation_y: bool =
|
|
600
|
-
use_translation_z: bool =
|
|
601
|
-
use_rotation_x: bool =
|
|
602
|
-
use_rotation_y: bool =
|
|
603
|
-
use_rotation_z: bool =
|
|
604
|
-
use_scale_x: bool =
|
|
605
|
-
use_scale_y: bool =
|
|
606
|
-
use_scale_z: bool =
|
|
600
|
+
use_translation_x: bool = True,
|
|
601
|
+
use_translation_y: bool = True,
|
|
602
|
+
use_translation_z: bool = True,
|
|
603
|
+
use_rotation_x: bool = True,
|
|
604
|
+
use_rotation_y: bool = True,
|
|
605
|
+
use_rotation_z: bool = True,
|
|
606
|
+
use_scale_x: bool = True,
|
|
607
|
+
use_scale_y: bool = True,
|
|
608
|
+
use_scale_z: bool = True,
|
|
607
609
|
):
|
|
608
610
|
super().__init__()
|
|
609
611
|
key_args = {"Value": value, "Position": position, "Rotation": rotation}
|
|
@@ -684,7 +684,7 @@ class MagicTexture(BaseNode):
|
|
|
684
684
|
scale: InputFloat = 5.0,
|
|
685
685
|
distortion: InputFloat = 1.0,
|
|
686
686
|
*,
|
|
687
|
-
turbulence_depth: int =
|
|
687
|
+
turbulence_depth: int = 2,
|
|
688
688
|
):
|
|
689
689
|
super().__init__()
|
|
690
690
|
key_args = {"Vector": vector, "Scale": scale, "Distortion": distortion}
|
|
@@ -802,7 +802,7 @@ class NoiseTexture(BaseNode):
|
|
|
802
802
|
gain: InputFloat = 1.0,
|
|
803
803
|
distortion: InputFloat = 0.0,
|
|
804
804
|
*,
|
|
805
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
805
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
806
806
|
noise_type: Literal[
|
|
807
807
|
"MULTIFRACTAL",
|
|
808
808
|
"RIDGED_MULTIFRACTAL",
|
|
@@ -810,7 +810,7 @@ class NoiseTexture(BaseNode):
|
|
|
810
810
|
"FBM",
|
|
811
811
|
"HETERO_TERRAIN",
|
|
812
812
|
] = "FBM",
|
|
813
|
-
normalize: bool =
|
|
813
|
+
normalize: bool = True,
|
|
814
814
|
):
|
|
815
815
|
super().__init__()
|
|
816
816
|
key_args = {
|
|
@@ -824,7 +824,8 @@ class NoiseTexture(BaseNode):
|
|
|
824
824
|
"Gain": gain,
|
|
825
825
|
"Distortion": distortion,
|
|
826
826
|
}
|
|
827
|
-
|
|
827
|
+
if noise_dimensions is not None:
|
|
828
|
+
self.noise_dimensions = noise_dimensions
|
|
828
829
|
self.noise_type = noise_type
|
|
829
830
|
self.normalize = normalize
|
|
830
831
|
self._establish_links(**key_args)
|
|
@@ -839,7 +840,7 @@ class NoiseTexture(BaseNode):
|
|
|
839
840
|
lacunarity: InputFloat = 2.0,
|
|
840
841
|
distortion: InputFloat = 0.0,
|
|
841
842
|
*,
|
|
842
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
843
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
843
844
|
) -> "NoiseTexture":
|
|
844
845
|
"""Create Noise Texture with operation 'Multifractal'. More uneven result (varies with location), more similar to a real terrain"""
|
|
845
846
|
return cls(
|
|
@@ -865,7 +866,7 @@ class NoiseTexture(BaseNode):
|
|
|
865
866
|
gain: InputFloat = 1.0,
|
|
866
867
|
distortion: InputFloat = 0.0,
|
|
867
868
|
*,
|
|
868
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
869
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
869
870
|
) -> "NoiseTexture":
|
|
870
871
|
"""Create Noise Texture with operation 'Ridged Multifractal'. Create sharp peaks"""
|
|
871
872
|
return cls(
|
|
@@ -893,7 +894,7 @@ class NoiseTexture(BaseNode):
|
|
|
893
894
|
gain: InputFloat = 1.0,
|
|
894
895
|
distortion: InputFloat = 0.0,
|
|
895
896
|
*,
|
|
896
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
897
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
897
898
|
) -> "NoiseTexture":
|
|
898
899
|
"""Create Noise Texture with operation 'Hybrid Multifractal'. Create peaks and valleys with different roughness values"""
|
|
899
900
|
return cls(
|
|
@@ -919,8 +920,8 @@ class NoiseTexture(BaseNode):
|
|
|
919
920
|
lacunarity: InputFloat = 2.0,
|
|
920
921
|
distortion: InputFloat = 0.0,
|
|
921
922
|
*,
|
|
922
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
923
|
-
normalize: bool =
|
|
923
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
924
|
+
normalize: bool = True,
|
|
924
925
|
) -> "NoiseTexture":
|
|
925
926
|
"""Create Noise Texture with operation 'fBM'. The standard fractal Perlin noise"""
|
|
926
927
|
return cls(
|
|
@@ -946,7 +947,7 @@ class NoiseTexture(BaseNode):
|
|
|
946
947
|
offset: InputFloat = 0.0,
|
|
947
948
|
distortion: InputFloat = 0.0,
|
|
948
949
|
*,
|
|
949
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
950
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
950
951
|
) -> "NoiseTexture":
|
|
951
952
|
"""Create Noise Texture with operation 'Hetero Terrain'. Similar to Hybrid Multifractal creates a heterogeneous terrain, but with the likeness of river channels"""
|
|
952
953
|
return cls(
|
|
@@ -1435,11 +1436,12 @@ class WhiteNoiseTexture(BaseNode):
|
|
|
1435
1436
|
vector: InputVector = None,
|
|
1436
1437
|
w: InputFloat = 0.0,
|
|
1437
1438
|
*,
|
|
1438
|
-
noise_dimensions: Literal["1D", "2D", "3D", "4D"] =
|
|
1439
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] | None = None,
|
|
1439
1440
|
):
|
|
1440
1441
|
super().__init__()
|
|
1441
1442
|
key_args = {"Vector": vector, "W": w}
|
|
1442
|
-
|
|
1443
|
+
if noise_dimensions is not None:
|
|
1444
|
+
self.noise_dimensions = noise_dimensions
|
|
1443
1445
|
self._establish_links(**key_args)
|
|
1444
1446
|
|
|
1445
1447
|
@property
|
|
@@ -409,7 +409,7 @@ class Mix(BaseNode):
|
|
|
409
409
|
"COLOR",
|
|
410
410
|
"VALUE",
|
|
411
411
|
] = "MIX",
|
|
412
|
-
clamp_factor: bool =
|
|
412
|
+
clamp_factor: bool = True,
|
|
413
413
|
clamp_result: bool = False,
|
|
414
414
|
):
|
|
415
415
|
super().__init__()
|
|
@@ -461,7 +461,7 @@ class Mix(BaseNode):
|
|
|
461
461
|
"COLOR",
|
|
462
462
|
"VALUE",
|
|
463
463
|
] = "MIX",
|
|
464
|
-
clamp_factor: bool =
|
|
464
|
+
clamp_factor: bool = True,
|
|
465
465
|
clamp_result: bool = False,
|
|
466
466
|
) -> "Mix":
|
|
467
467
|
"""Create Mix with operation 'Float'."""
|
|
@@ -505,7 +505,7 @@ class Mix(BaseNode):
|
|
|
505
505
|
"COLOR",
|
|
506
506
|
"VALUE",
|
|
507
507
|
] = "MIX",
|
|
508
|
-
clamp_factor: bool =
|
|
508
|
+
clamp_factor: bool = True,
|
|
509
509
|
clamp_result: bool = False,
|
|
510
510
|
) -> "Mix":
|
|
511
511
|
"""Create Mix with operation 'Vector'."""
|
|
@@ -549,7 +549,7 @@ class Mix(BaseNode):
|
|
|
549
549
|
"COLOR",
|
|
550
550
|
"VALUE",
|
|
551
551
|
] = "MIX",
|
|
552
|
-
clamp_factor: bool =
|
|
552
|
+
clamp_factor: bool = True,
|
|
553
553
|
clamp_result: bool = False,
|
|
554
554
|
) -> "Mix":
|
|
555
555
|
"""Create Mix with operation 'Color'."""
|
|
@@ -78,7 +78,7 @@ class AmbientOcclusion(BaseNode):
|
|
|
78
78
|
distance: InputFloat = 1.0,
|
|
79
79
|
normal: InputVector = None,
|
|
80
80
|
*,
|
|
81
|
-
samples: int =
|
|
81
|
+
samples: int = 16,
|
|
82
82
|
inside: bool = False,
|
|
83
83
|
only_local: bool = False,
|
|
84
84
|
):
|
|
@@ -164,7 +164,7 @@ class Bevel(BaseNode):
|
|
|
164
164
|
radius: InputFloat = 0.05,
|
|
165
165
|
normal: InputVector = None,
|
|
166
166
|
*,
|
|
167
|
-
samples: int =
|
|
167
|
+
samples: int = 4,
|
|
168
168
|
):
|
|
169
169
|
super().__init__()
|
|
170
170
|
key_args = {"Radius": radius, "Normal": normal}
|
|
@@ -115,14 +115,15 @@ class LightOutput(BaseNode):
|
|
|
115
115
|
self,
|
|
116
116
|
surface: InputShader = None,
|
|
117
117
|
*,
|
|
118
|
-
is_active_output: bool =
|
|
118
|
+
is_active_output: bool | None = None,
|
|
119
119
|
target: Literal["ALL", "EEVEE", "CYCLES"] = "ALL",
|
|
120
120
|
):
|
|
121
121
|
super().__init__()
|
|
122
122
|
key_args = {"Surface": surface}
|
|
123
|
-
self.is_active_output = is_active_output
|
|
124
123
|
self.target = target
|
|
125
124
|
self._establish_links(**key_args)
|
|
125
|
+
if is_active_output is not None:
|
|
126
|
+
self.is_active_output = is_active_output
|
|
126
127
|
|
|
127
128
|
@property
|
|
128
129
|
def is_active_output(self) -> bool:
|
|
@@ -198,7 +199,7 @@ class LineStyleOutput(BaseNode):
|
|
|
198
199
|
alpha: InputFloat = 1.0,
|
|
199
200
|
alpha_fac: InputFloat = 1.0,
|
|
200
201
|
*,
|
|
201
|
-
is_active_output: bool =
|
|
202
|
+
is_active_output: bool | None = None,
|
|
202
203
|
target: Literal["ALL", "EEVEE", "CYCLES"] = "ALL",
|
|
203
204
|
blend_type: Literal[
|
|
204
205
|
"MIX",
|
|
@@ -231,12 +232,13 @@ class LineStyleOutput(BaseNode):
|
|
|
231
232
|
"Alpha": alpha,
|
|
232
233
|
"Alpha Fac": alpha_fac,
|
|
233
234
|
}
|
|
234
|
-
self.is_active_output = is_active_output
|
|
235
235
|
self.target = target
|
|
236
236
|
self.blend_type = blend_type
|
|
237
237
|
self.use_alpha = use_alpha
|
|
238
238
|
self.use_clamp = use_clamp
|
|
239
239
|
self._establish_links(**key_args)
|
|
240
|
+
if is_active_output is not None:
|
|
241
|
+
self.is_active_output = is_active_output
|
|
240
242
|
|
|
241
243
|
@property
|
|
242
244
|
def is_active_output(self) -> bool:
|
|
@@ -381,7 +383,7 @@ class MaterialOutput(BaseNode):
|
|
|
381
383
|
displacement: InputVector = None,
|
|
382
384
|
thickness: InputFloat = None,
|
|
383
385
|
*,
|
|
384
|
-
is_active_output: bool =
|
|
386
|
+
is_active_output: bool | None = None,
|
|
385
387
|
target: Literal["ALL", "EEVEE", "CYCLES"] = "ALL",
|
|
386
388
|
):
|
|
387
389
|
super().__init__()
|
|
@@ -391,9 +393,10 @@ class MaterialOutput(BaseNode):
|
|
|
391
393
|
"Displacement": displacement,
|
|
392
394
|
"Thickness": thickness,
|
|
393
395
|
}
|
|
394
|
-
self.is_active_output = is_active_output
|
|
395
396
|
self.target = target
|
|
396
397
|
self._establish_links(**key_args)
|
|
398
|
+
if is_active_output is not None:
|
|
399
|
+
self.is_active_output = is_active_output
|
|
397
400
|
|
|
398
401
|
@property
|
|
399
402
|
def is_active_output(self) -> bool:
|
|
@@ -455,14 +458,15 @@ class WorldOutput(BaseNode):
|
|
|
455
458
|
surface: InputShader = None,
|
|
456
459
|
volume: InputShader = None,
|
|
457
460
|
*,
|
|
458
|
-
is_active_output: bool =
|
|
461
|
+
is_active_output: bool | None = None,
|
|
459
462
|
target: Literal["ALL", "EEVEE", "CYCLES"] = "ALL",
|
|
460
463
|
):
|
|
461
464
|
super().__init__()
|
|
462
465
|
key_args = {"Surface": surface, "Volume": volume}
|
|
463
|
-
self.is_active_output = is_active_output
|
|
464
466
|
self.target = target
|
|
465
467
|
self._establish_links(**key_args)
|
|
468
|
+
if is_active_output is not None:
|
|
469
|
+
self.is_active_output = is_active_output
|
|
466
470
|
|
|
467
471
|
@property
|
|
468
472
|
def is_active_output(self) -> bool:
|
|
@@ -330,8 +330,8 @@ class SkyTexture(BaseNode):
|
|
|
330
330
|
aerosol_density: float = 1.0,
|
|
331
331
|
ozone_density: float = 1.0,
|
|
332
332
|
sun_direction: tuple[float, float, float] = (0.0, 0.0, 1.0),
|
|
333
|
-
turbidity: float =
|
|
334
|
-
ground_albedo: float = 0.
|
|
333
|
+
turbidity: float = 2.2,
|
|
334
|
+
ground_albedo: float = 0.3,
|
|
335
335
|
):
|
|
336
336
|
super().__init__()
|
|
337
337
|
key_args = {"Vector": vector}
|
|
@@ -412,7 +412,7 @@ class SkyTexture(BaseNode):
|
|
|
412
412
|
vector: InputVector = None,
|
|
413
413
|
*,
|
|
414
414
|
sun_direction: tuple[float, float, float] = (0.0, 0.0, 1.0),
|
|
415
|
-
turbidity: float =
|
|
415
|
+
turbidity: float = 2.2,
|
|
416
416
|
) -> "SkyTexture":
|
|
417
417
|
"""Create Sky Texture with operation 'Preetham'. Preetham 1999 (Legacy)"""
|
|
418
418
|
return cls(
|
|
@@ -428,8 +428,8 @@ class SkyTexture(BaseNode):
|
|
|
428
428
|
vector: InputVector = None,
|
|
429
429
|
*,
|
|
430
430
|
sun_direction: tuple[float, float, float] = (0.0, 0.0, 1.0),
|
|
431
|
-
turbidity: float =
|
|
432
|
-
ground_albedo: float = 0.
|
|
431
|
+
turbidity: float = 2.2,
|
|
432
|
+
ground_albedo: float = 0.3,
|
|
433
433
|
) -> "SkyTexture":
|
|
434
434
|
"""Create Sky Texture with operation 'Hosek / Wilkie'. Hosek / Wilkie 2012 (Legacy)"""
|
|
435
435
|
return cls(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|