Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Render / Turntable #43

Open
wants to merge 112 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
cd7fc55
first commit, adding playblast module
Sasbom Nov 27, 2023
32b90dc
added utility and expanded on renderplayblast args and processing
Sasbom Nov 27, 2023
663f958
parsing complexity argument better, fixed walrus bugs
Sasbom Nov 28, 2023
eb84c53
slight refactor
Sasbom Nov 28, 2023
d04aad3
ConverFramePlaceholderblabla does internal None checking, so removed …
Sasbom Nov 28, 2023
bbac50c
Merge branch 'BigRoy:main' into enhancement/usdview_render_turntable
Sasbom Nov 28, 2023
8b9f7e6
Removed hardcoded complexity presets, added sanity checking for rende…
Sasbom Nov 28, 2023
b6c429c
Complete framerecorder initialization setup
Sasbom Nov 28, 2023
623f105
Merge branch 'BigRoy:main' into enhancement/usdview_render_turntable
Sasbom Nov 29, 2023
13f62c4
resources_rc added
Sasbom Nov 29, 2023
6d1e89e
added menu, functionality for snapshot. Doesn't work as intended with…
Sasbom Nov 29, 2023
94716ab
snapshot fix! Works now. Still needs major cleanup.
Sasbom Nov 29, 2023
14e5e00
Merge branch 'BigRoy:main' into enhancement/usdview_render_turntable
Sasbom Nov 29, 2023
028fdd4
changed logic in case no camera is selected to match usdrecord
Sasbom Nov 29, 2023
583f35b
Merge branch 'enhancement/usdview_render_turntable' of https://github…
Sasbom Nov 29, 2023
d7f4b9d
house cleaning, suggested bugfixes
Sasbom Nov 29, 2023
09a041b
slowly but surely adding methods to deal with cameras
Sasbom Nov 30, 2023
d69188d
added distance calculation function while downstairs neighbours are d…
Sasbom Nov 30, 2023
962ab0c
finished clipping planes function.
Sasbom Nov 30, 2023
b86915c
finished calculate camera position function.
Sasbom Nov 30, 2023
6b293db
cross platform catch for non-OGL native systems (macosx)
Sasbom Nov 30, 2023
1b934c1
Completed routine to add a framing camera!
Sasbom Nov 30, 2023
6cc9386
Merge branch 'BigRoy:main' into enhancement/usdview_render_turntable
Sasbom Nov 30, 2023
e0314a1
added fit parameter to add some padding
Sasbom Nov 30, 2023
f93c85b
micro commit to change a variable name in a function to something mor…
Sasbom Nov 30, 2023
4bbdb2d
Created render_util.turntable,
Sasbom Dec 1, 2023
271917b
bugfixes + exposed turntable render as temp functionality.
Sasbom Dec 1, 2023
60801ee
bugfix: adjusted transforms when framing camera as turntable camera
Sasbom Dec 1, 2023
b00d12f
added some utility to deal with the frame argument
Sasbom Dec 4, 2023
cdf43c0
made tuples_to_frames_string.tuple_gen way more sane
Sasbom Dec 4, 2023
9800a4b
made functions way less ridiculous
Sasbom Dec 4, 2023
218e7c1
refactored some things, added dialog helpers
Sasbom Dec 4, 2023
fa016b3
notes
Sasbom Dec 4, 2023
09a3104
top level function padding
Sasbom Dec 5, 2023
02be61e
Merge branch 'BigRoy:main' into enhancement/usdview_render_turntable
Sasbom Dec 5, 2023
38c53fa
Proposal: add traverse_prim_descendants to lib.usd
Sasbom Dec 5, 2023
8a1991f
cleaned up test
Sasbom Dec 5, 2023
fc4be96
struggling to do reparenting properly
Sasbom Dec 5, 2023
5f8ad2d
am no longer confused by reparenting, we're gonna do references.
Sasbom Dec 5, 2023
766e5c4
building out new reference based logic for turntable from file functi…
Sasbom Dec 6, 2023
3230460
fleshed out turntable_from_file to working order.
Sasbom Dec 6, 2023
bc8e23d
cleanup integration pass 1
Sasbom Dec 6, 2023
13a8545
Cleanup finalized
Sasbom Dec 6, 2023
8b46c65
cleared up some comments
Sasbom Dec 6, 2023
880e376
removed deprecated functions
Sasbom Dec 6, 2023
21b9868
updated comments
Sasbom Dec 6, 2023
e6289cb
updated comments
Sasbom Dec 6, 2023
290b14e
Merge branch 'enhancement/usdview_render_turntable' of https://github…
Sasbom Dec 6, 2023
8960936
A preset turntable USD file has been added.
Sasbom Dec 6, 2023
7123fdb
Cosmetics / cleanup
BigRoy Dec 6, 2023
3603058
Merge remote-tracking branch 'sasbom/enhancement/usdview_render_turnt…
BigRoy Dec 6, 2023
5125573
Merge pull request #2 from BigRoy/enhancement/usdview_render_turntabl…
Sasbom Dec 6, 2023
fbb7ab7
Changed template file to .usda, fixed up minor things in turntable.
Sasbom Dec 7, 2023
6730c38
division per element nessecary, fixed string error in dialog
Sasbom Dec 7, 2023
7568426
fix unwanted inclusion
Sasbom Dec 7, 2023
b19cf1e
Remove prims made in Render menu
Sasbom Dec 7, 2023
69ebc5d
clear bbox before stuffing it full of other things
Sasbom Dec 7, 2023
b6e5441
update gitignore to ignore temp folder
Sasbom Dec 7, 2023
1ef9f02
fix ignore of temp folder
Sasbom Dec 7, 2023
224de08
automated cleanup at the end of turntable render
Sasbom Dec 7, 2023
52bfb19
small changes, tiny checks for turntable from file functionality.
Sasbom Dec 8, 2023
da9e1e7
Added a guide to setting up your own turntable.
Sasbom Dec 8, 2023
910ff5c
Set up dialog and editor to dislay it
Sasbom Dec 8, 2023
6b65c0c
Merge branch 'enhancement/usdview_render_turntable' of https://github…
Sasbom Dec 8, 2023
8f81456
base layout style for PlayblastDialog
Sasbom Dec 8, 2023
cb2d3af
fleshing out dialog for playblasting
Sasbom Dec 8, 2023
5699639
further refined playblast menu
Sasbom Dec 8, 2023
d36af8e
added destination selection
Sasbom Dec 8, 2023
49866d2
added pre and post hooks to later hook into with the turntable
Sasbom Dec 8, 2023
5143d37
updated playblast dialog with area to select purposes
Sasbom Dec 8, 2023
38937ef
fixed some things, added progress bar and actual playblast functional…
Sasbom Dec 8, 2023
2918587
modified PlayblastDialog to be more flexible when inheriting
Sasbom Dec 9, 2023
e2060d1
Complexity combobox fixed and moved to be above render engine, sepera…
Sasbom Dec 9, 2023
25b84a2
added support for camera path argument in turntable_from_file
Sasbom Dec 9, 2023
160a512
Added search for cameras in stage from file
Sasbom Dec 9, 2023
09e1809
Pass along RenderReportable in turntable
Sasbom Dec 9, 2023
a8c4d35
started implementing turntable dialog
Sasbom Dec 9, 2023
ec89f96
added functionality for updating camera from file when finished typing.
Sasbom Dec 10, 2023
d6ede87
make sure playblast button on turntable doesn't do anything as it's n…
Sasbom Dec 10, 2023
52400cc
logic pass TurntableDialog
Sasbom Dec 11, 2023
0a6763e
adress minor fuckup
Sasbom Dec 11, 2023
65ca6b3
exposed fit parameter to dialog for generated framing cameras
Sasbom Dec 11, 2023
0e309e6
aux functionality for rendering turntables, laid out functionality
Sasbom Dec 11, 2023
3a58851
implemented stage rotation turntable in dialog
Sasbom Dec 12, 2023
f47ab3b
implemented camera rotation in dialog
Sasbom Dec 12, 2023
006a688
added better cleanup for camera around stage turntable in dialog, fix…
Sasbom Dec 12, 2023
2bf24b8
implemented turntable from file
Sasbom Dec 12, 2023
ec8d45a
cleaned up render menu in editor
Sasbom Dec 12, 2023
b543b86
minor cleanup
Sasbom Dec 12, 2023
f68ae5f
small fixes
Sasbom Dec 12, 2023
2feabcd
First pass of cleanup.
Sasbom Dec 13, 2023
4d0e808
added context managers for managing open scenes and deleting files
Sasbom Dec 13, 2023
5e85507
ExitStack shenanigans
Sasbom Dec 13, 2023
c104d5d
ExitStack shenanigans part 2: the big bugfix
Sasbom Dec 13, 2023
5fbaccb
fixed potential -1 index on camera box in playblast dialog
Sasbom Dec 13, 2023
daf480f
removed unneeded import to weakref
Sasbom Dec 13, 2023
30463db
exposed select functions in `__all__` and added missing stage context…
Sasbom Dec 14, 2023
184cc32
fixed spacing from top
Sasbom Dec 14, 2023
7f0720c
removed unnessecary import
Sasbom Dec 14, 2023
c51e2af
modified size, disallowed resizing of playblast/turntable dialogs
Sasbom Dec 14, 2023
57828f6
bugfix, making sure that right parameters get passed around and that …
Sasbom Dec 14, 2023
f8ffa7a
Refactor imports
BigRoy Dec 19, 2023
98e34ea
Cosmetics
BigRoy Dec 21, 2023
2b5bda6
Cleanup code; cosmetics
BigRoy Dec 21, 2023
1982636
Cosmetics - move imports to top
BigRoy Dec 22, 2023
b46b563
Add todo
BigRoy Dec 22, 2023
52efa6f
Some code simplification - avoid the need for temporary files as much…
BigRoy Dec 22, 2023
2da2ca2
Revert some changes back to `main`
BigRoy Dec 22, 2023
ad35afb
Add clarifying comment
BigRoy Dec 22, 2023
004ebc8
Simplify preset file
BigRoy Dec 22, 2023
6a1c781
Remove debug print
BigRoy Dec 22, 2023
df6ec14
Improve naming / cosmetics
BigRoy Dec 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions assets/turntable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#### USD Turntable Presets And You

