Open mottosso opened 8 years ago
This sounds great!
I think it's even better if this would be abstracted even further. Say the capture
command takes a context parameter that is a list of context managers.
Then performing a wedge like this becomes easy:
# pseudo
for layer in ["stiff", "heavy"]:
capture (context=anim _ layer(layer))
This would even allow other artists to instead of capturing different anim layers to do so for different render layers making it possible to do previews with different textures.
I feel the animation layer technique is somewhat specific and can easily be abstracted into an own custom context manager.
Thanks, glad you like it.
But I'm not exactly following, what is this "context" and how would it work capturing in a loop? How would you be able to use the output of each run? And what is anim_layer()
?
I think the creation of multiple output is a different issue. But the context manager I referred to was a means to 'plugging in' a custom "pre-capture" and "post-capture" functionality as it runs through the playblast.
It's like adding a pre_callback and post_callback and ensuring the post callbacks are triggered. All it would do is temporarily set the state of the animation layers. So in your case it would be something like
# pseudocode
import contextlib
@contextlib.contextmanager
def wedge(layers_str):
layers = cmds.ls(type="animLayer")
enable = layers_str.split(";")
original = {}
for layer in layers:
original[layer] = get_state(layer)
set_state(layer, layer in enable)
try:
yield
finally:
for layer, state in original.items():
set_state(layer, state)
for state in ["stiff", "loose", "stiff;high_substep"]:
capture(context=wedge(state))
I think combining multiple captures into a single "view" result like on_finished
is useful by itself, even without using a wedge. Maybe even captures with multiple cameras.
# pseudo
def run_in_rv(files):
subprocess.Popen(["rv"] + files)
with combined_view(on_finished=run_in_rv) as view:
result = capture(view=False)
view.append(result)
As stated, likely better fitted for a separate issue.
Ah. Ok. I implemented this briefly here, where I also made a context manager like this, but didn't think to expose it publicly, it was only used within wedge()
.
@contextlib.contextmanager
def _solo_animation_layer(layer):
"""Isolate animation layer"""
if not cmds.animLayer(layer, query=True, mute=True):
raise ValueError("%s must be muted" % layer)
try:
cmds.animLayer(layer, edit=True, mute=False)
yield
finally:
cmds.animLayer(layer, edit=True, mute=True)
Have a look at how it's used, to see if your idea could work in practice. Are you thinking it might be an idea to expose this context manager for manual use and calling capture()
as usual?
multiprocess=True
into async=True
, shorter, sweeter__post
to __monitor
, as it better describes what it does.Oof. Yeah,... so separate out the context manager so one could use their own custom ones to perform wedges in different manners as described earlier.
Use the anim layer thing solely to show an example. The checking for missing anim layers and alike should also become part of the method that you pass to wedge
since it's related to the anim layer technique.
Ok, I think it sounds like we're talking about two things.
Are you also talking about how to capture wedges, or about how to wedge in the first place?
For the wedge interface, we'll need
_______________________
|______________________x|
| |
| layer1 |------o---| x |
| layer2 |----o-----| x |
| layer3 |-----o----| x |
| ____________ |
| | ||
| | Stop all x ||
| |____________||
|_______________________|
Some more core functionality.
For example, if the currently running process consumes 1gb, and the machine currently has 10gb available, then a maximum of 9 simultaneous processes can run. Taking into account that we would want to maintain at least some ram, perhaps 1gb, that gives a maximum of 8 running processes.
We'll do a pre-flight check to test whether there is enough ram to run a single process, otherwise revert to running locally. If the test passes, then we'll run the maximum amount of processes based on available memory and save the rest in a queue to run once a process has finished.
The callback is only called when everything has finished.
We might also need:
Goal
Enable capturing of wedges.
You are tasked with producing playblasts for a combination of properties of nCloth.
In this example, each feature has two states - on or off - resulting in
3**2=9
wedges.Taking in mind that it may be important to return back to a particular configuration, given a successful review, a traditional workflow would have required an artist to alter the settings of a scene, save this as a uniquely rememberable version, playblast this, and then do the same for the other 8 variations.
With
capture.wedge
the same is both more manageable and with better performance, given that each capture can occur simultaneously (see below about multi-processing).Interface
Each wedge is based on an animation layer. Animation layers are capable of storing independent configurations that may be either blended or used in isolation.
Run
capture.wedge
Implementation
An animation layer is used per wedge and each wedge is set off as a background process, using a copy of the scene at its current state, including camera and scene settings (using
capture.parse_view
).multiprocessing
An option is provided for running Maya sessions as a background process simultaneously, in addition to the default behaviour of running each capture successively one after the other.
The benefit of the former is simultaneous capturing, resulting in an n-times shorter capturing duration, assuming capturing consumes a single processor core each. For example, 8 wedges involving nCloth runs 8 times as fast as running 8 captures within the same Maya session.
on_finished
With multi-processing, it's impossible to retrieve the resulting files created during capturing as the process is asynchronous. Therefore, there is an option to pass a callback for when it finishes, which is then passed a list of each newly created capture.
The above results in the finished captures automatically opening in RV when finished.
combinations
Animation layers provide a native ability to blend between each other, enabling a combination off effects.
Consider the following three layers.
Layers can then be activated two-and-two.