@@ -137,14 +137,29 @@ def accept(self, settings, item):
137
137
:returns: dictionary with boolean keys accepted, required and enabled
138
138
"""
139
139
140
+ accepted = True
141
+ publisher = self .parent
142
+
143
+ # Check the publish template if one defined
140
144
# If a publish template is configured, disable context change. This
141
145
# is a temporary measure until the publisher handles context switching
142
146
# natively.
143
- if settings .get ("Publish Template" ).value :
147
+ template_name = settings ["Publish Template" ].value
148
+ if template_name :
144
149
item .context_change_allowed = False
150
+ publish_template = publisher .get_template_by_name (template_name )
151
+ if not publish_template :
152
+ self .logger .debug (
153
+ "The valid publish template could not be determined for the "
154
+ "FBX publish. Not accepting the item."
155
+ )
156
+ accepted = False
145
157
146
- path = _session_path ()
158
+ # We've validated the publish template. add it to the item properties
159
+ # for use in subsequent methods
160
+ item .properties ["publish_template" ] = publish_template
147
161
162
+ path = _session_path ()
148
163
if not path :
149
164
# the session has not been saved before (no path determined).
150
165
# provide a save button. the session will need to be saved before
@@ -153,11 +168,11 @@ def accept(self, settings, item):
153
168
"The Maya session has not been saved." , extra = _get_save_as_action ()
154
169
)
155
170
156
-
157
- self .logger .info (
158
- "Maya '%s' plugin accepted the current Maya session." % (self .name ,)
159
- )
160
- return {"accepted" : True , "checked" : True }
171
+ if accepted :
172
+ self .logger .info (
173
+ "Maya '%s' plugin accepted the current Maya session." % (self .name ,)
174
+ )
175
+ return {"accepted" : accepted , "checked" : True }
161
176
162
177
def validate (self , settings , item ):
163
178
"""
@@ -184,95 +199,89 @@ def validate(self, settings, item):
184
199
self .logger .error (error_msg , extra = _get_save_as_action ())
185
200
return False
186
201
187
- # ensure we have an updated project root
202
+ # Ensure we have an updated project root
188
203
project_root = cmds .workspace (q = True , rootDirectory = True )
189
- item .properties ["project_root" ] = project_root
190
-
191
204
# log if no project root could be determined.
192
205
if not project_root :
193
- self .logger .info (
194
- "Your session is not part of a maya project." ,
206
+ self .logger .error (
207
+ "Your session is not part of a Maya project." ,
195
208
extra = {
196
209
"action_button" : {
197
210
"label" : "Set Project" ,
198
- "tooltip" : "Set the maya project" ,
211
+ "tooltip" : "Set the Maya project" ,
199
212
"callback" : lambda : mel .eval ('setProject ""' ),
200
213
}
201
214
},
202
215
)
216
+ return False
217
+ item .properties ["project_root" ] = project_root
203
218
204
219
# ---- check the session against any attached work template
205
220
206
221
# get the path in a normalized state. no trailing separator,
207
222
# separators are appropriate for current os, no double separators,
208
223
# etc.
209
224
path = sgtk .util .ShotgunPath .normalize (path )
210
-
225
+ publish_name = os . path . splitext ( os . path . basename ( path ))[ 0 ]
211
226
# if the session item has a known work template, see if the path
212
227
# matches. if not, warn the user and provide a way to save the file to
213
228
# a different path
214
229
work_template = item .properties .get ("work_template" )
215
- if work_template :
216
- if not work_template .validate (path ):
217
- self .logger .warning (
218
- "The current session does not match the configured work "
219
- "file template." ,
230
+ publish_template = item .properties .get ("publish_template" )
231
+ if work_template and publish_template :
232
+ # Ensure the fields work for the publish template
233
+ # This raises an error if the path does not match the template.
234
+ work_fields = work_template .get_fields (path )
235
+ missing_keys = publish_template .missing_keys (work_fields )
236
+ if missing_keys :
237
+ error_msg = (
238
+ "Work file '%s' missing keys required for the "
239
+ "publish template: %s" % (path , missing_keys )
240
+ )
241
+ self .logger .error (error_msg )
242
+ return False
243
+ # Create the publish path by applying the fields. store it in the item's
244
+ # properties. This is the path we'll create and then publish in the base
245
+ # publish plugin. Also set the publish_path to be explicit.
246
+ # NOTE: local_properties is used here as directed in the publisher
247
+ # docs when there may be more than one plugin operating on the
248
+ # same item in order for each plugin to have it's own values that
249
+ # aren't overwritten by the other.
250
+ item .local_properties ["publish_path" ] = publish_template .apply_fields (work_fields )
251
+
252
+ # use the work file's version number when publishing
253
+ if "version" in work_fields :
254
+ item .properties ["publish_version" ] = work_fields ["version" ]
255
+ else :
256
+ # Derive a publish path from the current scene path
257
+ workspace = cmds .workspace (q = True , openWorkspace = True )
258
+ if not workspace :
259
+ self .logger .error (
260
+ "A Maya workspace must be set when no SG TK templates are provided" ,
220
261
extra = {
221
262
"action_button" : {
222
- "label" : "Save File" ,
223
- "tooltip" : "Save the current Maya session to a "
224
- "different file name" ,
225
- # will launch wf2 if configured
226
- "callback" : _get_save_as_action (),
263
+ "label" : "Set Project" ,
264
+ "tooltip" : "Set the Maya project" ,
265
+ # This is a Mel script not available as a Python command.
266
+ "callback" : lambda : mel .eval ('setProject ""' ),
227
267
}
228
268
},
229
269
)
230
- else :
231
- self .logger .debug ("Work template configured and matches session file." )
232
- else :
233
- # We can't do anything without a work template
234
- raise ValueError ("A work template is required for this plugins." )
235
-
236
- # ---- see if the version can be bumped post-publish
237
-
238
- # check to see if the next version of the work file already exists on
239
- # disk. if so, warn the user and provide the ability to jump to save
240
- # to that version now
241
- (next_version_path , version ) = self ._get_next_version_info (path , item )
242
- if next_version_path and os .path .exists (next_version_path ):
243
-
244
- # determine the next available version_number. just keep asking for
245
- # the next one until we get one that doesn't exist.
246
- while os .path .exists (next_version_path ):
247
- (next_version_path , version ) = self ._get_next_version_info (
248
- next_version_path , item
249
- )
250
-
251
- error_msg = "The next version of this file already exists on disk."
252
- self .logger .error (
253
- error_msg ,
254
- extra = {
255
- "action_button" : {
256
- "label" : "Save to v%s" % (version ,),
257
- "tooltip" : "Save to the next available version number, "
258
- "v%s" % (version ,),
259
- "callback" : lambda : _save_session (next_version_path ),
260
- }
261
- },
262
- )
263
- return False
264
-
265
- # ---- populate the necessary properties and call base class validation
270
+ return False
271
+ fbx_dir = cmds .workspace (fileRuleEntry = "FBX" ) or "data"
272
+ # Append a "publishes" folder and get the full path
273
+ fbx_dir = cmds .workspace (expandName = os .path .join (fbx_dir , "publishes" ))
274
+
275
+ # Build a name from the Maya scene
276
+ base_name = "%s.fbx" % publish_name
277
+ publish_path = os .path .join (fbx_dir , base_name )
278
+ # NOTE: local_properties is used here as directed in the publisher
279
+ # docs when there may be more than one plugin operating on the
280
+ # same item in order for each plugin to have it's own values that
281
+ # aren't overwritten by the other.
282
+ # Set the publish_path to be explicit.
283
+ item .local_properties ["publish_path" ] = publish_path
266
284
267
- # populate the publish template on the item if found
268
- publish_template_setting = settings .get ("Publish Template" )
269
- publish_template = publisher .engine .get_template_by_name (
270
- publish_template_setting .value
271
- )
272
- if publish_template :
273
- item .local_properties ["publish_template" ] = publish_template
274
- else :
275
- raise ValueError ("A publish template is required for this plugins." )
276
285
277
286
# Set the session path on the item for use by the base plugin validation
278
287
# step.
@@ -283,12 +292,9 @@ def validate(self, settings, item):
283
292
# same item in order for each plugin to have it's own values that
284
293
# aren't overwritten by the other.
285
294
item .local_properties ["publish_type" ] = "Maya FBX"
286
- item .local_properties ["publish_name" ] = os .path .splitext (
287
- os .path .basename (path )
288
- )[0 ]
295
+ item .local_properties ["publish_name" ] = publish_name
289
296
290
- # run the base class validation
291
- return super (MayaFBXPublishPlugin , self ).validate (settings , item )
297
+ return True
292
298
293
299
def _copy_work_to_publish (self , settings , item ):
294
300
"""
@@ -338,15 +344,15 @@ def publish(self, settings, item):
338
344
339
345
# Store the exported fbx path onto the parent item so other items can
340
346
# retrieve it and use it without having to export themself an fbx.
341
- item .parent .properties ["exported_fbx_path" ]= publish_path
347
+ item .parent .properties ["exported_fbx_path" ] = publish_path
342
348
343
349
# Let the base class register the publish
344
350
super (MayaFBXPublishPlugin , self ).publish (settings , item )
345
351
# Save publish data locally on the item to be able to restore it later
346
352
item .local_properties ["sg_publish_data" ] = item .properties .sg_publish_data
347
353
# Store the published fbx data onto the parent item so other items can
348
354
# retrieve it and use it without having to export themself an fbx.
349
- item .parent .properties ["sg_fbx_publish_data" ]= item .properties .sg_publish_data
355
+ item .parent .properties ["sg_fbx_publish_data" ] = item .properties .sg_publish_data
350
356
351
357
def finalize (self , settings , item ):
352
358
"""
0 commit comments