mirror of https://github.com/wanadev/yoga.git
Adds black; reformat the yoga module
This commit is contained in:
parent
1e3fd63c57
commit
4b6b84b8a3
13
noxfile.py
13
noxfile.py
|
@ -1,10 +1,19 @@
|
|||
import nox
|
||||
|
||||
|
||||
PYTHON_FILES = [
|
||||
"yoga",
|
||||
"test",
|
||||
"setup.py",
|
||||
"noxfile.py",
|
||||
]
|
||||
|
||||
|
||||
@nox.session
|
||||
def lint(session):
|
||||
session.install("flake8")
|
||||
session.run("flake8", "yoga", "test", "noxfile.py")
|
||||
session.install("flake8", "black")
|
||||
session.run("flake8", *PYTHON_FILES)
|
||||
session.run("black", "--line-length=79", "--check", *PYTHON_FILES)
|
||||
|
||||
|
||||
@nox.session(python=["2.7", "3.5", "3.6", "3.7", "3.8", "3.9"])
|
||||
|
|
73
setup.py
73
setup.py
|
@ -12,14 +12,16 @@ from setuptools.command.build_py import build_py
|
|||
def _find_msbuild(plat_spec="x64"):
|
||||
# https://github.com/python/cpython/blob/master/Lib/distutils/_msvccompiler.py
|
||||
import distutils._msvccompiler as msvc
|
||||
|
||||
vc_env = msvc._get_vc_env(plat_spec)
|
||||
if "vsinstalldir" not in vc_env:
|
||||
raise Exception("Unable to find any Visual Studio installation")
|
||||
return os.path.join(vc_env["vsinstalldir"], "MSBuild", "Current", "Bin", "MSBuild.exe") # noqa
|
||||
return os.path.join(
|
||||
vc_env["vsinstalldir"], "MSBuild", "Current", "Bin", "MSBuild.exe"
|
||||
)
|
||||
|
||||
|
||||
class CustomBuildPy(build_py):
|
||||
|
||||
def run(self):
|
||||
if not os.path.isdir("./assimp/build"):
|
||||
os.mkdir("./assimp/build")
|
||||
|
@ -28,29 +30,33 @@ class CustomBuildPy(build_py):
|
|||
|
||||
if ccompiler.get_default_compiler() == "unix":
|
||||
os.environ["CPPFLAGS"] = "--std=c++11"
|
||||
subprocess.call([
|
||||
"cmake", "..",
|
||||
"-DBUILD_SHARED_LIBS=OFF",
|
||||
"-DASSIMP_BUILD_ASSIMP_TOOLS=OFF",
|
||||
"-DASSIMP_BUILD_TESTS=OFF",
|
||||
"-DASSIMP_BUILD_ZLIB=ON",
|
||||
])
|
||||
subprocess.call(
|
||||
[
|
||||
"cmake",
|
||||
"..",
|
||||
"-DBUILD_SHARED_LIBS=OFF",
|
||||
"-DASSIMP_BUILD_ASSIMP_TOOLS=OFF",
|
||||
"-DASSIMP_BUILD_TESTS=OFF",
|
||||
"-DASSIMP_BUILD_ZLIB=ON",
|
||||
]
|
||||
)
|
||||
subprocess.call(["make"])
|
||||
elif ccompiler.get_default_compiler() == "msvc":
|
||||
msbuild = _find_msbuild()
|
||||
subprocess.call([
|
||||
"cmake", "..",
|
||||
"-DBUILD_SHARED_LIBS=OFF",
|
||||
"-DASSIMP_BUILD_ASSIMP_TOOLS=OFF",
|
||||
"-DASSIMP_BUILD_TESTS=OFF",
|
||||
"-DASSIMP_BUILD_ZLIB=ON",
|
||||
"-DLIBRARY_SUFFIX=",
|
||||
])
|
||||
subprocess.call([
|
||||
msbuild,
|
||||
"-p:Configuration=Release",
|
||||
"Assimp.sln"
|
||||
])
|
||||
subprocess.call(
|
||||
[
|
||||
"cmake",
|
||||
"..",
|
||||
"-DBUILD_SHARED_LIBS=OFF",
|
||||
"-DASSIMP_BUILD_ASSIMP_TOOLS=OFF",
|
||||
"-DASSIMP_BUILD_TESTS=OFF",
|
||||
"-DASSIMP_BUILD_ZLIB=ON",
|
||||
"-DLIBRARY_SUFFIX=",
|
||||
]
|
||||
)
|
||||
subprocess.call(
|
||||
[msbuild, "-p:Configuration=Release", "Assimp.sln"]
|
||||
)
|
||||
else:
|
||||
raise Exception("Unhandled platform")
|
||||
|
||||
|
@ -70,24 +76,20 @@ setup(
|
|||
description="Yummy Optimizer for Gorgeous Assets",
|
||||
url="https://github.com/wanadev/yoga",
|
||||
license="BSD-3-Clause",
|
||||
|
||||
long_description=long_description,
|
||||
keywords="image jpeg png optimizer guetzli zopfli 3d model mesh assimp gltf glb converter", # noqa
|
||||
|
||||
author="Wanadev",
|
||||
author_email="contact@wanadev.fr",
|
||||
maintainer="Fabien LOISON, Alexis BREUST",
|
||||
|
||||
packages=find_packages(),
|
||||
|
||||
setup_requires=["cffi>=1.0.0"],
|
||||
install_requires=[
|
||||
"cffi>=1.0.0",
|
||||
"pillow>=6.2.2",
|
||||
"pyguetzli>=1.0.0",
|
||||
"unidecode>=1.0.0",
|
||||
"zopflipy>=1.0"
|
||||
],
|
||||
"zopflipy>=1.0",
|
||||
],
|
||||
extras_require={
|
||||
"dev": [
|
||||
"nox",
|
||||
|
@ -95,16 +97,15 @@ setup(
|
|||
"pytest",
|
||||
"Sphinx",
|
||||
"sphinx-rtd-theme",
|
||||
]},
|
||||
|
||||
]
|
||||
},
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"yoga = yoga.__main__:main"
|
||||
]},
|
||||
|
||||
"yoga = yoga.__main__:main",
|
||||
]
|
||||
},
|
||||
cffi_modules=["yoga/model/assimp_build.py:ffibuilder"],
|
||||
|
||||
cmdclass={
|
||||
"build_py": CustomBuildPy,
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
|
@ -14,8 +14,8 @@ def main():
|
|||
args.output,
|
||||
options=vars(args),
|
||||
verbose=args.verbose,
|
||||
quiet=args.quiet
|
||||
)
|
||||
quiet=args.quiet,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
54
yoga/cli.py
54
yoga/cli.py
|
@ -15,32 +15,36 @@ def _type_path(mode, string):
|
|||
path = os.path.dirname(os.path.abspath(string))
|
||||
if os.access(path, mode):
|
||||
return string
|
||||
raise argparse.ArgumentTypeError("the '%s' folder does not exist" % path) # noqa
|
||||
raise argparse.ArgumentTypeError(
|
||||
"the '%s' folder does not exist" % path
|
||||
)
|
||||
|
||||
|
||||
def add_main_cli_arguments(parser):
|
||||
parser.add_argument(
|
||||
"input",
|
||||
help="Input file path",
|
||||
type=partial(_type_path, os.R_OK)
|
||||
)
|
||||
"input",
|
||||
help="Input file path",
|
||||
type=partial(_type_path, os.R_OK),
|
||||
)
|
||||
parser.add_argument(
|
||||
"output",
|
||||
help="Output file path",
|
||||
type=partial(_type_path, os.W_OK)
|
||||
)
|
||||
"output",
|
||||
help="Output file path",
|
||||
type=partial(_type_path, os.W_OK),
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--verbose",
|
||||
help="enable verbose mode",
|
||||
default=False,
|
||||
action="store_true"
|
||||
)
|
||||
"-v",
|
||||
"--verbose",
|
||||
help="enable verbose mode",
|
||||
default=False,
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q", "--quiet",
|
||||
help="enable quiet mode (takes precedence over verbose)",
|
||||
default=False,
|
||||
action="store_true"
|
||||
)
|
||||
"-q",
|
||||
"--quiet",
|
||||
help="enable quiet mode (takes precedence over verbose)",
|
||||
default=False,
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
|
||||
def generate_image_cli(parser=None):
|
||||
|
@ -67,15 +71,15 @@ def generate_main_cli():
|
|||
subparsers = parser.add_subparsers(dest="subcommand")
|
||||
|
||||
image_parser = subparsers.add_parser(
|
||||
"image",
|
||||
help="Converts and optimizes images"
|
||||
)
|
||||
"image",
|
||||
help="Converts and optimizes images",
|
||||
)
|
||||
generate_image_cli(image_parser)
|
||||
|
||||
model_parser = subparsers.add_parser(
|
||||
"model",
|
||||
help="Converts and optimizes 3D models"
|
||||
)
|
||||
"model",
|
||||
help="Converts and optimizes 3D models",
|
||||
)
|
||||
generate_model_cli(model_parser)
|
||||
|
||||
return parser
|
||||
|
|
|
@ -146,8 +146,13 @@ def optimize(input_file, output_file, options={}, verbose=False, quiet=False):
|
|||
|
||||
image = Image.open(input_file)
|
||||
|
||||
if options["output_format"] == "orig" and image.format not in ("JPEG", "PNG"): # noqa
|
||||
raise ValueError("The input image must be a JPEG or a PNG when setting 'output_format' to 'orig'") # noqa
|
||||
if options["output_format"] == "orig" and image.format not in (
|
||||
"JPEG",
|
||||
"PNG",
|
||||
):
|
||||
raise ValueError(
|
||||
"The input image must be a JPEG or a PNG when setting 'output_format' to 'orig'" # noqa: E501
|
||||
)
|
||||
|
||||
# resize
|
||||
if options["resize"] != "orig":
|
||||
|
@ -172,7 +177,8 @@ def optimize(input_file, output_file, options={}, verbose=False, quiet=False):
|
|||
output_image_bytes = None
|
||||
if output_format == "jpeg":
|
||||
output_image_bytes = pyguetzli.process_pil_image(
|
||||
image, int(options["jpeg_quality"] * 100))
|
||||
image, int(options["jpeg_quality"] * 100)
|
||||
)
|
||||
else:
|
||||
image_io = io.BytesIO()
|
||||
image.save(image_io, format="PNG", optimize=False)
|
||||
|
|
|
@ -12,8 +12,10 @@ def _type_resize(string):
|
|||
return string
|
||||
if _RESIZE_OPTION_REGEXP.match(string):
|
||||
return string
|
||||
message = ("invalid format: '%s' (valid formats are "
|
||||
"'orig', <SIZE>, <WIDTH>x<HEIGHT>)") % string
|
||||
message = (
|
||||
"invalid format: '%s' (valid formats are "
|
||||
"'orig', <SIZE>, <WIDTH>x<HEIGHT>)"
|
||||
) % string
|
||||
raise argparse.ArgumentTypeError(message)
|
||||
|
||||
|
||||
|
@ -27,36 +29,39 @@ def _type_range(min_, max_, string):
|
|||
if min_ <= value <= max_:
|
||||
return value
|
||||
message = "number not in range: '%s' (range is [%i-%i])" % (
|
||||
string, min_, max_)
|
||||
string,
|
||||
min_,
|
||||
max_,
|
||||
)
|
||||
raise argparse.ArgumentTypeError(message)
|
||||
|
||||
|
||||
def add_image_cli_options(parser, prefix=""):
|
||||
parser.add_argument(
|
||||
"--%soutput-format" % prefix,
|
||||
help="format of the output image",
|
||||
metavar="{orig,auto,jpeg,png}",
|
||||
choices=["orig", "auto", "jpeg", "jpg", "png"],
|
||||
default=DEFAULT_OPTIONS["output_format"]
|
||||
)
|
||||
"--%soutput-format" % prefix,
|
||||
help="format of the output image",
|
||||
metavar="{orig,auto,jpeg,png}",
|
||||
choices=["orig", "auto", "jpeg", "jpg", "png"],
|
||||
default=DEFAULT_OPTIONS["output_format"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--%sresize" % prefix,
|
||||
help="resize the image",
|
||||
metavar="{orig,<SIZE>,<WIDTH>x<HEIGHT>}",
|
||||
type=_type_resize,
|
||||
default=DEFAULT_OPTIONS["resize"]
|
||||
)
|
||||
"--%sresize" % prefix,
|
||||
help="resize the image",
|
||||
metavar="{orig,<SIZE>,<WIDTH>x<HEIGHT>}",
|
||||
type=_type_resize,
|
||||
default=DEFAULT_OPTIONS["resize"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--%sjpeg-quality" % prefix,
|
||||
help="JPEG quality if the output format is set to 'jpeg'",
|
||||
metavar="0-100",
|
||||
type=partial(_type_range, 0, 100),
|
||||
default=DEFAULT_OPTIONS["jpeg_quality"]
|
||||
)
|
||||
"--%sjpeg-quality" % prefix,
|
||||
help="JPEG quality if the output format is set to 'jpeg'",
|
||||
metavar="0-100",
|
||||
type=partial(_type_range, 0, 100),
|
||||
default=DEFAULT_OPTIONS["jpeg_quality"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--%sopacity-threshold" % prefix,
|
||||
help="threshold below which a pixel is considered transparent",
|
||||
metavar="0-255",
|
||||
type=partial(_type_range, 0, 255),
|
||||
default=DEFAULT_OPTIONS["opacity_threshold"]
|
||||
)
|
||||
"--%sopacity-threshold" % prefix,
|
||||
help="threshold below which a pixel is considered transparent",
|
||||
metavar="0-255",
|
||||
type=partial(_type_range, 0, 255),
|
||||
default=DEFAULT_OPTIONS["opacity_threshold"],
|
||||
)
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import re
|
||||
|
||||
|
||||
# fmt: off
|
||||
DEFAULT_OPTIONS = {
|
||||
"output_format": "orig", # orig|auto|jpeg|png
|
||||
"resize": "orig", # orig|[w,h]
|
||||
"jpeg_quality": 0.84, # 0.00-1.00
|
||||
"opacity_threshold": 254 # 0-255
|
||||
}
|
||||
"output_format": "orig", # orig|auto|jpeg|png
|
||||
"resize": "orig", # orig|[w,h]
|
||||
"jpeg_quality": 0.84, # 0.00-1.00
|
||||
"opacity_threshold": 254 # 0-255
|
||||
}
|
||||
# fmt: on
|
||||
|
||||
|
||||
_RESIZE_OPTION_REGEXP = re.compile(
|
||||
r"^([0-9]+)[x\s:,;]([0-9]+)$", flags=re.IGNORECASE)
|
||||
r"^([0-9]+)[x\s:,;]([0-9]+)$", flags=re.IGNORECASE
|
||||
)
|
||||
|
||||
|
||||
def normalize_options(options=None):
|
||||
|
@ -28,7 +31,7 @@ def normalize_options(options=None):
|
|||
value = "jpeg"
|
||||
|
||||
if value not in ("orig", "auto", "jpeg", "png"):
|
||||
raise ValueError("Invalid value for 'output_format': '%s'" % value) # noqa
|
||||
raise ValueError("Invalid value for 'output_format': '%s'" % value)
|
||||
|
||||
result["output_format"] = value
|
||||
|
||||
|
@ -55,9 +58,9 @@ def normalize_options(options=None):
|
|||
elif _RESIZE_OPTION_REGEXP.match(value):
|
||||
match = _RESIZE_OPTION_REGEXP.match(value)
|
||||
value = [
|
||||
int(match.group(1)),
|
||||
int(match.group(2)),
|
||||
]
|
||||
int(match.group(1)),
|
||||
int(match.group(2)),
|
||||
]
|
||||
elif value != "orig":
|
||||
raise ValueError("Invalid value for 'resize': %s" % value)
|
||||
|
||||
|
|
|
@ -146,13 +146,19 @@ API
|
|||
import sys
|
||||
import os.path
|
||||
|
||||
from .assimp import (assimp_import_from_bytes, assimp_export_to_bytes)
|
||||
from .options import (normalize_options, extract_image_options)
|
||||
from .assimp import assimp_import_from_bytes, assimp_export_to_bytes
|
||||
from .options import normalize_options, extract_image_options
|
||||
from .helpers import model_embed_images
|
||||
|
||||
|
||||
def optimize(input_file, output_file, options={}, textures=None,
|
||||
verbose=False, quiet=False):
|
||||
def optimize(
|
||||
input_file,
|
||||
output_file,
|
||||
options={},
|
||||
textures=None,
|
||||
verbose=False,
|
||||
quiet=False,
|
||||
):
|
||||
"""Optimize given model.
|
||||
|
||||
:param str,file-like input_file: The input model file.
|
||||
|
@ -201,8 +207,8 @@ def optimize(input_file, output_file, options={}, textures=None,
|
|||
input_file,
|
||||
not model_options["no_graph_optimization"],
|
||||
not model_options["no_meshes_optimization"],
|
||||
verbose
|
||||
)
|
||||
verbose,
|
||||
)
|
||||
|
||||
# Embed images
|
||||
# @note We save the bytes to a dictionnary so that the garbage collector
|
||||
|
@ -216,14 +222,14 @@ def optimize(input_file, output_file, options={}, textures=None,
|
|||
root_path,
|
||||
image_options,
|
||||
textures,
|
||||
quiet
|
||||
)
|
||||
quiet,
|
||||
)
|
||||
|
||||
# Export the scene
|
||||
bytes_out = assimp_export_to_bytes(
|
||||
scene["cffi_pointer"],
|
||||
model_options["output_format"]
|
||||
)
|
||||
model_options["output_format"],
|
||||
)
|
||||
|
||||
# Write to output
|
||||
if not hasattr(output_file, "write"):
|
||||
|
|
|
@ -7,11 +7,8 @@ from ._assimp import lib, ffi
|
|||
|
||||
|
||||
def assimp_import_from_bytes(
|
||||
bytes_in,
|
||||
optimize_graph,
|
||||
optimize_meshes,
|
||||
verbose
|
||||
):
|
||||
bytes_in, optimize_graph, optimize_meshes, verbose
|
||||
):
|
||||
"""Generates an abstract 3D scene from a model file's bytes.
|
||||
:param bytes_in: the input model's bytes
|
||||
:param optimize_graph: whether the graph scene should be optimized
|
||||
|
@ -29,7 +26,7 @@ def assimp_import_from_bytes(
|
|||
|
||||
scene = {
|
||||
"cffi_pointer": None,
|
||||
"cffi_gc": None
|
||||
"cffi_gc": None,
|
||||
}
|
||||
scene["cffi_pointer"] = ffi.new("Scene*")
|
||||
scene["cffi_gc"] = ffi.gc(scene["cffi_pointer"], lib.assimp_free_scene)
|
||||
|
@ -39,11 +36,13 @@ def assimp_import_from_bytes(
|
|||
len(bytes_in),
|
||||
optimization_flags,
|
||||
scene["cffi_pointer"],
|
||||
verbose
|
||||
)
|
||||
verbose,
|
||||
)
|
||||
|
||||
if scene["cffi_pointer"].assimp_scene == ffi.NULL:
|
||||
raise ValueError("Invalid model: Assimp was not able to import the model") # noqa
|
||||
raise ValueError(
|
||||
"Invalid model: Assimp was not able to import the model"
|
||||
)
|
||||
|
||||
return scene
|
||||
|
||||
|
@ -58,21 +57,24 @@ def assimp_export_to_bytes(scene_p, output_format):
|
|||
"""
|
||||
|
||||
if output_format not in ("glb", "gltf"):
|
||||
raise ValueError("Invalid output format: should be glb or gltf but is %s" % output_format) # noqa
|
||||
raise ValueError(
|
||||
"Invalid output format: should be glb or gltf but is %s"
|
||||
% output_format
|
||||
)
|
||||
|
||||
output_format_dict = dict({
|
||||
output_format_dict = dict(
|
||||
{
|
||||
"glb": lib.OUTPUT_FORMAT_GLB,
|
||||
"gltf": lib.OUTPUT_FORMAT_GLTF
|
||||
})
|
||||
"gltf": lib.OUTPUT_FORMAT_GLTF,
|
||||
}
|
||||
)
|
||||
|
||||
bytes_out_p = ffi.new("char**")
|
||||
bytes_out_p_gc = ffi.gc(bytes_out_p, lib.assimp_free_bytes)
|
||||
|
||||
length = lib.assimp_export_to_bytes(
|
||||
scene_p,
|
||||
output_format_dict[output_format],
|
||||
bytes_out_p
|
||||
)
|
||||
scene_p, output_format_dict[output_format], bytes_out_p
|
||||
)
|
||||
|
||||
if length == 0:
|
||||
raise ValueError("Invalid model: Assimp was not able to export")
|
||||
|
|
|
@ -15,14 +15,33 @@ _LIB_ZLIB = None
|
|||
|
||||
if ccompiler.get_default_compiler() == "unix":
|
||||
# Default libs path for Unix systems
|
||||
_LIB_ASSIMP = os.path.join(_ROOT, "..", "..", "assimp", "build", "lib", "libassimp.a") # noqa
|
||||
_LIB_IRRXML = os.path.join(_ROOT, "..", "..", "assimp", "build", "lib", "libIrrXML.a") # noqa
|
||||
_LIB_ZLIB = os.path.join(_ROOT, "..", "..", "assimp", "build", "lib", "libzlibstatic.a") # noqa
|
||||
_LIB_ASSIMP = os.path.join(
|
||||
_ROOT, "..", "..", "assimp", "build", "lib", "libassimp.a"
|
||||
)
|
||||
_LIB_IRRXML = os.path.join(
|
||||
_ROOT, "..", "..", "assimp", "build", "lib", "libIrrXML.a"
|
||||
)
|
||||
_LIB_ZLIB = os.path.join(
|
||||
_ROOT, "..", "..", "assimp", "build", "lib", "libzlibstatic.a"
|
||||
)
|
||||
elif ccompiler.get_default_compiler() == "msvc":
|
||||
# Default libs path for Windows
|
||||
_LIB_ASSIMP = os.path.join(_ROOT, "..", "..", "assimp", "build", "lib", "Release", "assimp.lib") # noqa
|
||||
_LIB_IRRXML = os.path.join(_ROOT, "..", "..", "assimp", "build", "lib", "Release", "IrrXML.lib") # noqa
|
||||
_LIB_ZLIB = os.path.join(_ROOT, "..", "..", "assimp", "build", "lib", "Release", "zlibstatic.lib") # noqa
|
||||
_LIB_ASSIMP = os.path.join(
|
||||
_ROOT, "..", "..", "assimp", "build", "lib", "Release", "assimp.lib"
|
||||
)
|
||||
_LIB_IRRXML = os.path.join(
|
||||
_ROOT, "..", "..", "assimp", "build", "lib", "Release", "IrrXML.lib"
|
||||
)
|
||||
_LIB_ZLIB = os.path.join(
|
||||
_ROOT,
|
||||
"..",
|
||||
"..",
|
||||
"assimp",
|
||||
"build",
|
||||
"lib",
|
||||
"Release",
|
||||
"zlibstatic.lib",
|
||||
)
|
||||
|
||||
# Allow to override path through env vars
|
||||
if "YOGA_BUILD_LIB_ASSIMP" in os.environ:
|
||||
|
@ -33,25 +52,31 @@ if "YOGA_BUILD_LIB_ZLIB" in os.environ:
|
|||
_LIB_ZLIB = os.environ["YOGA_BUILD_LIB_ZLIB"]
|
||||
|
||||
if not _LIB_ASSIMP:
|
||||
raise Exception("Please provide the path to the assimp library using the YOGA_BUILD_LIB_ASSIMP environment variable") # noqa
|
||||
raise Exception(
|
||||
"Please provide the path to the assimp library using the YOGA_BUILD_LIB_ASSIMP environment variable" # noqa: E501
|
||||
)
|
||||
if not _LIB_IRRXML:
|
||||
raise Exception("Please provide the path to the IrrXML library using the YOGA_BUILD_LIB_IRRXML environment variable") # noqa
|
||||
raise Exception(
|
||||
"Please provide the path to the IrrXML library using the YOGA_BUILD_LIB_IRRXML environment variable" # noqa: E501
|
||||
)
|
||||
if not _LIB_ZLIB:
|
||||
raise Exception("Please provide the path to the zlib library using the YOGA_BUILD_LIB_ZLIB environment variable") # noqa
|
||||
raise Exception(
|
||||
"Please provide the path to the zlib library using the YOGA_BUILD_LIB_ZLIB environment variable" # noqa: E501
|
||||
)
|
||||
|
||||
|
||||
ffibuilder = FFI()
|
||||
ffibuilder.set_source(
|
||||
"yoga.model._assimp",
|
||||
open(_ASSIMP_CPP, "r").read(),
|
||||
extra_objects=[_LIB_ASSIMP, _LIB_IRRXML, _LIB_ZLIB],
|
||||
include_dirs=[
|
||||
_ROOT,
|
||||
os.path.join(_ROOT, "..", "..", "assimp", "include"),
|
||||
os.path.join(_ROOT, "..", "..", "assimp", "build", "include")
|
||||
],
|
||||
source_extension=".cpp"
|
||||
)
|
||||
"yoga.model._assimp",
|
||||
open(_ASSIMP_CPP, "r").read(),
|
||||
extra_objects=[_LIB_ASSIMP, _LIB_IRRXML, _LIB_ZLIB],
|
||||
include_dirs=[
|
||||
_ROOT,
|
||||
os.path.join(_ROOT, "..", "..", "assimp", "include"),
|
||||
os.path.join(_ROOT, "..", "..", "assimp", "build", "include"),
|
||||
],
|
||||
source_extension=".cpp",
|
||||
)
|
||||
ffibuilder.cdef(open(_ASSIMP_H, "r").read())
|
||||
|
||||
|
||||
|
|
|
@ -5,34 +5,35 @@ from .options import DEFAULT_OPTIONS
|
|||
|
||||
def add_model_cli_options(parser):
|
||||
parser.add_argument(
|
||||
"--output-format",
|
||||
help="format of the output model (default: %s)" % DEFAULT_OPTIONS["output_format"], # noqa
|
||||
metavar="{glb,gltf}",
|
||||
choices=["glb", "gltf"],
|
||||
default=DEFAULT_OPTIONS["output_format"]
|
||||
)
|
||||
"--output-format",
|
||||
help="format of the output model (default: %s)"
|
||||
% DEFAULT_OPTIONS["output_format"],
|
||||
metavar="{glb,gltf}",
|
||||
choices=["glb", "gltf"],
|
||||
default=DEFAULT_OPTIONS["output_format"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--fallback-texture",
|
||||
help="fallback image used when unable to find a texture",
|
||||
metavar="<PATH>",
|
||||
default=DEFAULT_OPTIONS["fallback_texture"],
|
||||
type=argparse.FileType("rb")
|
||||
)
|
||||
"--fallback-texture",
|
||||
help="fallback image used when unable to find a texture",
|
||||
metavar="<PATH>",
|
||||
default=DEFAULT_OPTIONS["fallback_texture"],
|
||||
type=argparse.FileType("rb"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-graph-optimization",
|
||||
help="disable empty graph nodes merging",
|
||||
default=DEFAULT_OPTIONS["no_graph_optimization"],
|
||||
action="store_true"
|
||||
)
|
||||
"--no-graph-optimization",
|
||||
help="disable empty graph nodes merging",
|
||||
default=DEFAULT_OPTIONS["no_graph_optimization"],
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-meshes-optimization",
|
||||
help="disable meshes optimization",
|
||||
default=DEFAULT_OPTIONS["no_meshes_optimization"],
|
||||
action="store_true"
|
||||
)
|
||||
"--no-meshes-optimization",
|
||||
help="disable meshes optimization",
|
||||
default=DEFAULT_OPTIONS["no_meshes_optimization"],
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-textures-optimization",
|
||||
help="disable textures optimization using yoga image",
|
||||
default=DEFAULT_OPTIONS["no_textures_optimization"],
|
||||
action="store_true"
|
||||
)
|
||||
"--no-textures-optimization",
|
||||
help="disable textures optimization using yoga image",
|
||||
default=DEFAULT_OPTIONS["no_textures_optimization"],
|
||||
action="store_true",
|
||||
)
|
||||
|
|
|
@ -45,7 +45,10 @@ def normalize_paths(paths):
|
|||
for path in paths:
|
||||
normalized_path = normalize_path(path)
|
||||
if normalized_path in normalized_paths:
|
||||
raise ValueError("Multiple paths are resolved to the same path %s." % normalized_path) # noqa
|
||||
raise ValueError(
|
||||
"Multiple paths are resolved to the same path %s."
|
||||
% normalized_path
|
||||
)
|
||||
normalized_paths[normalized_path] = paths[path]
|
||||
|
||||
return normalized_paths
|
||||
|
@ -62,7 +65,9 @@ def find_valid_path(path, paths):
|
|||
split_paths = map(lambda p: p.split("/")[::-1], paths.keys())
|
||||
|
||||
for i, name in enumerate(split_path):
|
||||
split_paths = list(filter(lambda sp: len(sp) > i and sp[i] == name, split_paths)) # noqa
|
||||
split_paths = list(
|
||||
filter(lambda sp: len(sp) > i and sp[i] == name, split_paths)
|
||||
)
|
||||
|
||||
if len(split_paths) == 0:
|
||||
break
|
||||
|
@ -80,13 +85,24 @@ def extract_files_dictionary(root_path):
|
|||
root_path = root_path.decode("utf-8")
|
||||
|
||||
# Recursive walk of root_path files
|
||||
files = [os.path.join(dp, f) for dp, dn, filenames in os.walk(root_path) for f in filenames] # noqa
|
||||
files = [
|
||||
os.path.join(dp, f)
|
||||
for dp, dn, filenames in os.walk(root_path)
|
||||
for f in filenames
|
||||
]
|
||||
return normalize_paths(dict(zip(files, files)))
|
||||
|
||||
|
||||
def model_embed_images(images, images_bytes,
|
||||
optimize_textures, fallback_texture, root_path,
|
||||
image_options, textures, quiet):
|
||||
def model_embed_images(
|
||||
images,
|
||||
images_bytes,
|
||||
optimize_textures,
|
||||
fallback_texture,
|
||||
root_path,
|
||||
image_options,
|
||||
textures,
|
||||
quiet,
|
||||
):
|
||||
optimized_textures = {}
|
||||
normalized_textures = normalize_paths(textures)
|
||||
files = extract_files_dictionary(root_path)
|
||||
|
@ -101,7 +117,9 @@ def model_embed_images(images, images_bytes,
|
|||
# If textures exists, we don't look for files on the file system
|
||||
normalized_image_path = normalize_path(image_path)
|
||||
if normalized_textures is not None:
|
||||
valid_image_path = find_valid_path(normalized_image_path, normalized_textures) # noqa
|
||||
valid_image_path = find_valid_path(
|
||||
normalized_image_path, normalized_textures
|
||||
)
|
||||
else:
|
||||
valid_image_path = find_valid_path(normalized_image_path, files)
|
||||
|
||||
|
@ -110,7 +128,10 @@ def model_embed_images(images, images_bytes,
|
|||
if fallback_texture is not None:
|
||||
valid_image_path = None
|
||||
if not quiet:
|
||||
print("Warning: Cannot resolve %s, using the fallback texture instead." % normalized_image_path) # noqa
|
||||
print(
|
||||
"Warning: Cannot resolve %s, using the fallback texture instead." # noqa: E501
|
||||
% normalized_image_path
|
||||
)
|
||||
else:
|
||||
raise ValueError("Cannot resolve %s" % normalized_image_path)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
DEFAULT_OPTIONS = {
|
||||
"output_format": "glb", # glb|gltf
|
||||
"fallback_texture": None,
|
||||
"no_graph_optimization": False,
|
||||
"no_meshes_optimization": False,
|
||||
"no_textures_optimization": False,
|
||||
}
|
||||
"output_format": "glb", # glb|gltf
|
||||
"fallback_texture": None,
|
||||
"no_graph_optimization": False,
|
||||
"no_meshes_optimization": False,
|
||||
"no_textures_optimization": False,
|
||||
}
|
||||
|
||||
|
||||
def normalize_options(options=None):
|
||||
|
@ -18,7 +18,7 @@ def normalize_options(options=None):
|
|||
value = options["output_format"].lower()
|
||||
|
||||
if value not in ("gltf", "glb"):
|
||||
raise ValueError("Invalid value for 'output_format': '%s'" % value) # noqa
|
||||
raise ValueError("Invalid value for 'output_format': '%s'" % value)
|
||||
|
||||
result["output_format"] = value
|
||||
|
||||
|
@ -33,8 +33,11 @@ def normalize_options(options=None):
|
|||
result["fallback_texture"] = fallback_texture_file
|
||||
|
||||
# Optimization flags
|
||||
for key in ("no_graph_optimization", "no_meshes_optimization",
|
||||
"no_textures_optimization"):
|
||||
for key in (
|
||||
"no_graph_optimization",
|
||||
"no_meshes_optimization",
|
||||
"no_textures_optimization",
|
||||
):
|
||||
if key in options:
|
||||
result[key] = bool(options[key])
|
||||
|
||||
|
|
Loading…
Reference in New Issue