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

Support Python3 for Pixar's UsdMaya and unit tests #555

Merged
merged 11 commits into from
Jun 15, 2020
7 changes: 0 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,6 @@ message(STATUS " PYTHON_INCLUDE_DIRS = ${PYTHON_INCLUDE_DIRS}")
message(STATUS " PYTHON_LIBRARIES = ${PYTHON_LIBRARIES}")
message(STATUS " Python_EXECUTABLE = ${Python_EXECUTABLE}")

# The building of the schemas requires some extra python packages which may or
# may not be installed. If they aren't we provide an option to add them from
# a python egg.
if (BUILD_USDMAYA_SCHEMAS)
include(cmake/jinja.cmake)
endif()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seando-adsk This was a bit of a surprise since this code never is called when the clean build happens.

BUILD_USDMAYA_SCHEMAS is an option that is set in AL. This value is not cached until AL's CmakeLists is called which happens later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what happened is when we moved some schema stuff from AL into core we moved this. But we forgot to move the option. Shouldn't we leave this here and move the option under line 35?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had actually started looking into that once, but got side tracked. I think we should fix this schema stuff in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I had to take it out eventually since I was getting bunch of weird issues with Python 3 when doing incremental builds. Let's revisit this together.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized that this needs to remain here. From the Maya build and our internal ecg-maya-usd repo we are setting this flag "BUILD_USDMAYA_SCHEMAS=ON" and providing the jinja/markupsafe locations. The jinja.cmake will check to see if jinja2 and markupsafe are part of the python executable. If not, then it will add them to the python path from the locations provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find_package(Maya 2018 REQUIRED)
find_package(USD REQUIRED)
include(cmake/usd.cmake)
Expand Down
4 changes: 4 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def PrintError(error):
traceback.print_exc()
print("ERROR:", error)

