Skip to content

Commit

Permalink
Correctly skip deleting/grouping prims inside references/payloads
Browse files Browse the repository at this point in the history
  • Loading branch information
BigRoy committed Dec 4, 2023
1 parent 7bf2ea9 commit dfebdca
Showing 1 changed file with 47 additions and 3 deletions.
50 changes: 47 additions & 3 deletions usd_qtpy/prim_hierarchy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from functools import partial

from qtpy import QtWidgets, QtCore
Expand All @@ -16,6 +17,8 @@
from .references import ReferenceListWidget
from .variants import CreateVariantSetDialog

log = logging.getLogger(__name__)


class View(QtWidgets.QTreeView):
# TODO: Add shortcuts
Expand Down Expand Up @@ -274,16 +277,46 @@ def _group_selected(self):
return

stage = prims[0].GetStage()

# Consider only prims that have opinions in the stage's layer stack
# disregard opinions inside payloads/references
stage_layers = set(stage.GetLayerStack())

# Exclude prims not defined in the stage's layer stack
prims = [
prim for prim in prims
if any(spec.layer in stage_layers for spec in prim.GetPrimStack())
]
if not prims:
log.warning("Skipped all prims because they are not defined in "
"the stage's layer stack but likely originate from a "
"reference or payload.")
return

parent_path = prims[0].GetPath().GetParentPath()

group_path = parent_path.AppendChild("group")
group_path = unique_name(stage, group_path)

# Define a group
group = stage.DefinePrim(group_path, "Xform")
stage.DefinePrim(group_path, "Xform")

# We want to group across all prim specs to ensure whatever we're
# moving gets put into the group, so we define the prim across all
# layers of the layer stack if it contains any of the objects
for layer in stage.GetLayerStack():
# If the layer has opinions on any of the source prims we ensure
# the new parent also exists, to ensure the movement of the input
# prims
if (
any(layer.GetObjectAtPath(prim.GetPath())
for prim in prims)
and not layer.GetPrimAtPath(group_path)
):
Sdf.CreatePrimInLayer(layer, group_path)

# Now we want to move all selected prims into this
parent_prims(prims, group.GetPath())
parent_prims(prims, group_path)

# If the original group was renamed but there's now no conflict
# anymore, e.g. we grouped `group` itself from the parent path
Expand All @@ -301,11 +334,22 @@ def _delete_selected(self):
if not prims:
return

stage = prims[0].GetStage()
stage_layers = stage.GetLayerStack()

# We first collect the prim specs before removing because the Usd.Prim
# will become invalid as we start removing specs
specs = []
for prim in prims:
specs.extend(prim.GetPrimStack())
# We only allow deletions from layers in the current layer stack
# and exclude those that are from loaded references/payloads to
# avoid editing specs inside references/layers
for spec in prim.GetPrimStack():
if spec.layer in stage_layers:
specs.append(spec)
else:
logging.warning("Skipping prim spec not in "
"stage's layer stack: %s", spec)

with Sdf.ChangeBlock():
for spec in specs:
Expand Down

0 comments on commit dfebdca

Please sign in to comment.