---
#### Turning tables

`usd-qtpy` supports the rendering of assets with a turntable preset.
This turntable preset is a USD file, that gets referenced along with a temporary
export of the scene itself.

By using a hierarchical structure that conforms to the standard, you too
can make a preset that turns your tables the exact way you wish your tables
to be turned.

#### Getting started

The turntable preset system requires the hierarchy to be laid out like so:

```
/
└─ turntable (Xform, default prim)
├─ scene (Xform)
│ │
| ├─ lights (Xform) (Optional)
│ │ └─ [all lights in scene]
│ │
│ ├─ camera (Camera pointing at your target)
│ │
│ └─ [some scene geometry] (Optional)
├─ parent (Xform, usually holds rotation animation)
└─ bounds (Xform) (Optional)
└─ [some invisible geometry that fits the bounds of your camera]

```

You can look at an example of a complete compliant hierarchy,
in `turntable_preset.usda`.
It isn't required to have a usda file, usd and usdc are supported as well.

##### Things that matter:
- `turntable` needs to be the default primitive
- Some Usd Camera needs to be present in the hierarchy
- `parent` must exist
- At least 1 `camera` exists somewhere (the first found camera will be used)

##### Things that don't matter:
- `bounds` doesn't have to exist
- `scene/lights` doesn't have to exist
- `camera` can be named anything and can exist everywhere in the hierarchy.

