Skip to content

Commit 228aa7e

Browse files
committed
Implement support for additional filterers.
Signed-off-by: Thomas Mansencal <[email protected]>
1 parent 0a55d32 commit 228aa7e

File tree

10 files changed

+161
-70
lines changed

10 files changed

+161
-70
lines changed

docs/opencolorio_config_aces.utilities.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ Common
4040
attest
4141
timestamp
4242
as_bool
43+
optional

opencolorio_config_aces/clf/discover/classify.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from opencolorio_config_aces.utilities import (
3131
attest,
3232
message_box,
33+
optional,
3334
paths_common_ancestor,
3435
vivified_to_dict,
3536
)
@@ -492,8 +493,7 @@ def __init__(
492493
genus: str | None = None,
493494
siblings: Sequence | None = None,
494495
) -> None:
495-
if siblings is None:
496-
siblings = []
496+
siblings = optional(siblings, [])
497497

498498
self._path: str = os.path.abspath(os.path.normpath(path))
499499

@@ -1246,8 +1246,7 @@ def filter_clf_transforms(
12461246
'blackmagic...input...BlackmagicDesign.Input.BMDFilm_Gen5_Log-Curve.clf')
12471247
"""
12481248

1249-
if filterers is None:
1250-
filterers = TRANSFORM_FILTERERS_DEFAULT_CLF
1249+
filterers = optional(filterers, TRANSFORM_FILTERERS_DEFAULT_CLF)
12511250

12521251
if isinstance(clf_transforms, Mapping):
12531252
clf_transforms = unclassify_clf_transforms(clf_transforms)

opencolorio_config_aces/config/cg/generate/config.py

Lines changed: 83 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
)
5050
from opencolorio_config_aces.utilities import (
5151
attest,
52+
optional,
5253
timestamp,
5354
validate_method,
5455
)
@@ -192,8 +193,7 @@ def clf_transform_to_description(
192193
*OpenColorIO* `Colorspace` or `NamedTransform` description.
193194
"""
194195

195-
if amf_components is None:
196-
amf_components = {}
196+
amf_components = optional(amf_components, {})
197197

