Release 0.1

This commit is contained in:
Stefan Cepko
2026-06-05 04:45:35 -04:00
parent b6d0eeffbb
commit 31e464f5cd
6 changed files with 289 additions and 54 deletions
+31
View File
@@ -0,0 +1,31 @@
name: Build & Release Addon (Gitea)
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Build Zip Package
run: python package_addon.py
- name: Create Release
uses: https://gitea.com/actions/release-action@main
with:
files: |
releases/*.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+36
View File
@@ -0,0 +1,36 @@
name: Build & Release Addon (GitHub)
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: write
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Build Zip Package
run: python package_addon.py
- name: Create Release and Upload Asset
uses: softprops/action-gh-release@v2
with:
files: |
releases/*.zip
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+102 -44
View File
@@ -8,10 +8,10 @@ A Blender add-on that generates a continuously morphing parade of procedural [to
## Features ## Features
- **20 built-in shader presets** — Gloss Blue, Neon Glow, Metallic, Glass, Hologram, Lava, Iridescent, Matte Clay, Ghost, Car Paint, Chrome, Ruby Glass, Frosted Ice, Lichen Rough, Copper Patina, Zebra Stripes, Wood Veneer, Carbon Fiber, Pearlescent, Plasma Glow
- **Playlist-based animation** — add, remove, reorder any number of knots; each entry controls its own topology, geometry, material, and animation rates - **Playlist-based animation** — add, remove, reorder any number of knots; each entry controls its own topology, geometry, material, and animation rates
- **Smooth transitions** — configurable per-knot morph windows with Linear, Quadratic In/Out, or Smoothstep easing - **Smooth transitions** — configurable per-knot morph windows with Linear, Quadratic In/Out, or Smoothstep easing
- **Audio-reactive hooks** — drive the global Reactivity factor from a sound driver to pulse spin, height, and scale rates in sync with audio - **Audio-reactive hooks** — drive the global Reactivity factor from a sound driver to pulse spin, height, and scale rates in sync with audio
- **20 built-in shader presets** — Gloss Blue, Neon Glow, Metallic, Glass, Hologram, Lava, Iridescent, Matte Clay, Ghost, Car Paint, Chrome, Ruby Glass, Frosted Ice, Lichen Rough, Copper Patina, Zebra Stripes, Wood Veneer, Carbon Fiber, Pearlescent, Plasma Glow
- **Random playlist generator** — configure min/max ranges for every parameter and generate an entire playlist in one click - **Random playlist generator** — configure min/max ranges for every parameter and generate an entire playlist in one click
- **Bake & Export** — bake the procedural animation to a standalone `.blend` with per-frame mesh visibility keyframes; no addon required at render time; supports split-file export for SheepIt / distributed render farms - **Bake & Export** — bake the procedural animation to a standalone `.blend` with per-frame mesh visibility keyframes; no addon required at render time; supports split-file export for SheepIt / distributed render farms
- **Blender 5.0+ native** — uses the layered Action API (`action → layers → strips → channelbag → fcurves`) and Blender 5 Principled BSDF input names directly - **Blender 5.0+ native** — uses the layered Action API (`action → layers → strips → channelbag → fcurves`) and Blender 5 Principled BSDF input names directly
@@ -24,37 +24,74 @@ A Blender add-on that generates a continuously morphing parade of procedural [to
|---|---| |---|---|
| Blender | **5.0** or later | | Blender | **5.0** or later |
| Blender built-in addon | **Add Curve: Extra Objects** (auto-enabled by the script) | | Blender built-in addon | **Add Curve: Extra Objects** (auto-enabled by the script) |
> **Note:** The single-file version (`knot_animation.py`) has no installation step — just open and run in the Text Editor.
--- ---
## Installation ## Installation & Running
### Option A — Persistent Add-on (recommended) ### Option A — Persistent Add-on (Recommended for Users)
1. Download or clone this repository. 1. Download a release zip (or run `package_addon.py` to build one).
2. In Blender, go to **Edit → Preferences → Add-ons → Install…** 2. In Blender, go to **Edit → Preferences → Get Extensions → Add-ons** (or **Install from Disk...** from the top right gear menu).
3. Zip the `knot_animation/` folder and select the zip (Blender 5 requires a zip for local installs). 3. Select the zip file (e.g. `releases/pr3tz_v2.0.0.zip`).
4. Enable **"Pr3tz"** from the add-on list. 4. Enable **"Pr3tz"** from the list.
5. Open the **3D Viewport → N-panel → Pr3tz** tab. 5. Access the controls in the **3D Viewport → N-panel (sidebar) → Pr3tz** tab.
### Option B — Run as a Script (no installation) ### Option B — Symlink (Recommended for Developers)
``` To test and develop with live code updates without having to reinstall the addon:
# From inside Blender's Text Editor: 1. Open your terminal as Administrator (on Windows) or with standard user permissions (on Linux/macOS).
# File → Open → knot_animation/__init__.py → Run Script (Alt+P) 2. Run the appropriate command for your OS/shell to link the `pr3tz/` folder directly to Blender's local addons directory (replace path with your Blender version/path if needed):
# Or from the command line: **PowerShell (Windows):**
"C:\Program Files\Blender Foundation\Blender 5.0\blender.exe" --python knot_animation/__init__.py ```powershell
New-Item -ItemType SymbolicLink -Path "$env:APPDATA\Blender Foundation\Blender\5.0\scripts\addons\pr3tz" -Value "$PWD\pr3tz"
```
**CMD (Windows):**
```cmd
mklink /d "%APPDATA%\Blender Foundation\Blender\5.0\scripts\addons\pr3tz" "%CD%\pr3tz"
```
**Bash (Linux):**
```bash
ln -s "$PWD/pr3tz" "$HOME/.config/blender/5.0/scripts/addons/pr3tz"
```
**Bash (macOS):**
```bash
ln -s "$PWD/pr3tz" "$HOME/Library/Application Support/Blender/5.0/scripts/addons/pr3tz"
```
3. Enable **"Pr3tz"** in Blender's Preferences.
4. Press `F3` and search for **"Reload Scripts"** to reload changes instantly.
### Option C — Bootstrap Loader (No Installation)
Since Python relative imports fail when running individual module files directly, you can run the bootstrap script from the repository root:
1. Open Blender.
2. In the **Text Editor**, open [run_script.py](run_script.py).
3. Click **Run Script** (or press `Alt+P`).
Alternatively, load it directly from the terminal:
**PowerShell (Windows):**
```powershell
& "C:\Program Files\Blender Foundation\Blender 5.0\blender.exe" --python run_script.py
``` ```
### Option C — Single-file version **CMD (Windows):**
```cmd
`knot_animation_single_file.py` is a self-contained copy of the entire add-on in one file, useful for quick testing without touching Blender's add-on directory. "C:\Program Files\Blender Foundation\Blender 5.0\blender.exe" --python run_script.py
``` ```
blender.exe --python knot_animation_single_file.py
**Bash (Linux):**
```bash
blender --python run_script.py
```
**Bash (macOS):**
```bash
/Applications/Blender.app/Contents/MacOS/Blender --python run_script.py
``` ```
--- ---
@@ -79,23 +116,24 @@ The **Bake & Export** button (bottom of the Pr3tz panel) converts the procedural
4. Submit the resulting `.blend` file(s) to your render farm — no addon needed on the farm. 4. Submit the resulting `.blend` file(s) to your render farm — no addon needed on the farm.
--- ---
## Repository Layout
## Module Layout
``` ```
knot_animation/ ├── pr3tz/ # Main add-on package folder
├── __init__.py # Add-on entry point, bl_info, register/unregister ├── __init__.py # Add-on entry point, bl_info, register/unregister
├── constants.py # Default playlist configs, camera/light positions, name tags ├── constants.py # Default playlist configs, camera/light positions, name tags
├── types.py # KnotConfig TypedDict (shared data contract) ├── types.py # KnotConfig TypedDict (shared data contract)
├── compat.py # Headless align_matrix fix and other Blender compat patches ├── compat.py # Headless align_matrix fix and other Blender compat patches
├── properties.py # Blender PropertyGroups (KnotItem, KnotGlobalSettings, …) ├── properties.py # Blender PropertyGroups (KnotItem, KnotGlobalSettings, …)
├── operators.py # KNOT_OT_* operators (Add, Remove, Move, Generate, Fit…) ├── operators.py # KNOT_OT_* operators (Add, Remove, Move, Generate, Fit…)
├── ui.py # N-panel, UILists, draw_knot_properties() ├── ui.py # N-panel, UILists, draw_knot_properties()
├── geometry.py # _make_torus_knot() — pure parametric NURBS, no bpy.context reads ├── geometry.py # _make_torus_knot() — pure parametric NURBS, no bpy.context reads
├── materials.py # 20 shader builders, material cache, blend/transition system ├── materials.py # 20 shader builders, material cache, blend/transition system
├── handler.py # @persistent frame_change_post handler, easing, playlist timing ├── handler.py # @persistent frame_change_post handler, easing, playlist timing
├── scene_setup.py # setup_scene() — camera, area light, world, render settings ├── scene_setup.py # setup_scene() — camera, area light, world, render settings
└── bake_export.py # KNOT_OT_BakeExport — bake to standalone .blend └── bake_export.py # KNOT_OT_BakeExport — bake to standalone .blend
├── run_script.py # Bootstrap runner for Text Editor / CLI execution
└── package_addon.py # Automated packaging tool to create release .zip files
``` ```
--- ---
@@ -157,6 +195,26 @@ knot_animation/
| `PEARLESCENT` | Angle-dependent pearl sheen | | `PEARLESCENT` | Angle-dependent pearl sheen |
| `PLASMA_GLOW` | High-energy plasma emission | | `PLASMA_GLOW` | High-energy plasma emission |
---
## Release Packaging
We provide an automated script to pack the addon for release:
**PowerShell / CMD (Windows):**
```cmd
python package_addon.py
```
**Bash (macOS/Linux):**
```bash
python3 package_addon.py
```
This script:
1. Parses the release version dynamically from `pr3tz/__init__.py`.
2. Zips the `pr3tz/` directory into `releases/pr3tz_v<version>.zip`.
3. Automatically excludes developer files (`__pycache__`, `.git`, `.pyc`, etc.) so that the release package remains clean.
--- ---
## Contributing ## Contributing
@@ -165,13 +223,13 @@ Pull requests are welcome. For major changes please open an issue first.
### Development setup ### Development setup
```powershell To configure your workspace for active development:
# Clone 1. Clone the repository:
git clone https://github.com/YOUR_USERNAME/pr3tz.git ```bash
git clone https://github.com/YOUR_USERNAME/pr3tz.git
# Run the syntax checker (no Blender needed) ```
python check_syntax.py 2. Symlink the addon to Blender's addons folder as shown in **Option B** of the installation instructions.
``` 3. Use `run_script.py` to quickly test code changes from the CLI or Text Editor.
--- ---
+67
View File
@@ -0,0 +1,67 @@
import os
import re
import zipfile
def get_addon_version():
"""Reads pr3tz/__init__.py and extracts the bl_info version tuple."""
init_path = os.path.join("pr3tz", "__init__.py")
if not os.path.exists(init_path):
raise FileNotFoundError(f"Could not find {init_path}")
with open(init_path, "r", encoding="utf-8") as f:
content = f.read()
# Search for the "version": (x, y, z) pattern in bl_info
match = re.search(r'"version"\s*:\s*\(([^)]+)\)', content)
if not match:
raise ValueError("Could not parse version from bl_info in __init__.py")
version_str = match.group(1)
# Parse numbers, e.g. "2, 0, 0" -> ["2", "0", "0"] -> "2.0.0"
version_parts = [part.strip() for part in version_str.split(",")]
return ".".join(version_parts)
def package_addon():
"""Zips the pr3tz addon folder, excluding development artifacts."""
try:
version = get_addon_version()
except Exception as e:
print(f"Warning: Could not parse version: {e}. Defaulting to 'unknown'.")
version = "unknown"
release_dir = "releases"
if not os.path.exists(release_dir):
os.makedirs(release_dir)
print(f"Created output directory: {release_dir}/")
zip_filename = f"pr3tz_v{version}.zip"
zip_path = os.path.join(release_dir, zip_filename)
print(f"Packaging addon v{version} into {zip_path}...")
addon_dir = "pr3tz"
ignored_dirs = {"__pycache__", ".git"}
ignored_extensions = {".pyc", ".pyo", ".py.bak"}
added_count = 0
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(addon_dir):
# Prune directories in-place to prevent walking into them
dirs[:] = [d for d in dirs if d not in ignored_dirs]
for file in files:
_, ext = os.path.splitext(file)
if ext in ignored_extensions:
continue
file_path = os.path.join(root, file)
# Ensure the path in the ZIP has "pr3tz/" as its root folder
arcname = os.path.relpath(file_path, os.path.dirname(addon_dir))
zipf.write(file_path, arcname)
print(f" Added: {arcname}")
added_count += 1
print(f"\nSuccess! Packaged {added_count} files into {zip_path}")
if __name__ == "__main__":
package_addon()
+12 -10
View File
@@ -1,6 +1,6 @@
""" """
knot_animation/__init__.py pr3tz/__init__.py
-------------------------- -----------------
Blender add-on entry-point for the Pr3tz procedural animation system. Blender add-on entry-point for the Pr3tz procedural animation system.
What this add-on does What this add-on does
@@ -42,16 +42,18 @@ How to use
---------- ----------
Requires Blender 5.0 or later. Requires Blender 5.0 or later.
Option A Blender Text Editor: Option A Persistent add-on:
Open knot_animation/__init__.py, click Run Script (Alt+P). Zip the pr3tz/ folder (using package_addon.py) and install it from Preferences.
Alternatively, copy or symlink the pr3tz/ folder to Blender's addons directory
and enable it from Edit → Preferences → Add-ons.
The panel appears under the "Pr3tz" tab in the 3-D viewport N-panel.
Option B Command line: Option B Run as a script (via bootstrap runner):
blender.exe --python knot_animation/__init__.py Open run_script.py from the workspace root in Blender's Text Editor,
and click Run Script (Alt+P).
Option C Persistent add-on: Option C Command line:
Copy the knot_animation/ folder to Blender's addons directory and enable blender.exe --python run_script.py
it from Edit → Preferences → Add-ons. The panel appears under the
"Pr3tz" tab in the 3-D viewport N-panel.
""" """
if "bpy" in locals(): if "bpy" in locals():
+41
View File
@@ -0,0 +1,41 @@
import sys
import os
import bpy
# Get the directory of this script (workspace root) and append it to sys.path
dir_path = os.path.dirname(os.path.abspath(__file__))
if dir_path not in sys.path:
sys.path.append(dir_path)
# Try to register the pr3tz module
try:
# If the module was already imported, reload it to pick up changes
if "pr3tz" in sys.modules:
import importlib
import pr3tz
# Trigger reload inside pr3tz to refresh its submodules
importlib.reload(pr3tz)
else:
import pr3tz
# Unregister first to clean up any leftover handlers or UI components
try:
pr3tz.unregister()
except Exception:
pass
# Register the addon components
pr3tz.register()
# Run the initial scene setup (creates camera, light, and default playlist)
pr3tz.setup_scene()
# Generate the torus knot for the current frame immediately
pr3tz.knot_frame_handler(bpy.context.scene)
print("[Pr3tz] Registered and scene set up successfully!")
print("[Pr3tz] Scrub the timeline or press Space in the Viewport to animate.")
except Exception as e:
print(f"[Pr3tz] Failed to register: {e}")
import traceback
traceback.print_exc()