#### Functionality in the turntable system:
##### Bounds:
There are times where you are unsure whether assets will fit in the camera view.
This worry can be entirely mitigated by including the bounds Xform, with some
geometry in it that fills the camera view.

If `bounds` is present, the turntable will automagically fit the geometry
uniformly so that it fits the bounds of the geometry contained in this Xform.

##### Scene lights:
Scene lights can be included with any name in any order. These will be turned
off for GL renders, because GL renders are lit by default. The introduction
of lights would make the renders overexposed.

Should you still want to have lights regardless of the renderer being used,
just include them them in `scene`.

##### Parent:
This is where the subject of the turntable will end up,
and it's usually an Xform that holds rotation frames.

The subject is placed at the centroid and lower bound in the middle of the scene
automatically, meaning that you can place `parent` pretty much wherever you want
in the scene, the subject will inherit its transforms.

##### Limits (for now):
- USD attributes `endTimeCode` and `startTimeCode` are not able to be read,
I might attempt to parse the actual description of the USD scene in the future,
but for now, manual entry of start and end timecodes is needed.

##### Happy turntabling!
295 changes: 295 additions & 0 deletions assets/turntable/turntable_preset.usda

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ name = "usd-qtpy"
authors = [
{name = "BigRoy"},
{name = "Hannes"},
{name = "Sasbom"},
]
description = "Python Qt components for building custom USD tools."
readme = "README.md"
Expand Down
65 changes: 65 additions & 0 deletions usd_qtpy/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def __init__(self, stage, parent=None):
title = f"{title}: {name}"
self.setWindowTitle(title)

self._stage = stage

