Skip to content

Commit 66e0f3e

Browse files
authored
Merge pull request #4387 from Autodesk/bailp/EMSUSD-2767/list-cameras
EMSUSD-2767 support cameras with identical names
2 parents c43de2b + f75da61 commit 66e0f3e

File tree

3 files changed

+91
-16
lines changed

3 files changed

+91
-16
lines changed

plugin/adsk/scripts/mayaUsd_exportHelpers.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,38 @@ def removeHiddenInOutliner(allItems):
1919
def updateDefaultPrimCandidates(excludeMesh, excludeLight, excludeCamera, excludeStage):
2020
allItems = cmds.ls(assemblies=True)
2121
excludeList = []
22+
23+
def add_excluded(items):
24+
for m in items:
25+
rel = cmds.listRelatives(m, parent=True, fullPath=True)[0]
26+
excludeList.append(m)
27+
excludeList.append(rel)
28+
if rel.startswith("|"):
29+
excludeList.append((rel.removeprefix("|")))
30+
2231
if excludeMesh == "1":
23-
meshes = cmds.ls(type=('mesh'), l=True)
24-
for m in meshes:
25-
excludeList.append(cmds.listRelatives(m, parent=True)[0])
32+
add_excluded(cmds.ls(type=('mesh'), l=True))
2633

2734
if excludeLight == "1":
28-
lights = cmds.ls(type=('light'), l=True)
29-
for l in lights:
30-
excludeList.append(cmds.listRelatives(l, parent=True)[0])
35+
add_excluded(cmds.ls(type=('light'), l=True))
3136

3237
if excludeCamera == "1":
33-
cameras = cmds.ls(type=('camera'), l=True)
34-
for c in cameras:
35-
excludeList.append(cmds.listRelatives(c, parent=True)[0])
38+
add_excluded(cmds.ls(type=('camera'), l=True))
3639
else:
40+
# Note: we still want to exclude the startup cameras even if
41+
# excludeCamera is not set, to avoid exporting them by mistake.
3742
cameras = cmds.ls(type=('camera'), l=True)
3843
startup_cameras = []
3944
for c in cameras:
40-
if cmds.camera(cmds.listRelatives(c, parent=True)[0], startupCamera=True, q=True):
41-
startup_cameras.append(cmds.listRelatives(c, parent=True)[0])
45+
camRelatives = cmds.listRelatives(c, parent=True, fullPath=True)
46+
if cmds.camera(camRelatives[0], startupCamera=True, q=True):
47+
startup_cameras.append(camRelatives[0])
4248

49+
startup_cameras.extend([c.removeprefix("|") for c in startup_cameras])
4350
allItems = list(set(allItems) - set(startup_cameras))
4451

4552
if excludeStage == "1":
46-
stages = cmds.ls(type=('mayaUsdProxyShape'), l=True)
47-
for st in stages:
48-
excludeList.append(st)
49-
excludeList.append(cmds.listRelatives(st, parent=True)[0])
53+
add_excluded(cmds.ls(type=('mayaUsdProxyShape'), l=True))
5054

5155
allItems = removeHiddenInOutliner(list(set(allItems) - set(excludeList)))
5256
allItems.sort(key=natural_key)
@@ -74,7 +78,7 @@ def _addExclusions(nodeType, excludeParent=False):
7478
nodes = cmds.ls(type=(nodeType), l=True)
7579
for n in nodes:
7680
if excludeParent:
77-
excludeSet.add(cmds.listRelatives(n, parent=True)[0])
81+
excludeSet.add(cmds.listRelatives(n, parent=True, fullPath=True)[0])
7882
path = _getRelatives(n)
7983
if not path:
8084
continue

test/lib/usd/translators/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(TEST_SCRIPT_FILES
77
testUsdExportBlendshapes.py
88
testUsdExportCamera.py
99
testUsdExportCameraAttrSpline.py
10+
testUsdExportCameraSameName.py
1011
testUsdExportColorSets.py
1112
testUsdExportConnected.py
1213
testUsdExportDefaultPrim.py
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env mayapy
2+
#
3+
# Copyright 2025 Autodesk
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
import os
19+
import unittest
20+
21+
from pxr import Usd
22+
from pxr import UsdGeom
23+
24+
from maya import cmds
25+
from maya import standalone
26+
27+
import fixturesUtils
28+
29+
class testUsdExportCameraWithSameName(unittest.TestCase):
30+
31+
@classmethod
32+
def setUpClass(cls):
33+
fixturesUtils.setUpClass(__file__)
34+
35+
@classmethod
36+
def tearDownClass(cls):
37+
standalone.uninitialize()
38+
39+
def testExportMultiCameras(self):
40+
"""
41+
Test that having multiple cameras with the same name and exporting
42+
by specifying a camera node name works. It used to fail because we
43+
would confuse both cameras.
44+
"""
45+
cmds.file(force=True, new=True)
46+
47+
# create a camera and group it
48+
cmds.camera()
49+
cmds.rename('cam')
50+
cmds.group(name='backup')
51+
52+
# create a second camera with the same name
53+
cmds.camera()
54+
cmds.rename('cam')
55+
56+
# export it to USD
57+
usdFilePath = os.path.abspath('UsdExportCameraTest.usda')
58+
if os.path.exists(usdFilePath):
59+
os.remove(usdFilePath)
60+
cmds.usdExport("|cam", file=usdFilePath)
61+
stage = Usd.Stage.Open(usdFilePath)
62+
self.assertTrue(stage)
63+
64+
# Verify the camera in USD
65+
cam = UsdGeom.Camera.Get(stage, '/cam')
66+
self.assertTrue(cam)
67+
68+
69+
if __name__ == '__main__':
70+
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)