1#!/pxrpythonsubst
2#
3# Copyright 2016 Pixar
4#
5# Licensed under the Apache License, Version 2.0 (the "Apache License")
6# with the following modification; you may not use this file except in
7# compliance with the Apache License and the following modification to it:
8# Section 6. Trademarks. is deleted and replaced with:
9#
10# 6. Trademarks. This License does not grant permission to use the trade
11#    names, trademarks, service marks, or product names of the Licensor
12#    and its affiliates, except as required to comply with Section 4(c) of
13#    the License and to reproduce the content of the NOTICE file.
14#
15# You may obtain a copy of the Apache License at
16#
17#     http://www.apache.org/licenses/LICENSE-2.0
18#
19# Unless required by applicable law or agreed to in writing, software
20# distributed under the Apache License with the above modification is
21# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22# KIND, either express or implied. See the Apache License for the specific
23# language governing permissions and limitations under the Apache License.
24#
25
26from __future__ import print_function
27
28import os
29ASSET_BASE = os.path.join(os.getcwd(), 'models')
30TABLE_HEIGHT = 74.5
31BALL_RADIUS = 5.715 * 0.5
32
33def main():
34    shotFilePath = 'shots/s00_01/s00_01.usd'
35    layoutLayerFilePath = 'shots/s00_01/s00_01_layout.usd'
36
37    from pxr import Usd, Sdf
38    stage = Usd.Stage.Open(shotFilePath)
39
40    # set the timeCode range for the shot that other applications can use.
41    stage.SetStartTimeCode(1)
42    stage.SetEndTimeCode(10)
43
44    # we use Sdf, a lower level library, to obtain the 'layout' layer.
45    workingLayer = Sdf.Layer.FindOrOpen(layoutLayerFilePath)
46    assert stage.HasLocalLayer(workingLayer)
47
48    # this makes the workingLayer the target for authoring operations by the
49    # stage.
50    stage.SetEditTarget(workingLayer)
51
52    _SetupBilliards(stage)
53    _MoveCamera(stage)
54
55    stage.GetEditTarget().GetLayer().Save()
56
57    print('===')
58    print('usdview %s' % shotFilePath)
59    print('usdcat %s' % layoutLayerFilePath)
60
61def _SetupBilliards(stage):
62    from pxr import Kind, Sdf, Usd, UsdGeom
63
64    # Make sure the model-parents we need are well-specified
65    Usd.ModelAPI(UsdGeom.Xform.Define(stage, '/World')).SetKind(Kind.Tokens.group)
66    Usd.ModelAPI(UsdGeom.Xform.Define(stage, '/World/anim')).SetKind(Kind.Tokens.group)
67    # in previous examples, we've been using GetReferences().AddReference(...).  The
68    # following uses .SetItems() instead which lets us explicitly set (replace)
69    # the references at once instead of adding.
70    cueBall = stage.DefinePrim('/World/anim/CueBall')
71    cueBall.GetReferences().SetReferences([
72        Sdf.Reference(os.path.join(ASSET_BASE, 'Ball/Ball.usd'))])
73
74    # deactivate everything that isn't 8, 9, 1, 4.  We accumulate the prims we
75    # want to deactivate so that we don't delete while iterating.
76    roomProps = stage.GetPrimAtPath('/World/sets/Room_set/Props')
77    keepers = set(['Ball_%d' % i for i in [1, 9, 8, 4] ])
78    toDeactivate = []
79    for child in roomProps.GetChildren():
80        if child.GetName() not in keepers:
81            toDeactivate.append(child)
82    for prim in toDeactivate:
83        prim.SetActive(False)
84
85    # the offset values are relative to the radius of the ball
86    def _MoveBall(ballPrim, offset):
87        translation = (offset[0] * BALL_RADIUS,
88                       TABLE_HEIGHT + BALL_RADIUS,
89                       offset[1] * BALL_RADIUS)
90
91        # Apply the UsdGeom.Xformable schema to the model, and then set the
92        # transformation.  Note we can use ordinary python tuples
93        from pxr import UsdGeom
94        UsdGeom.XformCommonAPI(ballPrim).SetTranslate(translation)
95
96    # all these values are just eye-balled and are relative to Ball_1.
97    _MoveBall(cueBall, (1.831,  4.331))
98    _MoveBall(stage.GetPrimAtPath('/World/sets/Room_set/Props/Ball_2'), (0.000,  0.000))
99    _MoveBall(stage.GetPrimAtPath('/World/sets/Room_set/Props/Ball_10'), (2.221,  1.119))
100    _MoveBall(stage.GetPrimAtPath('/World/sets/Room_set/Props/Ball_1'), (3.776,  0.089))
101    _MoveBall(stage.GetPrimAtPath('/World/sets/Room_set/Props/Ball_4'), (5.453, -0.543))
102
103def _MoveCamera(stage):
104    from pxr import UsdGeom, Gf
105    cam = UsdGeom.Camera.Get(stage, '/World/main_cam')
106
107    # the camera derives from UsdGeom.Xformable so we can
108    # use the XformCommonAPI on it, too, and see how rotations are handled
109    xformAPI = UsdGeom.XformCommonAPI(cam)
110    xformAPI.SetTranslate( (8, 120, 8) )
111    # -86 degree rotation around X axis.  Can specify rotation order as
112    # optional parameter
113    xformAPI.SetRotate( (-86, 0, 0 ) )
114
115if __name__ == '__main__':
116    main()
117
118