198198
description = None
199199
if describe != DescriptionStyle.NONE:
@@ -755,6 +755,7 @@ def generate_config_cg(
755755
describe=DescriptionStyle.SHORT_UNION,
756756
config_mapping_file_path=PATH_TRANSFORMS_MAPPING_FILE_CG,
757757
scheme="Modern 1",
758+
additional_filterers=None,
758759
additional_data=False,
759760
):
760761
"""
@@ -803,6 +804,20 @@ def generate_config_cg(
803804
scheme : str, optional
804805
{"Legacy", "Modern 1"},
805806
Naming convention scheme to use.
807+
additional_filterers : dict, optional
808+
Additional filterers to further include or exclude transforms from the
809+
generated config.
810+
811+
.. code-block:: python
812+
813+
{
814+
"any": {},
815+
"all": {
816+
"view_transform_filterers": [lambda x: "D60" not in x["name"]],
817+
"view_filterers": [lambda x: "D60" not in x["view"]],
818+
},
819+
},
820+
806821
additional_data : bool, optional
807822
Whether to return additional data.
808823
@@ -816,6 +831,8 @@ def generate_config_cg(
816831

817832
scheme = validate_method(scheme, ["Legacy", "Modern 1"])
818833

834+
additional_filterers = optional(additional_filterers, {"any": {}, "all": {}})
835+
819836
LOGGER.info(
820837
'Generating "%s" config...',
821838
config_name_cg(dependency_versions),
@@ -978,42 +995,74 @@ def transform_filterer(transform):
978995
if not aces_transform_id:
979996
continue
980997

981-
for data in transform["transforms_data"]:
998+
for data in transform.get("transforms_data", []):
982999
if aces_transform_id == data.get("aces_transform_id"):
9831000
return True
9841001

9851002
return False
9861003

987-
def multi_filters(array, filterers):
988-
"""Apply given filterers on given array."""
1004+
def filter_any(array, filterers):
1005+
"""Filter array elements passing any of the filterers."""
9891006

9901007
filtered = [a for a in array if any(filterer(a) for filterer in filterers)]
9911008

9921009
return filtered
9931010

994-
colorspace_filterers = [implicit_transform_filterer, transform_filterer]
995-
data.colorspaces = multi_filters(data.colorspaces, colorspace_filterers)
1011+
def filter_all(array, filterers):
1012+
"""Filter array elements passing all of the filterers."""
1013+
1014+
filtered = [a for a in array if all(filterer(a) for filterer in filterers)]
9961015

1016+
return filtered
1017+
1018+
# "Colorspaces" Filtering
1019+
any_colorspace_filterers = [
1020+
implicit_transform_filterer,
1021+
transform_filterer,
1022+
*additional_filterers["any"].get("colorspace_filterers", []),
1023+
]
1024+
data.colorspaces = filter_any(data.colorspaces, any_colorspace_filterers)
1025+
all_colorspace_filterers = [
1026+
*additional_filterers["all"].get("colorspace_filterers", [])
1027+
]
1028+
data.colorspaces = filter_all(data.colorspaces, all_colorspace_filterers)
9971029
LOGGER.info(
9981030
'Filtered "Colorspace" transforms: %s.',
9991031
[a["name"] for a in data.colorspaces],
10001032
)
10011033

1002-
look_filterers = [implicit_transform_filterer, transform_filterer]
1003-
data.looks = multi_filters(data.looks, look_filterers)
1034+
# "Looks" Filtering
1035+
any_look_filterers = [
1036+
implicit_transform_filterer,
1037+
transform_filterer,
1038+
*additional_filterers["any"].get("look_filterers", []),
1039+
]
1040+
data.looks = filter_any(data.looks, any_look_filterers)
1041+
all_look_filterers = [*additional_filterers["all"].get("look_filterers", [])]
1042+
data.looks = filter_all(data.looks, all_look_filterers)
10041043
LOGGER.info('Filtered "Look" transforms: %s ', [a["name"] for a in data.looks])
10051044

1006-
view_transform_filterers = [
1045+
# "View Transform" Filtering
1046+
any_view_transform_filterers = [
10071047
implicit_transform_filterer,
10081048
transform_filterer,
1049+
*additional_filterers["any"].get("view_transform_filterers", []),
10091050
]
1010-
data.view_transforms = multi_filters(data.view_transforms, view_transform_filterers)
1051+
data.view_transforms = filter_any(
1052+
data.view_transforms, any_view_transform_filterers
1053+
)
1054+
all_view_transform_filterers = [
1055+
*additional_filterers["all"].get("view_transform_filterers", [])
1056+
]
1057+
data.view_transforms = filter_all(
1058+
data.view_transforms, all_view_transform_filterers
1059+
)
10111060
LOGGER.info(
10121061
'Filtered "View" transforms: %s.',
10131062
[a["name"] for a in data.view_transforms],
10141063
)
10151064

1016-
# Views Filtering
1065+
# "Views & Shared Views" Filtering
10171066
display_names = [
10181067
a["name"] for a in data.colorspaces if a.get("family") == "Display"
10191068
]
@@ -1040,22 +1089,37 @@ def view_filterer(transform):
10401089

10411090
return False
10421091

1043-
shared_view_filterers = [implicit_view_filterer, view_filterer]
1044-
data.shared_views = multi_filters(data.shared_views, shared_view_filterers)
1092+
# "Shared Views" Filtering
1093+
any_shared_view_filterers = [
1094+
implicit_view_filterer,
1095+
view_filterer,
1096+
*additional_filterers["any"].get("shared_view_filterers", []),
1097+
]
1098+
data.shared_views = filter_any(data.shared_views, any_shared_view_filterers)
1099+
all_shared_view_filterers = [
1100+
*additional_filterers["all"].get("shared_view_filterers", [])
1101+
]
1102+
data.shared_views = filter_all(data.shared_views, all_shared_view_filterers)
10451103
LOGGER.info(
10461104
'Filtered shared "View(s)": %s.',
10471105
[a["view"] for a in data.shared_views],
10481106
)
10491107

1050-
view_filterers = [implicit_view_filterer, view_filterer]
1051-
data.views = multi_filters(data.views, view_filterers)
1108+
any_view_filterers = [
1109+
implicit_view_filterer,
1110+
view_filterer,
1111+
*additional_filterers["any"].get("view_filterers", []),
1112+
]
1113+
data.views = filter_any(data.views, any_view_filterers)
1114+
all_view_filterers = [*additional_filterers["all"].get("view_filterers", [])]
1115+
data.views = filter_all(data.views, all_view_filterers)
10521116
LOGGER.info('Filtered "View(s)": %s.', [a["view"] for a in data.views])
10531117

1054-
# Active Displays Filtering
1118+
# "Active Displays" Filtering
10551119
data.active_displays = [a for a in data.active_displays if a in display_names]
10561120
LOGGER.info("Filtered active displays: %s.", data.active_displays)
10571121

1058-
# Active Views Filtering
1122+
# "Active Views" Filtering
10591123
views = [view["view"] for view in data.views]
10601124
data.active_views = [view for view in data.active_views if view in views]
10611125
LOGGER.info("Filtered active views: %s.", data.active_views)
@@ -1238,24 +1302,10 @@ def view_filterer(transform):
12381302
dependency_versions=dependency_versions,
12391303
additional_data=True,
12401304
)
1241-
# TODO: Pickling "PyOpenColorIO.ColorSpace" fails on early "PyOpenColorIO"
1242-
# versions.
1305+
12431306
try:
12441307
serialize_config_data(
12451308
data, build_directory / config_basename.replace("ocio", "json")
12461309
)
12471310
except TypeError as error:
12481311
logging.critical(error)
1249-
1250-
if dependency_versions.ocio.minor <= 3:
1251-
config = ocio.Config.CreateFromFile( # pyright:ignore
1252-
str(build_directory / config_basename)
1253-
)
1254-
view_transforms = list(config.getViewTransforms())
1255-
view_transforms = [view_transforms[-1], *view_transforms[:-1]]
1256-
config.clearViewTransforms()
1257-
for view_transform in view_transforms:
1258-
config.addViewTransform(view_transform)
1259-
1260-
with open(build_directory / config_basename, "w") as file:
1261-
file.write(config.serialize())

opencolorio_config_aces/config/generation/factories.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from semver import Version
2727

2828
from opencolorio_config_aces.config.generation import PROFILE_VERSION_DEFAULT
29-
from opencolorio_config_aces.utilities import DocstringDict, attest
29+
from opencolorio_config_aces.utilities import DocstringDict, attest, optional
3030

3131
__author__ = "OpenColorIO Contributors"
3232
__copyright__ = "Copyright Contributors to the OpenColorIO Project."
@@ -179,8 +179,7 @@ def colorspace_factory(
179179
indent(pformat(locals()), " "),
180180
)
181181

182-
if bit_depth is None:
183-
bit_depth = ocio.BIT_DEPTH_F32
182+
bit_depth = optional(bit_depth, ocio.BIT_DEPTH_F32)
184183

185184
if reference_space is None:
186185
reference_space = ocio.REFERENCE_SPACE_SCENE
@@ -408,8 +407,7 @@ def view_transform_factory(
408407
indent(pformat(locals()), " "),
409408
)
410409

411-
if categories is None:
412-
categories = []
410+
categories = optional(categories, [])
413411

414412
if reference_space is None:
415413
reference_space = ocio.REFERENCE_SPACE_SCENE
@@ -495,8 +493,7 @@ def look_factory(
495493
indent(pformat(locals()), " "),
496494
)
497495

498-
if process_space is None:
499-
process_space = ocio.ROLE_SCENE_LINEAR
496+
process_space = optional(process_space, ocio.ROLE_SCENE_LINEAR)
500497

501498
if base_look is not None:
502499
if isinstance(base_look, Mapping):

opencolorio_config_aces/config/reference/discover/classify.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from opencolorio_config_aces.utilities import (
3131
attest,
3232
message_box,
33+
optional,
3334
paths_common_ancestor,
3435
vivified_to_dict,
3536
)
@@ -660,8 +661,7 @@ class CTLTransform:
660661
"""
661662

