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 #30

Closed
wants to merge 101 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
101 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
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
Prev Previous commit
Next Next commit
implemented stage rotation turntable in dialog
  • Loading branch information
Sasbom committed Dec 12, 2023
commit 3a58851cb01de1d62167e21537800562e80b804f
3 changes: 2 additions & 1 deletion usd_qtpy/render_util/__init__.py
Original file line number Diff line number Diff line change
@@ -2,4 +2,5 @@
from .playblast import *
from .framing_camera import *
from .turntable import *
from .dialog import *
from .dialog import *
from .basecls import *
10 changes: 10 additions & 0 deletions usd_qtpy/render_util/basecls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Provides mixins and classes to be inherited from.

from qtpy import QtCore

class RenderReportable:
"""
Mixin class to set up signals for everything needing slots.
"""
render_progress: QtCore.Signal = QtCore.Signal(int)
total_frames: QtCore.Signal = QtCore.Signal(int)
157 changes: 137 additions & 20 deletions usd_qtpy/render_util/dialog.py
Original file line number Diff line number Diff line change
@@ -9,8 +9,10 @@
from pxr import Usd, UsdGeom, Sdf
from pxr.Usdviewq.stageView import StageView

from . import playblast, framing_camera
from . import playblast, framing_camera, turntable
from .basecls import RenderReportable
from ..resources import get_icon
from ..lib import usd


