ayon-core/openpype/tools/texture_copy/app.py
Roy Nieterau b05afaa837
Global: Optimize anatomy formatting by only formatting used templates instead (#4784)
* TemplatesDict can create different type of template

* anatomy templates can be formatted on their own

* return objected templates on get item

* '_rootless_path' is public classmethod 'rootless_path_from_result'

* 'AnatomyStringTemplate' expect anatomy templates

* remove key getters

* fix typo 'create_ojected_templates' -> 'create_objected_templates'

* Fix type of argument

* Fix long line

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Optimize formatting to use single template formatting instead of formatting full anatomy

* Use format strict + code cosmetics

* Get template from the formatted data

* Update openpype/plugins/publish/integrate_legacy.py

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* Cosmetics

* Move template obj definition for path up + rename to `path_template_obj`

* Refactor more cases from `anatomy.format` to template obj `.format_strict`

* Refactor more cases from `anatomy.format` to template obj `.format_strict`

* Refactor more cases from `anatomy.format` to template obj `.format_strict`

---------

Co-authored-by: Jakub Trllo <jakub.trllo@gmail.com>
Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>
2023-04-17 14:53:15 +02:00

146 lines
4.8 KiB
Python

import os
import re
import click
import speedcopy
from openpype.client import get_project, get_asset_by_name
from openpype.lib import Terminal
from openpype.pipeline import legacy_io, Anatomy
t = Terminal()
texture_extensions = ['.tif', '.tiff', '.jpg', '.jpeg', '.tx', '.png', '.tga',
'.psd', '.dpx', '.hdr', '.hdri', '.exr', '.sxr', '.psb']
class TextureCopy:
def __init__(self):
if not legacy_io.Session:
legacy_io.install()
def _get_textures(self, path):
textures = []
for dir, subdir, files in os.walk(path):
textures.extend(
os.path.join(dir, x) for x in files
if os.path.splitext(x)[1].lower() in texture_extensions)
return textures
def _get_destination_path(self, asset, project):
project_name = project["name"]
hierarchy = ""
parents = asset['data']['parents']
if parents and len(parents) > 0:
hierarchy = os.path.join(*parents)
template_data = {
"project": {
"name": project_name,
"code": project['data']['code']
},
"asset": asset['name'],
"family": 'texture',
"subset": 'Main',
"hierarchy": hierarchy
}
anatomy = Anatomy(project_name)
template_obj = anatomy.templates_obj["texture"]["path"]
return template_obj.format_strict(template_data)
def _get_version(self, path):
versions = [0]
dirs = [f.path for f in os.scandir(path) if f.is_dir()]
for d in dirs:
ver = re.search(r'^v(\d+)$',
os.path.basename(d),
flags=re.IGNORECASE)
if ver is not None:
versions.append(int(ver.group(1)))
return max(versions) + 1
def _copy_textures(self, textures, destination):
for tex in textures:
dst = os.path.join(destination,
os.path.basename(tex))
t.echo(" - Copy {} -> {}".format(tex, dst))
try:
speedcopy.copyfile(tex, dst)
except Exception as e:
t.echo("!!! Copying failed")
t.echo("!!! {}".format(e))
exit(1)
def process(self, asset_name, project_name, path):
"""
Process all textures found in path and copy them to asset under
project.
"""
t.echo(">>> Looking for textures ...")
textures = self._get_textures(path)
if len(textures) < 1:
t.echo("!!! no textures found.")
exit(1)
else:
t.echo(">>> Found {} textures ...".format(len(textures)))
project = get_project(project_name)
if not project:
t.echo("!!! Project name [ {} ] not found.".format(project_name))
exit(1)
asset = get_asset_by_name(project_name, asset_name)
if not asset:
t.echo("!!! Asset [ {} ] not found in project".format(asset_name))
exit(1)
t.echo((">>> Project [ {} ] and "
"asset [ {} ] seems to be OK ...").format(project['name'],
asset['name']))
dst_path = self._get_destination_path(asset, project)
t.echo("--- Using [ {} ] as destination path".format(dst_path))
if not os.path.exists(dst_path):
try:
os.makedirs(dst_path)
except IOError as e:
t.echo("!!! Unable to create destination directory")
t.echo("!!! {}".format(e))
exit(1)
version = '%02d' % self._get_version(dst_path)
t.echo("--- Using version [ {} ]".format(version))
dst_path = os.path.join(dst_path, "v{}".format(version))
t.echo("--- Final destination path [ {} ]".format(dst_path))
try:
os.makedirs(dst_path)
except FileExistsError:
t.echo("!!! Somethings wrong, version directory already exists")
exit(1)
except IOError as e:
t.echo("!!! Cannot create version directory")
t.echo("!!! {}".format(e))
exit(1)
t.echo(">>> copying textures ...")
self._copy_textures(textures, dst_path)
t.echo(">>> done.")
t.echo("<<< terminating ...")
@click.command()
@click.option('--asset', required=True)
@click.option('--project', required=True)
@click.option('--path', required=True)
def texture_copy(asset, project, path):
t.echo("*** Running Texture tool ***")
t.echo(">>> Initializing avalon session ...")
os.environ["AVALON_PROJECT"] = project
os.environ["AVALON_ASSET"] = asset
TextureCopy().process(asset, project, path)
if __name__ == '__main__':
texture_copy()