5
5
import sgtk
6
6
from tank_vendor import six
7
7
from sgtk .platform .qt import QtGui , QtCore
8
- from sgtk .platform import SoftwareVersion
9
8
10
9
import maya .cmds as cmds
10
+ import maya .mel as mel
11
11
12
12
import copy
13
13
import datetime
19
19
import subprocess
20
20
import sys
21
21
import tempfile
22
+ from six .moves .urllib import parse
22
23
23
24
HookBaseClass = sgtk .get_hook_baseclass ()
24
25
@@ -131,7 +132,7 @@ def _open_current_path(self):
131
132
Open the current file in an external application.
132
133
"""
133
134
current_path = self .get_path ()
134
- engine = sgtk . platform . current_engine ()
135
+
135
136
# Would be awesome to use launch app, but launch_from_path does not work
136
137
# in SotfwareEntity mode.
137
138
# if engine and "tk-multi-launchapp" in engine.apps:
@@ -362,9 +363,6 @@ def description(self):
362
363
Verbose, multi-line description of what the plugin does. This can
363
364
contain simple html for formatting.
364
365
"""
365
-
366
- loader_url = "https://support.shotgunsoftware.com/hc/en-us/articles/219033078"
367
-
368
366
return """
369
367
<p>This plugin renders a turntable of the asset for the current session
370
368
in Unreal Engine. The asset will be exported to FBX and imported into
@@ -373,6 +371,7 @@ def description(self):
373
371
the turntable render will be published to Shotgun and submitted for review
374
372
as a Version.</p>
375
373
"""
374
+
376
375
@property
377
376
def icon (self ):
378
377
"""
@@ -515,7 +514,6 @@ def create_settings_widget(self, parent):
515
514
settings_frame .unreal_turntable_asset_label = QtGui .QLabel ("Unreal Turntable Assets Path:" )
516
515
settings_frame .unreal_turntable_asset_widget = QtGui .QLineEdit ("" )
517
516
518
-
519
517
# Create the layout to use within the QFrame
520
518
settings_layout = QtGui .QVBoxLayout ()
521
519
settings_layout .addWidget (settings_frame .description_label )
@@ -549,9 +547,9 @@ def get_ui_settings(self, widget):
549
547
"Turntable Map Path" : six .ensure_str (widget .unreal_turntable_map_widget .text ()),
550
548
"Sequence Path" : six .ensure_str (widget .unreal_sequence_widget .text ()),
551
549
"Turntable Assets Path" : six .ensure_str (widget .unreal_turntable_asset_widget .text ()),
552
- #"HDR Path": widget.hdr_image_template_widget.get_path(),
553
- #"Start Frame": widget.start_frame_spin_box.value(),
554
- #"End Frame": widget.end_frame_spin_box.value(),
550
+ # "HDR Path": widget.hdr_image_template_widget.get_path(),
551
+ # "Start Frame": widget.start_frame_spin_box.value(),
552
+ # "End Frame": widget.end_frame_spin_box.value(),
555
553
}
556
554
return settings
557
555
@@ -898,7 +896,7 @@ def get_unreal_project_property(self, settings, item):
898
896
raise RuntimeError (
899
897
"Unable to build an Unreal project path from %s with Unreal version %s" % (
900
898
unreal_project_path_template ,
901
- unreal_engine_version ,
899
+ item . properties [ " unreal_engine_version" ] ,
902
900
)
903
901
)
904
902
if not os .path .isfile (unreal_project_path ):
@@ -907,6 +905,39 @@ def get_unreal_project_property(self, settings, item):
907
905
)
908
906
item .properties ["unreal_project_path" ] = unreal_project_path
909
907
908
+ def _get_local_path (self , published_file ):
909
+ """
910
+ Returns the local path for the given published file.
911
+
912
+ :returns: The local path to the published file.
913
+ :raises ValueError: If no local path can be retrieved.
914
+ """
915
+ if "local_path" in published_file ["path" ]:
916
+ return published_file ["path" ]["local_path" ]
917
+
918
+ if "url" in published_file ["path" ]:
919
+ url = published_file ["path" ]["url" ]
920
+ parsed = parse .urlparse (url )
921
+ if parsed .scheme == "file" :
922
+ # Copied from
923
+ # https://github.com/shotgunsoftware/tk-core/blob/2fc8287a19f8f002e23101836bafba0ec0de9dc9/python/tank/util/shotgun/publish_resolve.py#L311
924
+ if parsed .netloc :
925
+ # UNC path
926
+ path = parse .unquote (
927
+ "//%s%s" % (parsed .netloc , parsed .path )
928
+ )
929
+ else :
930
+ path = parse .unquote (parsed .path )
931
+ # Deal with bad paths being set
932
+ # file:///C:/Users/me/default/data/publishes/Trooper_Full_NoKnife_2.fbx
933
+ # Leading to /C:/Users/me/default/data/publishes/Trooper_Full_NoKnife_2.fbx
934
+ # as path.
935
+ if re .match ("^/[A-Za-z]:/" , path ):
936
+ path = path [1 :]
937
+ return path
938
+
939
+ raise ValueError ("Unable to get a local path from %s" % published_file )
940
+
910
941
def publish (self , settings , item ):
911
942
"""
912
943
Executes the publish logic for the given item and settings.
@@ -956,7 +987,7 @@ def publish(self, settings, item):
956
987
# Use the Fbx which was published by another item or save one now.
957
988
published_fbx = item .parent .properties .get ("sg_fbx_publish_data" )
958
989
if published_fbx :
959
- fbx_published_path = published_fbx [ "path" ][ "local_path" ]
990
+ fbx_published_path = self . _get_local_path ( published_fbx )
960
991
# Check the path: Unreal doesn't like non-word characters in filenames
961
992
self .logger .info ("Using published FBX file %s" % fbx_published_path )
962
993
if re .search (exp , os .path .splitext (fbx_published_path )[0 ]):
@@ -997,7 +1028,7 @@ def publish(self, settings, item):
997
1028
self .logger .debug ("Copying %s to %s" % (unreal_project_path , temp_project_path ))
998
1029
shutil .copytree (project_path , temp_project_dir )
999
1030
1000
- current_folder = os .path .dirname ( __file__ )
1031
+ current_folder = os .path .dirname (__file__ )
1001
1032
script_path = os .path .abspath (
1002
1033
os .path .join (
1003
1034
current_folder ,
@@ -1024,6 +1055,8 @@ def publish(self, settings, item):
1024
1055
)
1025
1056
importer_destination = os .path .join (self .temp_folder , "unreal_importer.py" )
1026
1057
shutil .copy (importer_path , importer_destination )
1058
+ # UE5 does some weird things with \ so let's replace them with /
1059
+ script_path = script_path .replace ("\\ " , "/" )
1027
1060
1028
1061
if " " in temp_project_path :
1029
1062
temp_project_path = '"{}"' .format (temp_project_path )
@@ -1033,15 +1066,17 @@ def publish(self, settings, item):
1033
1066
# on the command line.
1034
1067
run_env = copy .copy (os .environ )
1035
1068
# Environment variables for turntable script
1069
+ # Make sure they are strings and not unicode with py2, otherwise
1070
+ # "environment can only contain strings" erors will happen.
1036
1071
extra_env = {
1037
1072
# The FBX to import into Unreal
1038
- "UNREAL_SG_FBX_OUTPUT_PATH" : fbx_output_path ,
1073
+ "UNREAL_SG_FBX_OUTPUT_PATH" : six . ensure_str ( fbx_output_path ) ,
1039
1074
# The Unreal content browser folder where the asset will be imported into
1040
- "UNREAL_SG_ASSETS_PATH" : turntable_assets_path ,
1075
+ "UNREAL_SG_ASSETS_PATH" : six . ensure_str ( turntable_assets_path ) ,
1041
1076
# The Unreal turntable map to duplicate where the asset will be instantiated into
1042
- "UNREAL_SG_MAP_PATH" : turntable_map_path ,
1043
- "UNREAL_SG_SEQUENCE_PATH" : sequence_path ,
1044
- "UNREAL_SG_MOVIE_OUTPUT_PATH" : publish_path ,
1077
+ "UNREAL_SG_MAP_PATH" : six . ensure_str ( turntable_map_path ) ,
1078
+ "UNREAL_SG_SEQUENCE_PATH" : six . ensure_str ( sequence_path ) ,
1079
+ "UNREAL_SG_MOVIE_OUTPUT_PATH" : six . ensure_str ( publish_path ) ,
1045
1080
}
1046
1081
self .logger .info ("Adding %s to the environment" % extra_env )
1047
1082
run_env .update (extra_env )
@@ -1079,7 +1114,7 @@ def publish(self, settings, item):
1079
1114
)
1080
1115
# Workaround for Level Sequencer only rendering avi on Windows and Movie Queue rendering
1081
1116
# mov on all platforms
1082
- publish_path = re .sub ("\.avi$" , ".mov" , publish_path )
1117
+ publish_path = re .sub (r "\.avi$" , ".mov" , publish_path )
1083
1118
item .local_properties ["publish_path" ] = publish_path
1084
1119
self ._unreal_render_movie_with_movie_render_queue (
1085
1120
unreal_exec_path ,
@@ -1132,8 +1167,6 @@ def publish(self, settings, item):
1132
1167
item .local_properties ["sg_publish_data" ] = item .properties .sg_publish_data
1133
1168
1134
1169
# Create a Version entry linked with the new publish
1135
- publish_name = item .properties .get ("publish_name" )
1136
-
1137
1170
# Populate the version data to send to SG
1138
1171
self .logger .info ("Creating Version..." )
1139
1172
version_data = {
@@ -1153,7 +1186,8 @@ def publish(self, settings, item):
1153
1186
"label" : "Version Data" ,
1154
1187
"tooltip" : "Show the complete Version data dictionary" ,
1155
1188
"text" : "<pre>%s</pre>" % (
1156
- pprint .pformat (version_data ),)
1189
+ pprint .pformat (version_data ),
1190
+ )
1157
1191
}
1158
1192
}
1159
1193
)
@@ -1168,7 +1202,7 @@ def publish(self, settings, item):
1168
1202
# Ensure the path is utf-8 encoded to avoid issues with
1169
1203
# the shotgun api
1170
1204
upload_path = six .ensure_text (
1171
- item .properties .sg_publish_data [ "path" ][ "local_path" ]
1205
+ self . _get_local_path ( item .properties .sg_publish_data )
1172
1206
)
1173
1207
1174
1208
# Upload the file to SG
@@ -1236,7 +1270,7 @@ def _maya_export_fbx(self, fbx_output_path):
1236
1270
# import maya.mel as mel
1237
1271
# mel.eval('FBXExport -f "fbx_output_path"')
1238
1272
cmds .FBXExport ('-f' , fbx_output_path )
1239
- except :
1273
+ except Exception :
1240
1274
self .logger .error ("Could not export scene to FBX" )
1241
1275
return False
1242
1276
@@ -1322,7 +1356,7 @@ def _unreal_render_movie_with_sequencer(
1322
1356
# Must delete it first, otherwise the Sequencer will add a number in the filename
1323
1357
try :
1324
1358
os .remove (output_path )
1325
- except OSError as e :
1359
+ except OSError :
1326
1360
self .logger .debug ("Couldn't delete {}. The Sequencer won't be able to output the movie to that file." .format (output_path ))
1327
1361
return False , None
1328
1362
@@ -1382,7 +1416,6 @@ def _unreal_render_movie_with_movie_render_queue(
1382
1416
string representing the path of the generated movie file
1383
1417
"""
1384
1418
output_folder , output_file = os .path .split (output_path )
1385
- movie_name = os .path .splitext (output_file )[0 ]
1386
1419
1387
1420
cmdline_args = self ._get_unreal_base_command (
1388
1421
unreal_exec_path ,
@@ -1434,7 +1467,7 @@ def _unreal_render_movie_with_movie_render_queue(
1434
1467
"-MoviePipelineConfig=\" %s\" " % manifest_path ,
1435
1468
])
1436
1469
self .logger .info ("Running %s" % cmdline_args )
1437
- ret = subprocess .call (cmdline_args )
1470
+ subprocess .call (cmdline_args )
1438
1471
return os .path .isfile (output_path ), output_path
1439
1472
1440
1473
def get_unreal_versions (self ):
@@ -1506,7 +1539,6 @@ def evaluate_unreal_project_path(self, unreal_project_path_template, unreal_engi
1506
1539
short_version = "." .join (unreal_engine_version .split ("." )[:2 ])
1507
1540
# Evaluate the "template"
1508
1541
engine = sgtk .platform .current_engine ()
1509
- engine_path = os .path .join (engine .disk_location , "hooks" )
1510
1542
hooks_folder = engine .sgtk .pipeline_configuration .get_hooks_location ()
1511
1543
fw = self .load_framework ("tk-framework-unrealqt_v1.x.x" )
1512
1544
return os .path .normpath (
@@ -1531,6 +1563,7 @@ def _copy_work_to_publish(self, settings, item):
1531
1563
"""
1532
1564
pass
1533
1565
1566
+
1534
1567
def _session_path ():
1535
1568
"""
1536
1569
Return the path to the current session
0 commit comments