Add quick integration with minecraft-render

This commit is contained in:
object-Object 2023-10-29 17:29:41 -04:00
parent 7d179e0f22
commit 511daaac63
3 changed files with 88 additions and 13 deletions

View file

@ -1,3 +1,4 @@
import base64
import json
import logging
import os
@ -7,6 +8,15 @@ from pathlib import Path
from typing import Annotated, Union
import typer
from minecraft_render import (
IPythonResourceLoader,
MinecraftAssetsLoader,
PythonLoaderWrapper,
RenderClass,
ResourcePath,
createMultiloader,
resourcePathAsString,
)
from hexdoc.core.loader import ModResourceLoader
from hexdoc.core.resource import ResourceLocation
@ -48,6 +58,40 @@ def list_langs(
print(json.dumps(langs))
@app.command()
def render_block(
block: str,
props_file: PathArgument = DEFAULT_PROPS_FILE,
*,
verbosity: VerbosityOption = 0,
):
"""Render a 3D image of a block."""
props, pm, _ = load_common_data(props_file, verbosity)
with ModResourceLoader.load_all(props, pm, export=False) as loader:
class HexdocPythonResourceLoader(IPythonResourceLoader):
def loadJSON(self, resource_path: ResourcePath) -> str:
path = "assets" / Path(resourcePathAsString(resource_path))
return loader.load_resource(path, decode=lambda v: v)[1]
def loadTexture(self, resource_path: ResourcePath) -> str:
path = "assets" / Path(resourcePathAsString(resource_path))
_, resolved_path = loader.find_resource(path)
with open(resolved_path, "rb") as f:
return base64.b64encode(f.read()).decode()
render_loader = createMultiloader(
PythonLoaderWrapper(HexdocPythonResourceLoader()),
MinecraftAssetsLoader.fetchAll(
props.minecraft_assets.ref,
props.minecraft_assets.version,
),
)
renderer = RenderClass(render_loader, {"outDir": "out"})
output_path = renderer.renderToFile(block)
print(f"Rendered: {output_path}")
@app.command()
def export(
props_file: PathArgument = DEFAULT_PROPS_FILE,

View file

@ -185,14 +185,50 @@ class ModResourceLoader:
...
def load_resource(
self,
*args: Any,
decode: Callable[[str], _T] = decode_json_dict,
export: ExportFn[_T] | Literal[False] | None = None,
**kwargs: Any,
) -> tuple[PathResourceDir, _T]:
"""Find the first file with this resource location in `resource_dirs`.
If no file extension is provided, `.json` is assumed.
Raises FileNotFoundError if the file does not exist.
"""
resource_dir, path = self.find_resource(*args, **kwargs)
return resource_dir, self._load_path(
resource_dir,
path,
decode=decode,
export=export,
)
@overload
def find_resource(
self,
type: ResourceType,
folder: str | Path,
id: ResourceLocation,
) -> tuple[PathResourceDir, Path]:
...
@overload
def find_resource(
self,
path: Path,
/,
) -> tuple[PathResourceDir, Path]:
...
def find_resource(
self,
type: ResourceType | Path,
folder: str | Path | None = None,
id: ResourceLocation | None = None,
*,
decode: Callable[[str], _T] = decode_json_dict,
export: ExportFn[_T] | Literal[False] | None = None,
) -> tuple[PathResourceDir, _T]:
) -> tuple[PathResourceDir, Path]:
"""Find the first file with this resource location in `resource_dirs`.
If no file extension is provided, `.json` is assumed.
@ -208,15 +244,9 @@ class ModResourceLoader:
# check by descending priority, return the first that exists
for resource_dir in self.resource_dirs:
try:
return resource_dir, self._load_path(
resource_dir,
resource_dir.path / path_stub,
decode=decode,
export=export,
)
except FileNotFoundError:
continue
path = resource_dir.path / path_stub
if path.is_file():
return resource_dir, path
raise FileNotFoundError(f"Path {path_stub} not found in any resource dir")

View file

@ -49,6 +49,7 @@ dependencies = [
"typer[all]~=0.9.0",
"requests~=2.31",
"ordered-set~=4.1",
"minecraft-render~=2.0",
]
dynamic = ["version"]