def _rectify_path_framenumberspec(path: str, padding: int = 4):
@@ -98,14 +100,6 @@ def _savepicture_dialog(stage: Usd.Stage,
stage.RemovePrim(camera.GetPath())


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


class PlayblastDialog(QtWidgets.QDialog, RenderReportable):
def __init__(self, parent: QtCore.QObject, stage: Usd.Stage, stageview: StageView = None) -> Any:
super(PlayblastDialog,self).__init__(parent=parent)
@@ -592,13 +586,14 @@ def populate_camera_combobox(self,
cam: UsdGeom.Camera
campath = cam.GetPath().pathString
cam_name = os.path.basename(campath)
cbox_camera.addItem(f"Cam: {cam_name}", cam_name)
cbox_camera.addItem(f"Cam: {cam_name}", Sdf.Path(campath))

cbox_camera.addItem("New: Framing Camera")
if self._has_viewer:
cbox_camera.addItem("New: Camera from View")
# cbox_camera.setDisabled(True)

cbox_camera.setCurrentIndex(0)
self.update_textfield_turntablefile(index)

def update_textfield_turntablefile(self, index: int = 0):
@@ -635,8 +630,8 @@ def frame_range_callback(self, formlayout: QtWidgets.QFormLayout):
formlayout.addRow("Starting Frame / Length", framerange_hlayout)

self.spinbox_loops = QtWidgets.QSpinBox()
self.spinbox_frame_length.setMinimum(1)
self.spinbox_frame_length.setMaximum(99)
self.spinbox_loops.setMinimum(1)
self.spinbox_loops.setMaximum(99)
formlayout.addRow("Repetitions", self.spinbox_loops)

def ui_pre_hook(self, vlayout: QtWidgets.QVBoxLayout):
@@ -676,21 +671,143 @@ def playblast_callback(self):
"""
Prevent playblast button from doing anything for now.
"""
turn_length = self.spinbox_frame_length.value()
frame_start = self.spinbox_frame_start.value()
repetition = self.spinbox_loops.value()

frames_string = turntable.get_turntable_frames_string(
turn_length,
frame_start,
repetition
)

fit = self.spinbox_fit.value()
width = self.spinbox_horresolution.value()
height = self.spinbox_verresolution.value()

render_path = self.txt_filename.text()
render_engine = self.cbox_renderer.currentText()

ttable_type = self.cbox_turntable_type.currentIndex()
if ttable_type == 0:
# Rotate camera around scene
...
elif ttable_type == 1:
# Group scene into Xform temporarily,
# make the Xform spin,
# generate framing camera
# render
# ungroup from Xform
# remove framing camera and temp root Xform
...
# Create temporary stage where the entire stage rotates in front
# of a camera

# make temporary folder to cache current subject session to.
if not os.path.isdir("./temp"):
os.mkdir("./temp")

# collect info about subject
subject_upaxis = framing_camera.get_stage_up(self._stage)
subject_zup = subject_upaxis == "Z"

# export subject
subject_filename = R"./temp/subject.usda"
subject_filename = os.path.abspath(subject_filename)

self._stage.Export(subject_filename)

assemble_stage = Usd.Stage.CreateInMemory()
UsdGeom.SetStageUpAxis(assemble_stage,subject_upaxis)

bounds = framing_camera.get_stage_boundingbox(self._stage)

# Put stage in turntable primitive.
turntable_xform = turntable\
.create_turntable_subject_bounds_xform(
assemble_stage,
bounds,
"/",
"turntabledialog_xform",
turn_length,
frame_start,
repetition)
# reference root in stage
root_override= assemble_stage\
.OverridePrim("/turntabledialog_xform/root")
root_override.GetReferences().AddReference(subject_filename)

path: Sdf.Path = self.cbox_camera.currentData()
camera_state = None

# get camera states, to create a valid camera in in-memory stage.

if path:
# take new root into account, split off the old scene root.
print("not generated cam",path.pathString)
# TODO: support animated cameras from scene?
# grab camera state
camera_stage = self._stage.GetPrimAtPath(path)
camera_geom = UsdGeom.Camera(camera_stage)
camera_state = camera_geom.GetCamera(frame_start)
else:
if "New: Framing Camera" in self.cbox_camera.currentText():
cam = framing_camera\
.create_framing_camera_in_stage(self._stage,
"/",
"framingcam",
fit,
width,
height
)
camera_state = cam.GetCamera(frame_start)
self._stage.RemovePrim(cam.GetPath())
elif "New: Camera from View" in self.cbox_camera.currentText():
cam = playblast.camera_from_stageview(self._stage,
self._stageview,
"viewcam")
camera_state = cam.GetCamera(frame_start)
self._stage.RemovePrim(cam.GetPath())

render_camera: UsdGeom.Camera = None
render_camera_name = "turntabledialog_cam"

# use camera state to generate proper camera in assemble_stage
render_camera = UsdGeom.Camera\
.Define(assemble_stage,f"/{render_camera_name}")
render_camera.SetFromCamera(camera_state)

render_camera = framing_camera.camera_conform_sensor_to_aspect(
render_camera,
width,
height
)

# We should now have an assembled stage.

real_stage_filename = R"./temp/turntable_assembly.usd"
real_stage_filename = os.path.abspath(real_stage_filename)

assemble_stage.Export(real_stage_filename)
del assemble_stage

real_stage = Usd.Stage.Open(real_stage_filename)
render_camera = real_stage.GetPrimAtPath(f"/{render_camera_name}")
render_camera = UsdGeom.Camera(render_camera)

playblast.render_playblast(real_stage,
render_path,
frames=frames_string,
width=width,
camera=render_camera,
renderer=render_engine,
qt_report_instance=self)

# cleanup
# unload real_stage from memory forcibly so file can be deleted.
del real_stage

os.remove(subject_filename)
os.remove(real_stage_filename)

self.progressbar.setFormat("Rendered %v frames!")

elif ttable_type == 2:
# turntable from file routine.
...


raise NotImplementedError()
# raise NotImplementedError()
23 changes: 23 additions & 0 deletions usd_qtpy/render_util/framing_camera.py
Original file line number Diff line number Diff line change
@@ -78,6 +78,29 @@ def create_perspective_camera_in_stage(stage: Usd.Stage,
return camera


def camera_conform_sensor_to_aspect(camera: UsdGeom.Camera,
width: int = 16,
height: int = 9) -> UsdGeom.Camera:
"""
Conforms an existing camera's sensor size to render with desired dimensions
"""

aspect_ratio: float = width / float(height)

# Focus at infinity
camera.CreateFocusDistanceAttr(168.60936)
camera.CreateFStopAttr(0)

# Aperture size (24) is based on the size of a full frame SLR camera sensor
# https://en.wikipedia.org/wiki/Image_sensor_format#Common_image_sensor_formats
camera.CreateHorizontalApertureAttr(24 * aspect_ratio)
camera.CreateHorizontalApertureOffsetAttr(0)
camera.CreateVerticalApertureAttr(24)
camera.CreateVerticalApertureOffsetAttr(0)

return camera


def _orient_to_z_up(xformable: UsdGeom.Xformable):
"""Rotate around X-axis by 90 degrees to orient for Z-up axis."""
xformable.AddRotateXOp(UsdGeom.XformOp.PrecisionDouble).Set(90)
4 changes: 2 additions & 2 deletions usd_qtpy/render_util/playblast.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
from pxr import Tf, Sdf, Usd, UsdGeom, UsdAppUtils
from pxr.Usdviewq.stageView import StageView

from . import dialog
from .basecls import RenderReportable

def _setup_opengl_widget(width: int, height: int, samples: int = 4):
"""
@@ -178,7 +178,7 @@ def render_playblast(stage: Usd.Stage,
renderer: str = None,
colormode: str = "sRGB",
purposes: list[str] = None,
qt_report_instance: dialog.RenderReportable = None
qt_report_instance: RenderReportable = None
) -> list[str]:
"""
Render one or multiple frames from a usd stage's camera.
53 changes: 47 additions & 6 deletions usd_qtpy/render_util/turntable.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,8 @@
from pxr import Usd, UsdGeom, Sdf, Gf
from qtpy import QtCore

from . import framing_camera, playblast, dialog
from . import framing_camera, playblast
from .basecls import RenderReportable
from ..layer_editor import LayerTreeWidget, LayerStackModel
from ..lib import usd

@@ -48,6 +49,44 @@ def create_turntable_xform(stage: Usd.Stage,

return xform

def create_turntable_subject_bounds_xform(stage: Usd.Stage,
bounds: Gf.Range3d,
path: Union[Sdf.Path, str],
name: str = "turntableXform",
length: int = 100,
frame_start: int = 0,
repeats: int = 1) -> UsdGeom.Xform:
"""
Creates a turntable Xform that contains animation spinning around the up axis, in the center floor of the stage.
We repeat the entire duration when repeats are given as an arguement.
A length of 100 with 3 repeats will result in a 300 frame long sequence
"""
from pxr.UsdGeom import XformOp

if isinstance(path, str):
path = Sdf.Path(path)

path = path.AppendPath(name)

is_z_up = framing_camera.get_stage_up(stage) == "Z"

#bounds = framing_camera.get_stage_boundingbox(stage)
centroid = bounds.GetMidpoint()

xform = UsdGeom.Xform.Define(stage, path)

if is_z_up:
translate = Gf.Vec3d(centroid[0], centroid[1], 0) # Z axis = floor normal
else:
translate = Gf.Vec3d(centroid[0], 0, centroid[2]) # Y axis = floor normal

# Move to centroid of bounds, rotate, move back to origin
xform.AddTranslateOp(XformOp.PrecisionDouble, "rotPivot").Set(translate)
add_turntable_spin_op(xform, length, frame_start, repeats, is_z_up)
xform.AddTranslateOp(XformOp.PrecisionDouble, "rotPivot", isInverseOp=True)

return xform


def create_turntable_camera(stage: Usd.Stage,
root: Union[Sdf.Path, str] = Sdf.Path("/"),
@@ -113,8 +152,10 @@ def pack_stage_root_to_prim(stage: Usd.Stage, goal_prim: Usd.Prim):
Move children of stage root to a primitive.
"""
stage_root = stage.GetPseudoRoot()
children: list[Usd.Prim] = list(stage_root.GetAllChildren())

children: list[Usd.Prim] = list(stage_root.GetChildren())
# filter children
children = [c for c in children
if not c.GetPath().pathString == goal_prim.GetPath().pathString]
usd.parent_prims(children, goal_prim.GetPath())


@@ -124,7 +165,7 @@ def unpack_prim_to_stage_root(stage: Usd.Stage, from_prim: Usd.Prim):
"""
stage_root = stage.GetPseudoRoot()
children: list[Usd.Prim] = list(from_prim.GetAllChildren())

usd.parent_prims(children,stage_root.GetPath())


@@ -136,7 +177,7 @@ def turntable_from_file(stage: Usd.Stage,
frame_start: int = 1,
repeats: int = 1,
camera_path : Union[str, Sdf.Path] = None,
qt_report_instance: dialog.RenderReportable = None):
qt_report_instance: RenderReportable = None):
"""
#### STILL UNDER CONSTRUCTION

@@ -289,7 +330,7 @@ def turntable_from_file(stage: Usd.Stage,
if lights_prim.IsValid():
lights_prim.GetAttribute("visibility").Set("invisible",0)

realstage_filename = R"./temp/test_turntable_fit.usd"
realstage_filename = R"./temp/turntable_assembly.usd"
realstage_filename = os.path.abspath(realstage_filename)

ttable_stage.Export(realstage_filename)