Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
563798a
fix: interface socket's hard_min/max are irrelevant
Vollkornaffe Feb 23, 2026
96f17b5
chore: delete .python-version and put into ignore
Vollkornaffe Feb 23, 2026
f7e00f9
chore: change deps to test Blender 5.1
Vollkornaffe Feb 23, 2026
54a93bb
fix: somehow the conftest doesn't work otherwise
Vollkornaffe Feb 23, 2026
c71b032
tidy: the printed message was a tad off
Vollkornaffe Feb 23, 2026
ffdd588
Merge pull request #163 from Algebraic-UG/skip_clamping_for_interface
Vollkornaffe Feb 23, 2026
4c6a2c3
feat: add support for Field to List node
Vollkornaffe Feb 24, 2026
a1bf34f
fix: skip 'add' and 'remove' attributes
Vollkornaffe Feb 24, 2026
2ed2b20
Merge pull request #166 from Algebraic-UG/fix_cryptomatte_nodes
Vollkornaffe Feb 24, 2026
acc6f80
tidy: remove superfluous call
Vollkornaffe Feb 25, 2026
9f759f6
tidy: reusing class name
Vollkornaffe Feb 25, 2026
10755e8
fix: font is now a socket
Vollkornaffe Feb 25, 2026
ec516ca
feat: store imported blender version for backward compat handling
Vollkornaffe Feb 25, 2026
86df494
fix: missing parent import
Vollkornaffe Feb 25, 2026
e2b9f2b
feat: add backward compat for String to Curves
Vollkornaffe Feb 25, 2026
281e62d
refactor
Vollkornaffe Feb 25, 2026
954ec79
feat: add backward compat for UV Unwrap
Vollkornaffe Feb 25, 2026
83215e3
feat: add backward compat for Pack UV Islands
Vollkornaffe Feb 25, 2026
ae6504d
fix: actually import the sockets' default_value
Vollkornaffe Feb 25, 2026
fc2f073
chore: make default hint available for tests
Vollkornaffe Feb 25, 2026
947638a
fix: allow passing None as external ref
Vollkornaffe Feb 25, 2026
68223b2
fix: make external items test work for 5.0 again
Vollkornaffe Feb 25, 2026
b2a3635
feat: add some tests for the backwards compatibility
Vollkornaffe Feb 25, 2026
2d8dba9
tidy: remove some superfluous ignores
Vollkornaffe Feb 25, 2026
c500594
fix: remove this weirdness
Vollkornaffe Feb 25, 2026
b02868e
tidy: ruff
Vollkornaffe Feb 25, 2026
af68889
fix: vendorize task
Vollkornaffe Feb 25, 2026
a7e011d
fix: import in addon
Vollkornaffe Feb 25, 2026
54913f2
feat: add backward compat for Fill Curve
Vollkornaffe Feb 25, 2026
08603fc
feat: add simple import test for old exports
Vollkornaffe Feb 25, 2026
c30493d
Revert "accept bpy version override in CI"
Vollkornaffe Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ on:
pull_request:
branches: ["*"]
workflow_dispatch:
inputs:
bpy_spec:
description: 'Override bpy requirement (e.g. "bpy==5.1.0" or "bpy>=5.0,<5.2")'
required: false
default: ""

# Cancel in-progress runs when a new workflow with the same group is triggered
concurrency:
Expand Down Expand Up @@ -49,10 +44,6 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Lock with bpy override
if: ${{ github.event.inputs.bpy_spec != '' }}
run: uv lock --upgrade-package "${{ github.event.inputs.bpy_spec }}"

- name: Install tree_clipper
run: uv sync --all-extras

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
Expand Down
1 change: 0 additions & 1 deletion .python-version

This file was deleted.

