AcademySoftwareFoundation / AcademySoftwareFoundation/OpenColorIO
Python API: Override Transform "+" and "-" operators as shorthand for concatenation and inversion
- Lingua principale
- C++
- Stelle
- 2.1k
- Fork
- 503
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
# Objective
Override the Transform class addition and subtraction operators to provide a convenient, intuitive, "magical" mechanism for combining and inverting transforms with a syntax similar OCIO's "Look Expression Language"
# Motivation
_Vastly_ improves the API user-experience and code intelligibility. Inspired by a feature written by @rminsk for our in-house OCIO config-authoring library. I'm the only person who knows the feature exists, and it's _really_ nice.
# The Pitch
Say you've got these three Transforms you'd like to string together:
```
lin_to_log = ColorSpaceTransform("scene_linear", "color_timing")
dailies_grade = FileTransform("dailies.ccc", cccid="$SHOT")
show_lut = FileTransform("show_lut_rec709.csp")
```
Right now, there's a **traditional** way of concatenating as a GroupTransform:
```
gt = GroupTransform()
gt.append(lin_to_log)
gt.append(dailies_grade)
gt.append(show_lut)
```
...and a **fancy** way:
```
gt = GroupTransform( [lin_to_log, dailies_grade, show_lut] )
```
Proposed is an **_extra_ fancy** way, via the Transform _addition_ operator:
```
gt = lin_to_log + dailies_grade + show_lut
```
Additionally, the Transform _subtraction_ operator would denote direction inversion:
Currently, inverting a Transform involves first determining what the inverted direction would be:
```
inv_dir = combineTransformDirections(lin_to_log.getDirection(), TRANSFORM_DIRECTION_INVERSE)
log_to_lin = lin_to_log.setDirection(inv_dir)
```
(note: the above example mutates the state of the original "lin_to_log" instance)
Sure would be nice to be able to do the following:
```
log_to_lin = -lin_to_log
```
But like Peter Falk says in Wings of Desire, "To concatenate, to invert... and if you do it together, it's fantastic":
```
# convert to working space, invert neutral grade, apply dailies grade, apply show_lut
inv_neutral_shot_look = lin_to_log - neutral_grade + dailies_grade + show_lut
# concatenate discrete inverse-shaper LUT1Ds and shaped LUT3Ds
lut1d3d = -ColorSpaceTransform("shaper_to_linear") + FileTransform("shaped_lattice.spi3d")
```
# Implementation
I can't publicly share our actual code, but I can show you guys how it works in private, and / or quickly mock up a pure python example. The basic heuristic is very straightforward:
Addition:
1. Create a new GroupTransform that concatenates the left-hand operand followed by the right-hand operand.
Subtraction:
1. Enclose the operand in a new GroupTransform, and set the GroupTransform's direction to TRANSFORM_DIR_INVERSE
In practice, there are a some considerations for reducing unnecessary nested or adjacent GroupTransforms; and "inverted" GroupTransforms are converted to "forward" GroupTransforms by recursively unpacking, "flipping", and re-packing each Transform in the sequence.
In our implementation, when our library is imported, we're actually subclassing PyOpenColorIO.Transform, overriding the operators, and injecting the modified classes back into the PyOpenColorIO namespace, which is certainly one way of going about this... I'm not much for C++, but it seems like this wouldn't take too much time or energy to implement with pybind11. If there's interest in seeing a PR, I'd be more than happy to harass @remia and @michdolan for help.
What do you guys think... too much magic? Not enough magic?
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia esaminando i binding dell’API Python per Transform e il comportamento esistente di GroupTransform, append, setDirection e combineTransformDirections. Definisci e testa l’addizione concatenata per la concatenazione e la sottrazione unaria per l’inversione, inclusi i casi descritti di GroupTransform annidati o adiacenti; il lavoro è completato quando le espressioni mostrate producono le transform desiderate senza modificare l’operando originale.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- cpp, python
- Ambito
- api
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 25/100