662663
def __init__(self, path, family=None, genus=None, siblings=None):
663-
if siblings is None:
664-
siblings = []
664+
siblings = optional(siblings, [])
665665

666666
self._path = os.path.abspath(os.path.normpath(path))
667667

@@ -1362,8 +1362,7 @@ def filter_ctl_transforms(ctl_transforms, filterers=None):
13621362
P3-D65_1000nit_in_P3-D65_ST2084.ctl')
13631363
"""
13641364

1365-
if filterers is None:
1366-
filterers = TRANSFORM_FILTERERS_DEFAULT_CTL
1365+
filterers = optional(filterers, TRANSFORM_FILTERERS_DEFAULT_CTL)
13671366

13681367
if isinstance(ctl_transforms, Mapping):
13691368
ctl_transforms = unclassify_ctl_transforms(ctl_transforms)

opencolorio_config_aces/config/reference/discover/graph.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
filter_ctl_transforms,
2727
unclassify_ctl_transforms,
2828
)
29-
from opencolorio_config_aces.utilities import required
29+
from opencolorio_config_aces.utilities import optional, required
3030

3131
__author__ = "OpenColorIO Contributors"
3232
__copyright__ = "Copyright Contributors to the OpenColorIO Project."
@@ -235,8 +235,7 @@ def filter_nodes(graph, filterers=None):
235235
'Output/P3-D65_1000nit_in_P3-D65_ST2084'
236236
"""
237237

238-
if filterers is None:
239-
filterers = []
238+
filterers = optional(filterers, [])
240239

241240
filtered_nodes = []
242241
for node in graph.nodes:

opencolorio_config_aces/config/reference/generate/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from opencolorio_config_aces.utilities import (
4949
as_bool,
5050
attest,
51+
optional,
5152
timestamp,
5253
validate_method,
5354
)
@@ -340,8 +341,7 @@ def ctl_transform_to_description(
340341
*OpenColorIO* `Colorspace` or `Look` description.
341342
"""
342343

343-
if amf_components is None:
344-
amf_components = {}
344+
amf_components = optional(amf_components, {})
345345

346346
description = None
347347
if describe != DescriptionStyle.NONE:

0 commit comments

Comments
 (0)