Architecture

The Blender Development for PyCharm plugin is built as a set of services within the IntelliJ Platform.

Core Services

  • ``BlenderService``: The primary project-level facade. It coordinates all other services and provides a simplified API for common operations like starting Blender or reloading extensions.

  • ``BlenderDownloader``: An application-level service responsible for downloading and managing different Blender versions from download.blender.org.

  • ``BlenderLinker``: Manages the connection between your project code and Blender. It creates symbolic links (or directory junctions on Windows) in Blender’s extensions directory.

  • ``BlenderLauncher``: Handles the process execution of Blender, including setting up environment variables for sandboxing and configuring app templates.

  • ``BlenderCommunicationService``: A TCP server that listens for connections from the Blender instance and sends structured JSON commands (like reload).

  • ``BlenderScriptGenerator``: Generates the Python scripts that are injected into Blender at startup to initialize the communication and manage extensions.

  • ``BlenderLogger``: Provides consistent logging to both the IntelliJ platform log and the project-local blender_plugin.log.

  • ``BlenderTelemetryService``: Collects and logs local-only telemetry for debugging and stability monitoring.

  • ``PythonLinterService``: Manages the project’s virtual environment (VENV) and handles the installation of fake-bpy-module for linting.

Other Key Components

  • ``BlenderScanner``: Scans the system path and standard installation directories for already installed Blender versions. It uses version metadata caching for performance.

  • ``BlenderVersions``: Provides a centralized source of truth for supported Blender versions and their download URLs.

  • ``ExternalProcessUtil``: A utility class for safely executing external processes (like pip or venv creation) and capturing their output.

Hot-Reloading Protocol

The hot-reloading feature works through a TCP-based communication layer:

  1. Startup: When Blender starts, the plugin injects a startup script that starts a background thread in Blender.

  2. Heartbeat: Blender sends a “ready” signal upon startup to notify PyCharm that it is ready to receive commands.

  3. Connection: The Blender side connects to the TCP server started by BlenderCommunicationService. PyCharm utilizes a bidirectional heartbeat and retry logic (up to 5 attempts) to establish a stable connection.

  4. Trigger: When you save a file or use the reload action, PyCharm sends a structured JSON message: {"type": "reload", "name": "your_extension"}.

  5. Execution: Blender receives the message and schedules a reload task on the main thread using bpy.app.timers.

  6. Reload Cycle: - Disable: The extension is temporarily disabled. - Purge: All modules related to the extension are removed from Python’s sys.modules. - Refresh: A repository refresh (bpy.ops.extensions.repo_refresh_all()) is forced to ensure Blender sees any new files. The plugin uses a dedicated extension repository named blender_pycharm. - Enable: The extension is re-enabled, forcing a fresh import of the code.

Error Handling

Critical communication errors (e.g., connection failure, heartbeat timeout) are surfaced via IDE balloon notifications in addition to being logged in blender_plugin.log.

Sandboxing and Versioning

The plugin supports multiple Blender versions (4.2+ and 5.0/5.1) and uses the BLENDER_USER_CONFIG and BLENDER_USER_SCRIPTS environment variables to isolate the development environment. When sandboxing is enabled:

  • Configuration is stored in .venv/blender_sandbox/config.

  • Scripts and extensions are stored in .venv/blender_sandbox/scripts.

  • An app template named pycharm is created within the sandbox to provide a clean environment and a custom splash screen (copied from images/sandbox_splash.png if present).