1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"command": "uv",
"args": [
"run",
"--prerelease=allow",
"python-vendorize",
],
"options": {
Expand Down
3 changes: 1 addition & 2 deletions packages/tree_clipper/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[project]
name = "tree-clipper"
version = "0.1.5"
requires-python = ">=3.11"
dependencies = []
maintainers = [
{ name="Algebraic", email="tree.clipper@algebraic.games" },
Expand All @@ -26,7 +25,7 @@ Homepage = "https://github.com/Algebraic-UG/tree_clipper"
Issues = "https://github.com/Algebraic-UG/tree_clipper/issues"

[project.optional-dependencies]
bpy = [ "bpy >= 5.0.0, < 5.1" ]
bpy = [ "bpy >= 5" ]

[build-system]
requires = ["uv_build >= 0.9.18, < 0.10.0"]
Expand Down
1 change: 1 addition & 0 deletions packages/tree_clipper/src/tree_clipper/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,4 @@ def most_specific_type_handled(
EXTERNAL_SERIALIZATION = dict[str, int | str | None]

DEFAULT_FILE = str(Path(tempfile.gettempdir()) / "default.json")
DEFAULT_HINT = "Hint for Import"
3 changes: 3 additions & 0 deletions packages/tree_clipper/src/tree_clipper/export_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ def _export_property_simple(

# https://github.com/Algebraic-UG/tree_clipper/issues/96
def clamp_and_report(value: int | float) -> int | float:
# https://github.com/Algebraic-UG/tree_clipper/issues/162
if isinstance(obj, bpy.types.NodeTreeInterfaceSocket):
return value
# https://github.com/Algebraic-UG/tree_clipper/issues/132
if (
isinstance(obj, bpy.types.NodeSocket)
Expand Down
26 changes: 21 additions & 5 deletions packages/tree_clipper/src/tree_clipper/import_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@ def __init__(
class Importer:
def __init__(
self,
*,
blender_version: list[int],
specific_handlers: dict[type, DESERIALIZER],
getters: dict[int, GETTER],
debug_prints: bool,
) -> None:
self.blender_version = blender_version

self.specific_handlers = specific_handlers
self.getters = getters
self.debug_prints = debug_prints
Expand Down Expand Up @@ -498,10 +502,15 @@ def getter() -> bpy.types.ShaderNodeTree:


def _check_version(data: dict) -> None:
exporter_blender_version = data[BLENDER_VERSION]
importer_blender_version = bpy.app.version_string

if exporter_blender_version != importer_blender_version:
exporter_blender_version = [
int(v) for v in data[BLENDER_VERSION].split(" ")[0].split(".")
]
importer_blender_version = bpy.app.version

if (
exporter_blender_version[0] != importer_blender_version[0]
or exporter_blender_version[1] > importer_blender_version[1]
):
raise RuntimeError(
f"Blender version mismatch. File version: {exporter_blender_version}, but running {importer_blender_version}"
)
Expand Down Expand Up @@ -586,7 +595,7 @@ def get_external(self) -> dict[str, EXTERNAL_SERIALIZATION]:

def set_external(
self,
ids_and_references: Iterator[Tuple[int, bpy.types.ID]],
ids_and_references: Iterator[Tuple[int, bpy.types.ID | None]],
) -> None:
for external_id, external_item in ids_and_references:
scene_id = self.get_external()[str(external_id)][EXTERNAL_SCENE_ID]
Expand Down Expand Up @@ -620,11 +629,18 @@ def set_external(
assert int(external_id) in self.getters

def start_import(self, parameters: ImportParameters) -> None:
version_cycle = self.data[BLENDER_VERSION].split(" ")
blender_version = [int(v) for v in version_cycle[0].split(".")]
self.importer = Importer(
blender_version=blender_version,
specific_handlers=parameters.specific_handlers,
getters=self.getters,
debug_prints=parameters.debug_prints,
)
if len(version_cycle) > 1:
self.importer.report.warnings.append(
f"This was exported from a Blender {version_cycle[1]} version."
)

def step(self) -> bool:
assert isinstance(self.importer, Importer)
Expand Down
24 changes: 24 additions & 0 deletions packages/tree_clipper/src/tree_clipper/specific_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,30 @@ def import_all_simple_writable_properties_and_list(self, id_list: list[str]):
self.import_all_simple_writable_properties()
self.import_properties_from_id_list(id_list)

def only_create_getters(self, id_list: list[str]):
for identifier in id_list:
self.register_getter(
getter=lambda: getattr(self.getter(), identifier),
serialization=self.serialization[identifier],
from_root=self.from_root.add_prop(
self.getter().bl_rna.properties[identifier]
),
)

def register_getter(
self,
*,
getter: GETTER,
serialization: dict[str, Any],
from_root,
):
self.importer._import_obj_with_deserializer(
getter=getter,
serialization=serialization,
deserializer=default_deserializer,
from_root=from_root,
)

@abstractmethod
def deserialize(self) -> None:
"""Do the actual importing here"""
Loading