Skip to content

Commit

Permalink
Support distributing as Blender extension (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
lasa01 committed Nov 7, 2024
1 parent 948af81 commit 7b6df38
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 98 deletions.
42 changes: 32 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ jobs:
strategy:
matrix:
os: [macos-13, macos-latest, windows-latest]
include:
- os: macos-13
blender-install: |
brew update
brew install --cask blender
filename-match: "dist/*-macos_x64.zip"
- os: macos-latest
blender-install: |
brew update
brew install --cask blender
filename-match: "dist/*-macos_arm64.zip"
- os: windows-latest
blender-install: |
choco install blender --version=4.2.2
echo "C:\Program Files\Blender Foundation\Blender 4.2\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
filename-match: "dist/*-windows_x64.zip"
fail-fast: false
runs-on: ${{ matrix.os }}

Expand All @@ -48,16 +64,17 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Build
run: python setup.py bdist_blender_addon
- name: Rename artifact
shell: bash
run: for filename in dist/*.zip; do mv "${filename}" "${filename%.zip}-${{ runner.os }}-${{ runner.arch }}.zip"; done;
run: python setup.py build_rust --inplace
- name: Install Blender
run: ${{ matrix.blender-install }}
- name: Package addon into Blender extension
run: blender --command extension build --source-dir plumber --output-dir dist --split-platforms
- name: Release
uses: softprops/action-gh-release@v2
with:
draft: true
fail_on_unmatched_files: true
files: dist/*.zip
files: ${{ matrix.filename-match }}

build-manylinux:
runs-on: ubuntu-latest
Expand All @@ -78,13 +95,18 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Build
run: python setup.py bdist_blender_addon
- name: Rename artifact
shell: bash
run: for filename in dist/*.zip; do mv "${filename}" "${filename%.zip}-${{ runner.os }}-${{ runner.arch }}.zip"; done;
run: python setup.py build_rust --inplace
- name: Install Blender
run: |
sudo dnf install -y wget tar xz
wget https://download.blender.org/release/Blender4.2/blender-4.2.3-linux-x64.tar.xz
tar -xf blender-4.2.3-linux-x64.tar.xz
echo "$PWD/blender-4.2.3-linux-x64" >> $GITHUB_PATH
- name: Package addon into Blender extension
run: blender --command extension build --source-dir plumber --output-dir dist --split-platforms
- name: Release
uses: softprops/action-gh-release@v2
with:
draft: true
fail_on_unmatched_files: true
files: dist/*.zip
files: "dist/*-linux_x64.zip"
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "plumber"
version = "1.1.1"
version = "1.1.1-extensiontest"
authors = ["Lassi Säike"]
edition = "2021"

Expand Down
115 changes: 45 additions & 70 deletions plumber/__init__.py
Original file line number Diff line number Diff line change
@@ -1,73 +1,48 @@
import platform
import os

bl_info = {
"name": "Plumber",
"author": "Lassi Säike",
"version": (1, 1, 1),
"blender": (2, 90, 0),
"location": "File > Import -> Plumber",
"description": "Imports Source Engine assets.",
"warning": "",
"tracker_url": "https://github.com/lasa01/plumber",
"category": "Import-Export",
}

version = bl_info["version"]
version_pre = bl_info["warning"]

version_str = ".".join(map(str, version))

if version_pre != "":
version_str += f"-{version_pre}"

# check if imported by setup.py or actually running in Blender
try:
from bpy.app import version as bpy_version
except ImportError:
bpy_version = None

if bpy_version is not None:
is_windows = platform.system() == "Windows"

def register():
if is_windows:
# Check if the extension module was renamed on the last unregister,
# and either rename it back or delete it if the addon was updated with a newer extension module
ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd")
unloaded_ext_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded"
)

if os.path.isfile(unloaded_ext_path):
if os.path.isfile(ext_path):
try:
os.remove(unloaded_ext_path)
except OSError:
print(
"[Plumber] [WARN] old files remaining, restart Blender to finish post-update clean up"
)
else:
os.rename(unloaded_ext_path, ext_path)

from . import addon

addon.register()

def unregister():
from . import addon

addon.unregister()

if is_windows:
# Rename the extension module to allow updating the addon without restarting Blender,
# since the extension module will stay open and can't be overwritten even if the addon is unloaded
ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd")
unloaded_ext_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded"
)

try:
os.rename(ext_path, unloaded_ext_path)
except OSError:
pass
is_windows = platform.system() == "Windows"


def register():
if is_windows:
# Check if the extension module was renamed on the last unregister,
# and either rename it back or delete it if the addon was updated with a newer extension module
ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd")
unloaded_ext_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded"
)

if os.path.isfile(unloaded_ext_path):
if os.path.isfile(ext_path):
try:
os.remove(unloaded_ext_path)
except OSError:
print(
"[Plumber] [WARN] old files remaining, restart Blender to finish post-update clean up"
)
else:
os.rename(unloaded_ext_path, ext_path)

from . import addon

addon.register()


def unregister():
from . import addon

addon.unregister()

if is_windows:
# Rename the extension module to allow updating the addon without restarting Blender,
# since the extension module will stay open and can't be overwritten even if the addon is unloaded
ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd")
unloaded_ext_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded"
)

try:
os.rename(ext_path, unloaded_ext_path)
except OSError:
pass
11 changes: 1 addition & 10 deletions plumber/addon.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import bpy
from bpy.types import Context, Menu

from . import preferences, importer, tools, benchmark, version_str
from . import preferences, importer, tools, benchmark
from .importer import ImportMdl, ImportVmf, ImportVmt, ImportVtf
from .tools import IMPORT_MT_plumber_browse

Expand Down Expand Up @@ -32,15 +32,6 @@ def menu_func_import(self: Menu, context: Context):


def register():
from . import plumber

rust_version = plumber.version()
if rust_version != version_str:
raise Exception(
f"Native code version {rust_version} does not match Python code version {version_str}. "
+ "Please restart Blender and reinstall the addon."
)

preferences.register()
importer.register()
tools.register()
Expand Down
19 changes: 19 additions & 0 deletions plumber/blender_manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
schema_version = "1.0.0"

id = "plumber"
version = "1.1.1-extensiontest"
name = "Plumber"
tagline = "Imports Source 1 engine maps, models, materials and textures"
maintainer = "Lassi Säike <[email protected]>"
type = "add-on"
website = "https://github.com/lasa01/Plumber"
tags = ["Import-Export"]
blender_version_min = "4.2.0"
license = ["SPDX:GPL-3.0-or-later"]
platforms = ["windows-x64", "macos-x64", "macos-arm64", "linux-x64"]

[permissions]
files = "Import/extract assets from/to disk, detect installed games"

[build]
paths_exclude_pattern = ["__pycache__/", "/.git/", "/*.zip", "/*.pyi"]
4 changes: 2 additions & 2 deletions plumber/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class AddonPreferences(AddonPreferences):
)

def update_enable_file_browser_panel(self, context: Context):
from plumber.tools import GameFileBrowserPanel
from .tools import GameFileBrowserPanel

if not self.enable_file_browser_panel:
bpy.utils.unregister_class(GameFileBrowserPanel)
Expand All @@ -392,7 +392,7 @@ def update_enable_file_browser_panel(self, context: Context):
)

def update_enable_benchmarking(self, context: Context):
from plumber.benchmark import BenchmarkVmf
from .benchmark import BenchmarkVmf

if not self.enable_benchmarking:
bpy.utils.unregister_class(BenchmarkVmf)
Expand Down
2 changes: 1 addition & 1 deletion plumber/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
)
import bpy

from plumber.importer import (
from .importer import (
DisableCommonPanel,
GameFileImporterOperator,
GameFileImporterOperatorProps,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[build-system]
requires = ["setuptools", "setuptools-rust", "blender.distutils"]
requires = ["setuptools", "setuptools-rust", "blender.distutils", "toml"]
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ setuptools
setuptools-rust
blender.distutils
black
toml
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from setuptools import setup, find_packages, sic
from setuptools_rust import Binding, RustExtension
import toml

from plumber import version_str
with open("plumber/blender_manifest.toml", "r") as f:
manifest = toml.load(f)

version_str = manifest["version"]

rust_extension = RustExtension(
"plumber.plumber",
Expand Down
6 changes: 5 additions & 1 deletion setup_trace.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from setuptools import setup, find_packages, sic
from setuptools_rust import Binding, RustExtension
import toml

from plumber import version_str
with open("plumber/blender_manifest.toml", "r") as f:
manifest = toml.load(f)

version_str = manifest["version"]

rust_extension = RustExtension(
"plumber.plumber",
Expand Down

0 comments on commit 7b6df38

Please sign in to comment.