def Python3():
return sys.version_info.major == 3
############################################################
def Windows():
return platform.system() == "Windows"
Expand Down Expand Up @@ -558,6 +560,7 @@ def __init__(self, args):
Build directory {buildDir}
Install directory {instDir}
Variant {buildVariant}
Python 3: {enablePython3}
Python Debug {debugPython}
CMake generator {cmakeGenerator}"""

Expand Down Expand Up @@ -588,6 +591,7 @@ def __init__(self, args):
ctestArgs=context.ctestArgs,
buildVariant=BuildVariant(context),
debugPython=("On" if context.debugPython else "Off"),
enablePython3=("On" if Python3() else "Off"),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple change to output Python3 state in the output console.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only to indicate that the build.py was called with Python 3 - right? Not that we are actually building python 3 bindings. That is still controlled by the cmake option "BUILD_WITH_PYTHON_3"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seando-adsk Correct, just a simple indication in the output console:

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @seando-adsk's point was that that's indicating that build.py itself is running using Python 3, and not necessarily indicating that you're building for Python 3. You could run build.py using Python 3 but still be building maya-usd for Python 2, in which case that indicator might be misleading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I already realized that :) I agree with you that this could be misleading and in fact in my mind was thinking to change it. something for another day.

cmakeGenerator=("Default" if not context.cmakeGenerator
else context.cmakeGenerator)
)
Expand Down
34 changes: 20 additions & 14 deletions cmake/modules/FindMaya.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -239,21 +239,7 @@ find_program(MAYA_EXECUTABLE
"Maya's executable path"
)

find_program(MAYA_PY_EXECUTABLE
mayapy
HINTS
"${MAYA_LOCATION}"
"$ENV{MAYA_LOCATION}"
"${MAYA_BASE_DIR}"
PATH_SUFFIXES
Maya.app/Contents/bin/
bin/
DOC
"Maya's Python executable path"
)

if(MAYA_INCLUDE_DIRS AND EXISTS "${MAYA_INCLUDE_DIR}/maya/MTypes.h")

# Tease the MAYA_API_VERSION numbers from the lib headers
file(STRINGS ${MAYA_INCLUDE_DIR}/maya/MTypes.h TMP REGEX "#define MAYA_API_VERSION.*$")
string(REGEX MATCHALL "[0-9]+" MAYA_API_VERSION ${TMP})
Expand All @@ -265,9 +251,29 @@ if(MAYA_INCLUDE_DIRS AND EXISTS "${MAYA_INCLUDE_DIR}/maya/MTypes.h")
else()
string(SUBSTRING ${MAYA_API_VERSION} "0" "4" MAYA_APP_VERSION)
endif()
endif()

# swtich between mayapy and mayapy2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor typo "switch"

set(mayapy_exe mayapy)
if(${MAYA_APP_VERSION} STRGREATER_EQUAL "2021")
if(NOT BUILD_WITH_PYTHON_3)
set(mayapy_exe mayapy2)
endif()
endif()

find_program(MAYA_PY_EXECUTABLE
${mayapy_exe}
HINTS
"${MAYA_LOCATION}"
"$ENV{MAYA_LOCATION}"
"${MAYA_BASE_DIR}"
PATH_SUFFIXES
Maya.app/Contents/bin/
bin/
DOC
"Maya's Python executable path"
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a switch to handle mayapy executable name in dual Maya python.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great.

# handle the QUIETLY and REQUIRED arguments and set MAYA_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
Expand Down
1 change: 0 additions & 1 deletion plugin/pxr/cmake/macros/Public.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ function(pxr_setup_python)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/__init__.py
${CMAKE_CURRENT_BINARY_DIR}/__init__.pyc
DESTINATION
${INSTALL_DIR_SUFFIX}/${installPrefix}
)
Expand Down
12 changes: 6 additions & 6 deletions plugin/pxr/cmake/macros/compilePython.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import py_compile

if len(sys.argv) < 4:
print "Usage: %s src.py file.py file.pyc" % sys.argv[0]
print("Usage: %s src.py file.py file.pyc" % sys.argv[0])
sys.exit(1)

try:
Expand All @@ -45,14 +45,14 @@
try:
linenumber = exc_value[1][1]
line = exc_value[1][3]
print '%s:%s: %s: "%s"' % (sys.argv[1], linenumber, error, line)
print('%s:%s: %s: "%s"' % (sys.argv[1], linenumber, error, line))
except IndexError:
print '%s: Syntax error: "%s"' % (sys.argv[1], error)
print('%s: Syntax error: "%s"' % (sys.argv[1], error))
else:
print "%s: Unhandled compile error: (%s) %s" % (
sys.argv[1], compileError.exc_type_name, exc_value)
print("%s: Unhandled compile error: (%s) %s" % (
sys.argv[1], compileError.exc_type_name, exc_value))
sys.exit(1)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
print "%s: Unhandled exception: %s" % (sys.argv[1], exc_value)
print("%s: Unhandled exception: %s" % (sys.argv[1], exc_value))
sys.exit(1)
16 changes: 8 additions & 8 deletions plugin/pxr/cmake/macros/testWrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ def _windowsReplacement(m):

def _cleanOutput(pathPattern, fileName, verbose):
if verbose:
print "stripping path pattern {0} from file {1}".format(pathPattern,
fileName)
print("stripping path pattern {0} from file {1}".format(pathPattern,
fileName))
_stripPath(fileName, pathPattern)
return True

Expand All @@ -137,7 +137,7 @@ def _diff(fileName, baselineDir, verbose):
diff = '/usr/bin/diff'
cmd = [diff, _resolvePath(baselineDir, fileName), fileName]
if verbose:
print "diffing with {0}".format(cmd)
print("diffing with {0}".format(cmd))

# This will print any diffs to stdout which is a nice side-effect
return subprocess.call(cmd) == 0
Expand Down Expand Up @@ -181,7 +181,7 @@ def _runCommand(raw_command, stdout_redir, stderr_redir, env,
cmd = _splitCmd(raw_command)
fout, ferr = _getRedirects(stdout_redir, stderr_redir)
try:
print "cmd: %s" % (cmd, )
print("cmd: %s" % (cmd, ))
retcode = _convertRetCode(subprocess.call(cmd, shell=False, env=env,
stdout=(fout or sys.stdout),
stderr=(ferr or sys.stderr)))
Expand Down Expand Up @@ -217,13 +217,13 @@ def _runCommand(raw_command, stdout_redir, stderr_redir, env,
testDir = tempfile.mkdtemp()
os.chdir(testDir)
if args.verbose:
print "chdir: {0}".format(testDir)
print("chdir: {0}".format(testDir))

# Copy the contents of the testenv directory into our test run directory so
# the test has it's own copy that it can reference and possibly modify.
if args.testenv_dir and os.path.isdir(args.testenv_dir):
if args.verbose:
print "copying testenv dir: {0}".format(args.testenv_dir)
print("copying testenv dir: {0}".format(args.testenv_dir))
try:
_copyTree(args.testenv_dir, os.getcwd())
except Exception as e:
Expand Down Expand Up @@ -273,7 +273,7 @@ def _runCommand(raw_command, stdout_redir, stderr_redir, env,
if args.files_exist:
for f in args.files_exist:
if args.verbose:
print 'checking if {0} exists.'.format(f)
print('checking if {0} exists.'.format(f))
if not os.path.exists(f):
sys.stderr.write('Error: {0} does not exist '
'(FILES_EXIST).'.format(f))
Expand All @@ -282,7 +282,7 @@ def _runCommand(raw_command, stdout_redir, stderr_redir, env,
if args.files_dont_exist:
for f in args.files_dont_exist:
if args.verbose:
print 'checking if {0} does not exist.'.format(f)
print('checking if {0} does not exist.'.format(f))
if os.path.exists(f):
sys.stderr.write('Error: {0} does exist '
'(FILES_DONT_EXIST).'.format(f))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.
#

from future.utils import iteritems

from pxr import UsdMaya

from pxr import Tf
Expand Down Expand Up @@ -47,7 +49,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
statsOutputLines = []
for profileScopeName, elapsedTime in cls._profileScopeMetrics.iteritems():
for profileScopeName, elapsedTime in iteritems(cls._profileScopeMetrics):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In python3, dict.iteritems is no longer available. Using python.future function iteritems()

Note: mayapy shipped with Maya already comes with future package installed

statsDict = {
'profile': profileScopeName,
'metric': 'time',
Expand Down Expand Up @@ -131,7 +133,7 @@ def _RunPlaybackTest(self):
profileScopeName = '%s Proxy Orbit Playback Time' % self._testName

with self._ProfileScope(profileScopeName):
for frame in xrange(int(self.animStartTime), int(self.animEndTime + 1.0)):
for frame in range(int(self.animStartTime), int(self.animEndTime + 1.0)):
cmds.currentTime(frame, edit=True)

playElapsedTime = self._profileScopeMetrics[profileScopeName]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.
#

from future.utils import iteritems

from pxr import UsdMaya

from pxr import Tf
Expand Down Expand Up @@ -45,7 +47,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
statsOutputLines = []
for profileScopeName, elapsedTime in cls._profileScopeMetrics.iteritems():
for profileScopeName, elapsedTime in iteritems(cls._profileScopeMetrics):
statsDict = {
'profile': profileScopeName,
'metric': 'time',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.
#

from future.utils import iteritems

from pxr import UsdMaya

from pxr import Gf
Expand Down Expand Up @@ -109,7 +111,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
statsOutputLines = []
for profileScopeName, elapsedTime in cls._profileScopeMetrics.iteritems():
for profileScopeName, elapsedTime in iteritems(cls._profileScopeMetrics):
statsDict = {
'profile': profileScopeName,
'metric': 'time',
Expand Down
4 changes: 2 additions & 2 deletions plugin/pxr/maya/lib/pxrUsdMayaGL/testenv/testPxrUsdMayaGL.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def testSimpleSceneDrawsAndReloads(self):
# a memory issue would sometimes cause maya to crash when opening a new
# scene.

for _ in xrange(20):
for _ in range(20):
cmds.file(new=True, force=True)
for i in xrange(10):
for i in range(10):
usdFilePath = os.path.abspath('plane%d.usda' % (i%2))
assembly = cmds.assembly(name='plane', type='pxrUsdReferenceAssembly')
cmds.setAttr("%s.filePath" % assembly, usdFilePath, type='string')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def variantSets_Replace(nodeAttr, new):

try:
cmds.optionMenuGrp(omg, e=True, value=variantOverride)
except RuntimeError, e:
except (RuntimeError, e):
cmds.warning('Invalid choice %r for %r'%(variantOverride, variantSetName))

cmds.optionMenuGrp(omg, e=True, changeCommand=functools.partial(variantSets_changeCommmand, omg=omg, node=node, variantSetName=variantSetName))
Expand Down
2 changes: 1 addition & 1 deletion plugin/pxr/maya/lib/usdMaya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def LoadReferenceAssemblies(parentNodes=None):
isInterruptable=True, minValue=0, maxValue=numRefAssemblies,
status='Loading USD reference assemblies...')

for i in xrange(numRefAssemblies):
for i in range(numRefAssemblies):
refAssembly = refAssemblies[i]

if mainProgressBar:
Expand Down
8 changes: 4 additions & 4 deletions plugin/pxr/maya/lib/usdMaya/testenv/testUsdExportAsClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def setUpClass(cls):

cmds.file(os.path.abspath('UsdExportAsClipTest.ma'), open=True,
force=True)
print os.path.abspath('UsdExportAsClipTest.ma')
print(os.path.abspath('UsdExportAsClipTest.ma'))

cmds.loadPlugin('pxrUsd', quiet=True)

Expand All @@ -55,9 +55,9 @@ def getValues(stage):
cube = stage.GetPrimAtPath(primPath)
self.assertTrue(cube)
attr = cube.GetAttribute(attrName)
return [attr.Get(time=tc) for tc in xrange(*frameRange)]
return [attr.Get(time=tc) for tc in range(*frameRange)]

for frame, x,y in zip(xrange(*frameRange),
for frame, x,y in zip(range(*frameRange),
getValues(canonicalStage),
getValues(testStage)):
msg = ('different values found on frame: {frame}\n'
Expand Down Expand Up @@ -116,7 +116,7 @@ def testExportAsClip(self):
canonicalUsdFile = os.path.abspath('canonical.usda')
cmds.usdExport(mergeTransformAndShape=True, file=canonicalUsdFile, frameRange=(1, 20))

print 'comparing: \nnormal: {}\nstitched: {}'.format(canonicalUsdFile, stitchedPath)
print('comparing: \nnormal: {}\nstitched: {}'.format(canonicalUsdFile, stitchedPath))
canonicalStage = Usd.Stage.Open(canonicalUsdFile)
clipsStage = Usd.Stage.Open(stitchedPath)
# visible
Expand Down
4 changes: 2 additions & 2 deletions plugin/pxr/maya/lib/usdMaya/testenv/testUsdExportColorSets.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,15 +369,15 @@ def _GetExpectedColorSetIndices(self, colorSetName):
else:
# Every component has an assignment.
if isFaceColor:
assignmentIndices = [i for i in xrange(self._colorSetSourceMesh.numPolygons())]
assignmentIndices = [i for i in range(self._colorSetSourceMesh.numPolygons())]
elif isVertexColor:
# The assignments for vertex color are a little different
# due to MItMeshFaceVertex visiting components in faceVertex
# order, in which case we actually visit vertices somewhat
# out of order.
assignmentIndices = [0, 1, 3, 2, 5, 4, 7, 6]
elif isFaceVertexColor:
assignmentIndices = [i for i in xrange(self._colorSetSourceMesh.numFaceVertices())]
assignmentIndices = [i for i in range(self._colorSetSourceMesh.numFaceVertices())]

return assignmentIndices

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.
#

from future.utils import iteritems

import os
import unittest

Expand Down Expand Up @@ -44,9 +46,9 @@ def assertRotateSamples(self, usdFile, expected):
xform = stage.GetPrimAtPath('/pCube1')
rot = xform.GetProperty('xformOp:rotateXYZ')

for time, expectedVec in expected.iteritems():
for time, expectedVec in iteritems(expected):
actualVec = rot.Get(time)
for i in xrange(3):
for i in range(3):
msg = "sample at time {}, index {} unequal".format(time, i)
self.assertAlmostEqual(actualVec[i], expectedVec[i], 4, msg)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.
#

from future.utils import iteritems

import os
import unittest

Expand Down Expand Up @@ -91,8 +93,8 @@ def doExportImportOneMethod(self, method, constraint=True, place3d=True,
if filter:
options['filterTypes'] = ','.join(filter)
kwargs['options'] = ';'.join('{}={}'.format(key, val)
for key, val in options.iteritems())
print "running: {}(*{!r}, **{!r})".format(exportMethod.__name__, args, kwargs)
for key, val in iteritems(options))
print("running: {}(*{!r}, **{!r})".format(exportMethod.__name__, args, kwargs))
exportMethod(*args, **kwargs)
return Usd.Stage.Open(usdFile)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def testExportInstances(self):
self.assertEqual(ref.primPath, i)

# Test that the InstanceSources prim is last in the layer's root prims.
rootPrims = layer.rootPrims.keys()
rootPrims = list(layer.rootPrims.keys())
self.assertEqual(rootPrims[-1], "InstanceSources")

def testExportInstances_ModelHierarchyValidation(self):
Expand Down
4 changes: 2 additions & 2 deletions plugin/pxr/maya/lib/usdMaya/testenv/testUsdExportMesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def tearDownClass(cls):

def _AssertVec3fArrayAlmostEqual(self, arr1, arr2):
self.assertEqual(len(arr1), len(arr2))
for i in xrange(len(arr1)):
for j in xrange(3):
for i in range(len(arr1)):
for j in range(3):
self.assertAlmostEqual(arr1[i][j], arr2[i][j], places=3)

def testExportAsCatmullClark(self):
Expand Down
Loading