Technical Art portfolio bridging code architecture with artist-friendly environments. Includes Python pipeline automation, headless rendering scripts, and procedural Geometry Nodes setups. Built to eliminate bottlenecks and scale 3D workflows in Blender.
| ← Back to Home | 🔗 View Full Repository on GitHub |
Macuare Hub in action: Single Sign-On (SSO), dynamic environment building, and isolated DCC launching.
Updating software mid-production is a massive risk for any studio. Global installations and cross-dependencies often mean that upgrading a tool for a new project completely breaks legacy projects. Artists waste hours dealing with Python AttributeError crashes, missing add-ons, and manual path configurations just to open an older file.
Furthermore, traditional pipelines often rely on saving plain-text SVN or network credentials on local disks, creating significant security vulnerabilities in shared studio environments.
The challenge was twofold: eliminate environment friction entirely (ensuring every project retains its original “DNA” to be opened years later) and secure network credentials without compromising the artist’s user experience.
To solve this, I developed the Macuare Hub, a custom environment manager and standalone executable written in Python. Functioning as a lightweight, OS-agnostic alternative to frameworks like rez, this launcher creates an absolute, invisible sandbox for artists.
It acts as a bridge between our production tracker (Kitsu), our version control (SVN), and our hybrid storage (Nextcloud). Based on the project’s JSON manifest, the Hub dynamically extracts specific DCC binaries, isolates required add-ons locally, and injects runtime variables—all without touching the OS global registry.
BLENDER_USER_RESOURCES, the Hub forces the DCC to read and write preferences, extensions, and scripts strictly within a local project folder (06_conf_LOCAL). Artists can run Blender 3.6 and Blender 4.2 simultaneously without cross-contamination.
| Category | Technology Used |
|---|---|
| Language / UI | Python 3.12, CustomTkinter (Artist-proof UI) |
| Production Tracking | Kitsu (Gazu API for SSO and Role Validation) |
| Network / VCS | SVN (Apache Subversion), Nextcloud, Git LFS |
| Core Architecture | MVC Pattern, In-Memory Vault, Ephemeral Sandboxing |
| Distribution | PyInstaller (Standalone frozen executable, no Python required for artists) |
Instead of extracting add-ons globally, the Hub builds an ephemeral environment. It hijacks the DCC’s resource paths before launching the subprocess, guaranteeing zero global footprint.
import os
import subprocess
from pathlib import Path
def lanzar_blender(project_root: Path, config_path: Path, svn_user: str, svn_pwd: str, kitsu_user: str, kitsu_pwd: str):
# ... (Manifest parsing and binary validation omitted) ...
env = os.environ.copy()
env["MACUARE_PROJECT_CONFIG"] = str(config_path)
# === ABSOLUTE ISOLATION (SANDBOX) ===
# Force the DCC to use a local, project-specific folder for all configs and extensions
sandbox_dir = project_root / "06_conf_LOCAL" / "blender_data"
sandbox_dir.mkdir(parents=True, exist_ok=True)
env["BLENDER_USER_RESOURCES"] = str(sandbox_dir)
# Inject RAM-secured credentials
env["MACUARE_SVN_USER"] = svn_user
env["MACUARE_SVN_PASSWORD"] = svn_pwd
env["KITSU_USER"] = kitsu_user
env["KITSU_PWD"] = kitsu_pwd
# Launch subprocess with the custom App Template
cmd = [str(blender_bin), "--app-template", template_name]
subprocess.Popen(cmd, env=env)
To prevent saving passwords on disk, the UI components intercept the launch action. If the RAM Vault is empty, execution pauses, prompts the user, stores the keys in volatile memory, and resumes automatically via callbacks.
def iniciar_proyecto_hilo(self, project_root: Path, config_path: Path):
# === JIT INTERCEPTOR FOR SECURE LAUNCH ===
if not self.vault.has_svn_credentials():
SVNLoginWindow(
parent=self.winfo_toplevel(),
vault_manager=self.vault,
on_success_callback=lambda: self.iniciar_proyecto_hilo(project_root, config_path)
)
return
# Extract full credentials strictly from RAM
svn_user, svn_pwd = self.vault.get_svn_credentials()
kitsu_user, kitsu_pwd = self.vault.get_kitsu_credentials()
threading.Thread(
target=lanzar_blender,
args=(project_root, config_path, svn_user, svn_pwd, kitsu_user, kitsu_pwd),
daemon=True
).start()
| Ernesto Del Valle Macuare | Pipeline TD & Tools Developer |
| 🔗 GitHub | 📧 edelvallemacuare@gmail.com |