self.setWindowFlags(
self.windowFlags() |
QtCore.Qt.Dialog
Expand All @@ -49,8 +51,10 @@ def __init__(self, stage, parent=None):
splitter.addWidget(hierarchy_widget)

viewer_widget = None
self._stageview = None
if HAS_VIEWER:
viewer_widget = viewer.Widget(stage=stage)
self._stageview = viewer_widget.view
splitter.addWidget(viewer_widget)

prim_spec_editor_widget = prim_spec_editor.SpecEditorWindow(stage=stage)
Expand All @@ -75,6 +79,7 @@ def build_menubar(self):

menubar = QtWidgets.QMenuBar()

# Panels menu
panels_menu = menubar.addMenu("Panels")
for label, widget in self._panels.items():
action = panels_menu.addAction(label)
Expand All @@ -94,5 +99,65 @@ def update_panel_checkstate():

panels_menu.aboutToShow.connect(update_panel_checkstate)

if HAS_VIEWER:
self._build_render_menu(menubar)

layout = self.layout()
layout.setMenuBar(menubar)

def _build_render_menu(self, menubar):

# Import here because we only want to import this dependency
# if the viewer libraries exist
from . import render_util

# Render menu
render_menu = menubar.addMenu("Render")
labels = (
"Snapshot View",
"Snapshot Framing Camera",
"Playblast Stage",
"Turntable Stage"
)
actions = {label: render_menu.addAction(label) for label in labels}

def render_snap():
"""Render still frame from current view"""
# TODO: Allow picking resolution
filepath = render_util.prompt_output_path("Save frame")
if not filepath:
return
render_util.dialog.save_image_from_stageview(self._stageview,
filepath)

def render_snap_framed():
"""Render still frame from a 'framed camera'"""
filepath = render_util.prompt_output_path("Save frame with framing camera")
if not filepath:
return
stage = self._stage
camera = render_util.create_framing_camera_in_stage(stage, fit=1.1)
render_util.render_playblast(stage,
filepath,
"1",
1920,
renderer="GL",
camera=camera)
stage.RemovePrim(camera.GetPath())

def playblast_stage_dialog():
dialog = render_util.PlayblastDialog(self,
self._stage,
self._stageview)
dialog.show()

def turntable_stage_dialog():
dialog = render_util.TurntableDialog(self,
self._stage,
self._stageview)
dialog.show()

actions["Snapshot View"].triggered.connect(render_snap)
actions["Snapshot Framing Camera"].triggered.connect(render_snap_framed)
actions["Playblast Stage"].triggered.connect(playblast_stage_dialog)
actions["Turntable Stage"].triggered.connect(turntable_stage_dialog)
2 changes: 2 additions & 0 deletions usd_qtpy/lib/qt.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
import sys
import logging
from functools import wraps
from qtpy import QtCore, QtGui, QtWidgets


Expand Down Expand Up @@ -55,6 +56,7 @@ def report_error(fn):
`Tf.Notice` registry because those do not output the errors that occur.

"""
@wraps(fn) # keep signature and docstring of decorated function intact.
def wrap(*args, **kwargs):
try:
return fn(*args, **kwargs)
Expand Down
3 changes: 2 additions & 1 deletion usd_qtpy/lib/usd.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import defaultdict
from typing import Union

from pxr import Usd, Plug, Tf, Sdf
import logging
Expand Down Expand Up @@ -319,4 +320,4 @@ def remove_spec(spec):
spec.owner.RemoveVariant(spec)

else:
raise TypeError(f"Unsupported spec type: {spec}")
raise TypeError(f"Unsupported spec type: {spec}")
54 changes: 54 additions & 0 deletions usd_qtpy/render_util/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from .base import (
RenderReportable,
)
from .dialog import (
prompt_input_path,
prompt_output_path,
PlayblastDialog,
TurntableDialog,
)
from .framing_camera import (
get_stage_up,
create_framing_camera_in_stage,
camera_conform_sensor_to_aspect,
)
from .playblast import (
camera_from_stageview,
iter_stage_cameras,
get_file_cameras,
get_frames_string,
tuples_to_frames_string,
render_playblast,
)
from .turntable import (
create_turntable_xform,
create_turntable_camera,
get_turntable_frames_string,
turntable_from_preset
)


__all__ = [
"RenderReportable",

"prompt_input_path",
"prompt_output_path",
"PlayblastDialog",
"TurntableDialog",

"get_stage_up",
"create_framing_camera_in_stage",
"camera_conform_sensor_to_aspect",

"camera_from_stageview",
"iter_stage_cameras",
"get_file_cameras",
"get_frames_string",
"tuples_to_frames_string",
"render_playblast",

"create_turntable_xform",
"create_turntable_camera",
"get_turntable_frames_string",
"turntable_from_preset"
]
33 changes: 33 additions & 0 deletions usd_qtpy/render_util/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Provides mixins and classes to be inherited from, as well as decorators
import os
from contextlib import contextmanager
from typing import Union

from qtpy import QtCore
from pxr import Usd, Sdf


@contextmanager
def defer_file_deletion(path: str):
try:
yield None
finally:
os.remove(path)


@contextmanager
def defer_primpath_deletion(stage: Usd.Stage, path: Union[str, Sdf.Path]):
if isinstance(path, str):
path = Sdf.Path(path)
try:
yield None
finally:
stage.RemovePrim(path)


class RenderReportable:
"""
Mixin class to set up signals for everything needing slots.
"""
render_progress = QtCore.Signal(int)
total_frames = QtCore.Signal(int)
Loading