Author: Stefan
Version: 01b
Version: 2020 and up?
Automate the creation of a VFX Shots folders structure:
– Create a VFX library like VFX_ABC
– Create a folder per shot, like ABC_0010
– Create subfolders as needed, based on a given set (plates, renders, elements …)
– Creates a BatchGroup per shot and save it in the proper folder.
– Include a Write File node per BatchGroup.
– Save previously selected clips (plates) to their respective ‘plates’ folder.
You can assign a shortcut to launch it.
Open the app and set things up:
– Select clips from a reel (optionnal)
– Set the openclip path: pattern-ed path for the Write file to write to (renders, .clip, setups)
– set the amount of shots to create, increments, subfolders to include, Schematic and shelf reels to include, start frame, duration.
– The Duration box should be removed, since it can be the default (100) anyway.
– Hit ‘Create’ and enjoy.
Hope you find it useful!
Comments and feedback are more than welcome and appreciated.
Sorry, the pasted code is tripping on something and replacing some characters with >>>> …
Please ignore and browse through for quick view, otherwise simply down the script from the above link.
</pre> # -*- coding: utf-8 -*- ''' Stefan Gaillot xenjee@gmail.com 2019/05/04 sg_breakout_lib_and_clips.py ''' from PySide2 import QtCore, QtWidgets import json import os import flame print "" print "CUA BREAKOUT - WITH CLIPS" global MainClass, QtWidgets global openclip_path_json # To save the json config file per project prj = flame.project.current_project # To save the json config file per project openclip_path_json = '/opt/Autodesk/project/' + prj.project_name + '/cfg/openclip_path_json.json' # print "openclip_path_json: ", openclip_path_json class Ui_Widget(object): def setupUi(self, Widget): Widget.setObjectName("Widget") Widget.setEnabled(True) Widget.resize(545, 589) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(Widget.sizePolicy().hasHeightForWidth()) Widget.setSizePolicy(sizePolicy) Widget.setMinimumSize(QtCore.QSize(450, 400)) self.verticalLayout_8 = QtWidgets.QVBoxLayout(Widget) self.verticalLayout_8.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) self.verticalLayout_8.setContentsMargins(11, 11, 11, 11) self.verticalLayout_8.setObjectName("verticalLayout_8") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setContentsMargins(11, 11, 11, 11) self.verticalLayout.setSpacing(6) self.verticalLayout.setObjectName("verticalLayout") self.HLayout_main = QtWidgets.QHBoxLayout() self.HLayout_main.setContentsMargins(11, 11, 11, 11) self.HLayout_main.setSpacing(6) self.HLayout_main.setObjectName("HLayout_main") self.GB_folders = QtWidgets.QGroupBox(Widget) self.GB_folders.setObjectName("GB_folders") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.GB_folders) self.verticalLayout_2.setContentsMargins(11, 11, 11, 11) self.verticalLayout_2.setSpacing(6) self.verticalLayout_2.setObjectName("verticalLayout_2") self.groupBox_3 = QtWidgets.QGroupBox(self.GB_folders) self.groupBox_3.setTitle("") self.groupBox_3.setObjectName("groupBox_3") self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_3) self.verticalLayout_4.setContentsMargins(11, 11, 11, 11) self.verticalLayout_4.setSpacing(6) self.verticalLayout_4.setObjectName("verticalLayout_4") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setContentsMargins(11, 11, 11, 11) self.horizontalLayout.setSpacing(6) self.horizontalLayout.setObjectName("horizontalLayout") self.label_basename = QtWidgets.QLabel(self.groupBox_3) self.label_basename.setMinimumSize(QtCore.QSize(0, 25)) self.label_basename.setObjectName("label_basename") self.horizontalLayout.addWidget(self.label_basename) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.lineEdit_sequence_name = QtWidgets.QLineEdit(self.groupBox_3) self.lineEdit_sequence_name.setMinimumSize(QtCore.QSize(0, 25)) self.lineEdit_sequence_name.setObjectName("lineEdit_sequence_name") self.horizontalLayout.addWidget(self.lineEdit_sequence_name) self.verticalLayout_4.addLayout(self.horizontalLayout) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_3.setSpacing(6) self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.label_shot_amount = QtWidgets.QLabel(self.groupBox_3) self.label_shot_amount.setMinimumSize(QtCore.QSize(0, 25)) self.label_shot_amount.setObjectName("label_shot_amount") self.horizontalLayout_3.addWidget(self.label_shot_amount) spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem1) self.SB_shots_amount = QtWidgets.QSpinBox(self.groupBox_3) self.SB_shots_amount.setMinimumSize(QtCore.QSize(0, 25)) self.SB_shots_amount.setMaximum(1000) self.SB_shots_amount.setObjectName("SB_shots_amount") self.horizontalLayout_3.addWidget(self.SB_shots_amount) self.verticalLayout_4.addLayout(self.horizontalLayout_3) self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_4.setSpacing(6) self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.label_start_at = QtWidgets.QLabel(self.groupBox_3) self.label_start_at.setMinimumSize(QtCore.QSize(0, 25)) self.label_start_at.setObjectName("label_start_at") self.horizontalLayout_4.addWidget(self.label_start_at) spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_4.addItem(spacerItem2) self.SB_start_at = QtWidgets.QSpinBox(self.groupBox_3) self.SB_start_at.setMinimumSize(QtCore.QSize(0, 25)) self.SB_start_at.setMaximum(1000) self.SB_start_at.setObjectName("SB_start_at") self.horizontalLayout_4.addWidget(self.SB_start_at) self.verticalLayout_4.addLayout(self.horizontalLayout_4) self.horizontalLayout_5 = QtWidgets.QHBoxLayout() self.horizontalLayout_5.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_5.setSpacing(6) self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.label_increments = QtWidgets.QLabel(self.groupBox_3) self.label_increments.setMinimumSize(QtCore.QSize(0, 25)) self.label_increments.setObjectName("label_increments") self.horizontalLayout_5.addWidget(self.label_increments) spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_5.addItem(spacerItem3) self.SB_increments = QtWidgets.QSpinBox(self.groupBox_3) self.SB_increments.setMinimumSize(QtCore.QSize(0, 25)) self.SB_increments.setMaximum(1000) self.SB_increments.setObjectName("SB_increments") self.horizontalLayout_5.addWidget(self.SB_increments) self.verticalLayout_4.addLayout(self.horizontalLayout_5) self.verticalLayout_2.addWidget(self.groupBox_3) self.groupBox_4 = QtWidgets.QGroupBox(self.GB_folders) self.groupBox_4.setTitle("") self.groupBox_4.setObjectName("groupBox_4") self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox_4) self.verticalLayout_6.setContentsMargins(11, 11, 11, 11) self.verticalLayout_6.setSpacing(6) self.verticalLayout_6.setObjectName("verticalLayout_6") self.CB_fldr_plates = QtWidgets.QCheckBox(self.groupBox_4) self.CB_fldr_plates.setObjectName("CB_fldr_plates") self.verticalLayout_6.addWidget(self.CB_fldr_plates) self.CB_fldr_refs = QtWidgets.QCheckBox(self.groupBox_4) self.CB_fldr_refs.setObjectName("CB_fldr_refs") self.verticalLayout_6.addWidget(self.CB_fldr_refs) self.CB_fldr_elements = QtWidgets.QCheckBox(self.groupBox_4) self.CB_fldr_elements.setObjectName("CB_fldr_elements") self.verticalLayout_6.addWidget(self.CB_fldr_elements) self.CB_fldr_mattes = QtWidgets.QCheckBox(self.groupBox_4) self.CB_fldr_mattes.setObjectName("CB_fldr_mattes") self.verticalLayout_6.addWidget(self.CB_fldr_mattes) self.CB_fldr_batch = QtWidgets.QCheckBox(self.groupBox_4) self.CB_fldr_batch.setObjectName("CB_fldr_batch") self.verticalLayout_6.addWidget(self.CB_fldr_batch) self.CB_fldr_result = QtWidgets.QCheckBox(self.groupBox_4) self.CB_fldr_result.setObjectName("CB_fldr_result") self.verticalLayout_6.addWidget(self.CB_fldr_result) self.verticalLayout_2.addWidget(self.groupBox_4) self.HLayout_main.addWidget(self.GB_folders) self.GB_batchgroup = QtWidgets.QGroupBox(Widget) self.GB_batchgroup.setObjectName("GB_batchgroup") self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.GB_batchgroup) self.verticalLayout_3.setContentsMargins(11, 11, 11, 11) self.verticalLayout_3.setSpacing(6) self.verticalLayout_3.setObjectName("verticalLayout_3") self.groupBox_5 = QtWidgets.QGroupBox(self.GB_batchgroup) self.groupBox_5.setTitle("") self.groupBox_5.setObjectName("groupBox_5") self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_5) self.verticalLayout_5.setContentsMargins(11, 11, 11, 11) self.verticalLayout_5.setSpacing(6) self.verticalLayout_5.setObjectName("verticalLayout_5") self.horizontalLayout_7 = QtWidgets.QHBoxLayout() self.horizontalLayout_7.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_7.setSpacing(6) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.label_startframe = QtWidgets.QLabel(self.groupBox_5) self.label_startframe.setMinimumSize(QtCore.QSize(0, 25)) self.label_startframe.setObjectName("label_startframe") self.horizontalLayout_7.addWidget(self.label_startframe) spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_7.addItem(spacerItem4) self.SB_start_frame = QtWidgets.QSpinBox(self.groupBox_5) self.SB_start_frame.setMinimumSize(QtCore.QSize(0, 25)) self.SB_start_frame.setMaximum(1001) self.SB_start_frame.setObjectName("SB_start_frame") self.horizontalLayout_7.addWidget(self.SB_start_frame) self.verticalLayout_5.addLayout(self.horizontalLayout_7) self.horizontalLayout_8 = QtWidgets.QHBoxLayout() self.horizontalLayout_8.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_8.setSpacing(6) self.horizontalLayout_8.setObjectName("horizontalLayout_8") self.label_duration = QtWidgets.QLabel(self.groupBox_5) self.label_duration.setMinimumSize(QtCore.QSize(0, 25)) self.label_duration.setObjectName("label_duration") self.horizontalLayout_8.addWidget(self.label_duration) spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_8.addItem(spacerItem5) self.SB_duration = QtWidgets.QSpinBox(self.groupBox_5) self.SB_duration.setMinimumSize(QtCore.QSize(0, 25)) self.SB_duration.setMaximum(1000) self.SB_duration.setObjectName("SB_duration") self.horizontalLayout_8.addWidget(self.SB_duration) self.verticalLayout_5.addLayout(self.horizontalLayout_8) self.horizontalLayout_9 = QtWidgets.QHBoxLayout() self.horizontalLayout_9.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_9.setSpacing(6) self.horizontalLayout_9.setObjectName("horizontalLayout_9") self.label_task = QtWidgets.QLabel(self.groupBox_5) self.label_task.setMinimumSize(QtCore.QSize(0, 25)) self.label_task.setObjectName("label_task") self.horizontalLayout_9.addWidget(self.label_task) spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_9.addItem(spacerItem6) self.lineEdit_task = QtWidgets.QLineEdit(self.groupBox_5) self.lineEdit_task.setMinimumSize(QtCore.QSize(0, 25)) self.lineEdit_task.setObjectName("lineEdit_task") self.horizontalLayout_9.addWidget(self.lineEdit_task) self.verticalLayout_5.addLayout(self.horizontalLayout_9) self.verticalLayout_3.addWidget(self.groupBox_5) self.groupBox_6 = QtWidgets.QGroupBox(self.GB_batchgroup) self.groupBox_6.setTitle("") self.groupBox_6.setObjectName("groupBox_6") self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.groupBox_6) self.verticalLayout_7.setContentsMargins(11, 11, 11, 11) self.verticalLayout_7.setSpacing(6) self.verticalLayout_7.setObjectName("verticalLayout_7") self.CB_batch_plates = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_plates.setObjectName("CB_batch_plates") self.verticalLayout_7.addWidget(self.CB_batch_plates) self.CB_batch_elements = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_elements.setObjectName("CB_batch_elements") self.verticalLayout_7.addWidget(self.CB_batch_elements) self.CB_batch_mattes = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_mattes.setObjectName("CB_batch_mattes") self.verticalLayout_7.addWidget(self.CB_batch_mattes) self.CB_batch_cg = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_cg.setObjectName("CB_batch_cg") self.verticalLayout_7.addWidget(self.CB_batch_cg) self.CB_batch_prerender = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_prerender.setObjectName("CB_batch_prerender") self.verticalLayout_7.addWidget(self.CB_batch_prerender) self.CB_batch_result = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_result.setObjectName("CB_batch_result") self.verticalLayout_7.addWidget(self.CB_batch_result) self.CB_batch_shelf = QtWidgets.QCheckBox(self.groupBox_6) self.CB_batch_shelf.setObjectName("CB_batch_shelf") self.verticalLayout_7.addWidget(self.CB_batch_shelf) self.verticalLayout_3.addWidget(self.groupBox_6) self.HLayout_main.addWidget(self.GB_batchgroup) self.verticalLayout.addLayout(self.HLayout_main) self.GB_writefile = QtWidgets.QGroupBox(Widget) self.GB_writefile.setTitle("") self.GB_writefile.setObjectName("GB_writefile") self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.GB_writefile) self.verticalLayout_9.setContentsMargins(11, 11, 11, 11) self.verticalLayout_9.setSpacing(6) self.verticalLayout_9.setObjectName("verticalLayout_9") # trying self.horizontalLayout_20 = QtWidgets.QHBoxLayout() self.horizontalLayout_20.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_20.setSpacing(6) self.horizontalLayout_20.setObjectName("horizontalLayout_20") # self.horizontalLayout_14 = QtWidgets.QHBoxLayout() self.horizontalLayout_14.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_14.setSpacing(6) self.horizontalLayout_14.setObjectName("horizontalLayout_14") # trying self.CB_batchgroup = QtWidgets.QCheckBox(self.GB_writefile) self.CB_batchgroup.setObjectName("CB_batchgroup") self.horizontalLayout_20.addWidget(self.CB_batchgroup) # self.label_openclip_mainpath = QtWidgets.QLabel(self.GB_writefile) self.label_openclip_mainpath.setObjectName("label_openclip_mainpath") self.horizontalLayout_14.addWidget(self.label_openclip_mainpath) # WRITE FILE LINE EDIT # self.lineEdit_openclip_mainpath = QtWidgets.QLineEdit(self.GB_writefile) self.lineEdit_openclip_mainpath.setMinimumSize(QtCore.QSize(0, 25)) self.lineEdit_openclip_mainpath.setObjectName("lineEdit_openclip_mainpath") self.horizontalLayout_14.addWidget(self.lineEdit_openclip_mainpath) self.btn_openclip_path = QtWidgets.QPushButton(self.GB_writefile) self.btn_openclip_path.setMinimumSize(QtCore.QSize(0, 25)) self.btn_openclip_path.setObjectName("btn_openclip_path") # NEED TO SAVE IN A JSON FILE - When the 'Create' button is pressed self.horizontalLayout_14.addWidget(self.btn_openclip_path) # trying self.verticalLayout_9.addLayout(self.horizontalLayout_20) # self.verticalLayout_9.addLayout(self.horizontalLayout_14) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_2.setSpacing(6) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.label_file_type = QtWidgets.QLabel(self.GB_writefile) self.label_file_type.setObjectName("label_file_type") self.horizontalLayout_2.addWidget(self.label_file_type) spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem7) self.CB_file_type = QtWidgets.QComboBox(self.GB_writefile) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.CB_file_type.sizePolicy().hasHeightForWidth()) self.CB_file_type.setSizePolicy(sizePolicy) self.CB_file_type.setMinimumSize(QtCore.QSize(0, 25)) self.CB_file_type.setObjectName("CB_file_type") self.horizontalLayout_2.addWidget(self.CB_file_type) self.verticalLayout_9.addLayout(self.horizontalLayout_2) spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout_9.addItem(spacerItem8) self.verticalLayout.addWidget(self.GB_writefile) self.verticalLayout_8.addLayout(self.verticalLayout) spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout_8.addItem(spacerItem9) self.BB_apply_cancel = QtWidgets.QDialogButtonBox(Widget) self.BB_apply_cancel.setStandardButtons(QtWidgets.QDialogButtonBox.Close | QtWidgets.QDialogButtonBox.Ok) self.BB_apply_cancel.setCenterButtons(True) self.BB_apply_cancel.setObjectName("BB_apply_cancel") self.verticalLayout_8.addWidget(self.BB_apply_cancel) self.retranslateUi(Widget) QtCore.QMetaObject.connectSlotsByName(Widget) def retranslateUi(self, Widget): _translate = QtCore.QCoreApplication.translate Widget.setWindowTitle(_translate("Widget", "Breakout - include clips")) self.GB_folders.setTitle(_translate("Widget", "Folders")) self.label_basename.setText(_translate("Widget", "Seq Name")) self.label_shot_amount.setText(_translate("Widget", "Amount of shots")) self.label_start_at.setText(_translate("Widget", "Start at")) self.label_increments.setText(_translate("Widget", "Increments")) self.CB_fldr_plates.setText(_translate("Widget", "Plates")) self.CB_fldr_refs.setText(_translate("Widget", "Refs")) self.CB_fldr_elements.setText(_translate("Widget", "Elements")) self.CB_fldr_mattes.setText(_translate("Widget", "Mattes")) self.CB_fldr_batch.setText(_translate("Widget", "Batch")) self.CB_fldr_result.setText(_translate("Widget", "Result")) self.GB_batchgroup.setTitle(_translate("Widget", "Batch Group")) self.label_startframe.setText(_translate("Widget", "Start Frame")) self.label_duration.setText(_translate("Widget", "Duration")) self.label_task.setText(_translate("Widget", "Task")) self.CB_batch_plates.setText(_translate("Widget", "Plates")) self.CB_batch_elements.setText(_translate("Widget", "Elements")) self.CB_batch_mattes.setText(_translate("Widget", "Mattes")) self.CB_batch_cg.setText(_translate("Widget", "CG")) self.CB_batch_prerender.setText(_translate("Widget", "Pre_Renders")) self.CB_batch_result.setText(_translate("Widget", "Result")) self.CB_batch_shelf.setText(_translate("Widget", "Shelf reel")) self.label_openclip_mainpath.setText(_translate("Widget", "Openclips Path")) self.btn_openclip_path.setText(_translate("Widget", "Browse")) self.label_file_type.setText(_translate("Widget", "File type")) # trying self.CB_batchgroup.setText(_translate("Widget", "Create Batchgroups")) # self.show() # -------------------- # # MainClass # # -------------------- class MainClass(QtWidgets.QWidget, Ui_Widget): ''' Set up the user interface from widget.ui (created in Qt designer) converted to widget_UI.py terminal command line to convert: pyuic5 widget.ui -o widget_UI.py Then change 'from PyQt5 import ...' to 'from PySide2 import ...' in the widget_UI.py file. ''' def __init__(self, selection): super(MainClass, self).__init__() self.selection = selection self.setupUi(self) global flame # ---------- VARIABLES ---------- self.shots_folders_list = [] self.shots_subfolders_list = [] self.schematic_reels_list = [] self.shelf_reels_list = [] self.shot_name_only = '' self.shot_name_plus = '' self.seq_name = '' self.lib_name = '' self.vfx_lib = '' self.list_of_filetypes = ['DPX 10bits', 'OpenEXR 16fp'] # ---------- PRE CONFIGURATION - and place holders ---------- # comment out or un-comment for default 'preset' configuration self.lineEdit_sequence_name.setText("ABC") self.SB_shots_amount.setValue(1) self.SB_start_at.setValue(10) self.SB_increments.setValue(10) self.CB_fldr_plates.setChecked(True) # self.CB_fldr_refs.setChecked(True) # self.CB_fldr_elements.setChecked(True) # self.CB_fldr_mattes.setChecked(True) # self.CB_fldr_batch.setChecked(True) # self.CB_fldr_result.setChecked(True) self.SB_start_frame.setValue(1) self.SB_duration.setValue(100) self.lineEdit_task.setText("taskname") self.CB_batch_plates.setChecked(True) # self.CB_batch_elements.setChecked(True) # self.CB_batch_mattes.setChecked(True) # self.CB_batch_cg.setChecked(True) self.CB_batch_prerender.setChecked(True) self.CB_batch_result.setChecked(True) self.CB_batch_shelf.setChecked(True) self.CB_batchgroup.setChecked(True) # Read from a json config file - When the window is created, set the open clip root path from it. with open(openclip_path_json, 'r') as my_file: for i in my_file.readlines(): print ">>>> read from json file: ", i self.lineEdit_openclip_mainpath.setText(i.replace('"', '')) my_file.close() # ---------- Connections and other STUFF ---------- self.BB_apply_cancel.button(QtWidgets.QDialogButtonBox.Ok).setText("Create") self.BB_apply_cancel.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.click_create) self.BB_apply_cancel.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self.close_window) self.BB_apply_cancel.button(QtWidgets.QDialogButtonBox.Ok).setShortcut("Return") self.connect(self.btn_openclip_path, QtCore.SIGNAL('clicked()'), self.openclip_chose_path) self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.CB_file_type.addItems(self.list_of_filetypes) # -------------------- # MAIN LOGIC # -------------------- def click_create(self): print "-" * 60 self.get_folders_infos() self.create_subfolders_list() self.create_vfx_lib() self.create_schematic_reels_list() self.create_shelf_reels_list() self.create_batchGroup() self.create_server_sequence_folders() self.close_window() # NEED TO SAVE TO THE JSON FILE - When the 'Create' button is pressed with open(openclip_path_json, 'w') as openclip_path_to_json: openclip_path_to_json.write(json.dumps(self.lineEdit_openclip_mainpath.text())) # -------------------- # FOLDERS & SUBFOLDERS # -------------------- def get_folders_infos(self): shots_amount = int(self.SB_shots_amount.value()) start_at = int(self.SB_start_at.value()) increments = int(self.SB_increments.value()) self.seq_name = self.lineEdit_sequence_name.text() task_name = str(self.lineEdit_task.text()) # stop_before = shots_amount * increments + start_at stop_before = start_at + (increments * shots_amount) for x in range(start_at, stop_before, increments): folder_name = (self.seq_name + '_' + '%04d' % x) print ">>>> folder to create: ", folder_name self.shots_folders_list.append(folder_name) print "-" * 30 def create_subfolders_list(self): if self.CB_fldr_plates.isChecked(): print ">>>> CB_fldr_plates ... is Checked ... adding to list" self.shots_subfolders_list.append("Plates") if self.CB_fldr_refs.isChecked(): print ">>>> CB_fldr_refs ... is Checked ... adding to list" self.shots_subfolders_list.append("Refs") if self.CB_fldr_elements.isChecked(): print ">>>> CB_fldr_elements ... is Checked ... adding to list" self.shots_subfolders_list.append("Elements") if self.CB_fldr_mattes.isChecked(): print ">>>> CB_fldr_mattes ... is Checked ... adding to list" self.shots_subfolders_list.append("Mattes") if self.CB_fldr_batch.isChecked(): print ">>>> CB_fldr_batch ... is Checked ... adding to list" self.shots_subfolders_list.append("Batch") if self.CB_fldr_result.isChecked(): print ">>>> CB_fldr_result ... is Checked ... adding to list" self.shots_subfolders_list.append("Result") print "-" * 30 # -------------------- # FLAME STUFF - create VFX lib and folders # Then save each clip in its corresponding 'Plates' folder. # -------------------- def create_vfx_lib(self): import flame print ">>>> shots_folders_list: ", self.shots_folders_list print ">>>> shots_subfolders_list: ", self.shots_subfolders_list desk = flame.project.current_project.current_workspace.desktop ws = flame.project.current_project.current_workspace # Set the VFX library name: self.lib_name = "VFX_" + self.seq_name # Create the library ans store it to a variable (self.vfx_lib) self.vfx_lib = ws.create_library(str(self.lib_name)) # Create folders and subfolders. for fldr in self.shots_folders_list: shot_folder = self.vfx_lib.create_folder(str(fldr)) for subfldr in self.shots_subfolders_list: sub_folder = shot_folder.create_folder(subfldr) # SAVE CLIPS IN FOLDERS for clip in self.selection: print "clip.name: ", str(clip.name).replace("'", "") clip_name = '_'.join(str(clip.name).replace("'", "").split('_')[0:2]) print "clip_name: ", clip_name if fldr == '_'.join(str(clip_name).split('_')[0:2]): if str(subfldr) == "Plates": desk.destination = sub_folder clip.save() # -------------------- # FLAME STUFF - create batchgroups with writeFile nodes (openclip) # -------------------- def create_schematic_reels_list(self): print "-" * 30 if self.CB_batch_plates.isChecked(): print ">>>> CB_batch_plates ... is Checked ... adding to list" self.schematic_reels_list.append("Plates") if self.CB_batch_elements.isChecked(): print ">>>> CB_batch_elements ... is Checked ... adding to list" self.schematic_reels_list.append("Elements") if self.CB_batch_mattes.isChecked(): print ">>>> CB_batch_mattes ... is Checked ... adding to list" self.schematic_reels_list.append("Mattes") if self.CB_batch_cg.isChecked(): print ">>>> CB_batch_cg ... is Checked ... adding to list" self.schematic_reels_list.append("CG") if self.CB_batch_prerender.isChecked(): print ">>>> CB_batch_prerender ... is Checked ... adding to list" self.schematic_reels_list.append("Pre_Renders") if self.CB_batch_result.isChecked(): print ">>>> CB_batch_result ... is Checked ... adding to list" self.schematic_reels_list.append("Result") def create_shelf_reels_list(self): print "-" * 30 if self.CB_batch_shelf.isChecked(): print ">>>> CB_batch_shelf ... is Checked ... adding to list" self.shelf_reels_list.append("batch_renders") def openclip_chose_path(self): self.lineEdit_openclip_mainpath.setText(QtWidgets.QFileDialog.getExistingDirectory( self, "Browser", "/var/temp", QtWidgets.QFileDialog.ShowDirsOnly)) def create_batchGroup(self): import flame desk = flame.project.current_project.current_workspace.desktop # my_libs = flame.project.current_project.current_workspace.libraries print "-" * 60 batch_start_frame = int(self.SB_start_frame.value()) batch_duration = int(self.SB_duration.value()) task_name = str(self.lineEdit_task.text()) for shotname in self.shots_folders_list: print ">>>> shotname: ", shotname self.shot_name_only = shotname self.shot_name_plus = shotname + "_" + task_name batchGroup = flame.batch.create_batch_group(str(self.shot_name_plus), start_frame=batch_start_frame, duration=batch_duration, reels=self.schematic_reels_list, shelf_reels=self.shelf_reels_list) self.create_write_file() subfldr_list = [] for fldr in self.vfx_lib.folders: if fldr.name == str(shotname): for subfldr in fldr.folders: subfldr_list.append(subfldr.name) if subfldr.name == 'Batch': desk.destination = subfldr print "subfldr_list: ", subfldr_list if str('Batch') not in subfldr_list: desk.destination = fldr batchGroup.save() flame.delete(batchGroup) desk.destination = self.vfx_lib def create_write_file(self): import flame write_file = flame.batch.create_node("Write File") write_file.name = "<batch name>" # write_file.shot_name = "ABC_0000" write_file.shot_name = str(self.shot_name_only) clip_path = self.lineEdit_openclip_mainpath.text() + '/' self.clip_result_path = clip_path + self.lineEdit_sequence_name.text() write_file.media_path = str(self.clip_result_path) write_file.media_path_pattern = "<shot name>/renders/<name>_<version name>/<name>_<version name>" write_file.create_clip_path = "<shot name>/<name>" write_file.include_setup = True write_file.include_setup_path = "<shot name>/setups/<name>_<version name>" write_file.version_mode = "Follow Iteration" write_file.version_name = "<version>" write_file.version_padding = 3 write_file.frame_padding = 4 if self.CB_file_type.currentText() == 'DPX 10bits': write_file.file_type = "Dpx" write_file.bit_depth = 10 if self.CB_file_type.currentText() == 'OpenEXR 16fp': write_file.file_type = "OpenEXR" write_file.bit_depth = 16 # PICKUP HERE ########################################## def create_server_sequence_folders(self): print ">>>>>> self.clip_result_path,: ", self.clip_result_path seq_folder = os.path.dirname(self.clip_result_path) + "/" + self.seq_name print "seq_folder: ", seq_folder if not os.path.exists(seq_folder): print "creating sequence folder_name" os.makedirs(seq_folder) # ################################# Close Window def close_window(self): print ">>>> close_window" self.close() # -------------------- # FLAME MENU ENTRY # -------------------- def start_process(selection): import flame import os import json # create a dummy string (does it need to be a list?) to create and feed a .json config file if there was none. # the following path should be changed to use a pattern including the project name (auto detected) default_openclip_path = "/var/temp/OPENCLIP" if not os.path.isfile(openclip_path_json): print "-" * 30 + "FILE NOT FOUND, CREATING FILE" + "-" * 30 with open(openclip_path_json, "w+") as myfilepy: myfilepy.write(json.dumps(default_openclip_path)) myfilepy.close() form = MainClass(selection) form.show() return form def get_media_panel_custom_ui_actions(): """ Return custom UI actions to execute on media panel objects. """ return [ { "name": "Breakout", "actions": [ { "name": "Create VFX Lib and Save Plates", # "execute": start_process, "execute": start_process, } ] } ] # end of script <pre>
Duplicate.
Salut Steph,
Le lien pour télécharger le .py de Hook: Create Shot Folders Structure n’est pas dispo sur la page. Est-ce normal ?
As-tu envisager de faire un script d’install à la façon de PyFlame, afin que tes scripts se retrouvent bien ranger dans un menu ?
Y-t-il moyen que tu collabores avec PyFlame pour qu’il y ajoute tes scripts ?
Concernant ton script Create Shot Folders, j’aimerai pouvoir l’utiliser afin de ranger dans des Desktop tous les “Create Batch Group” créés à partir du bouton dans le module “Conform”.
Je m’explique :
Dans notre workflow, nous faisons nos confos et créons à partir du module “Confort” tous les Batch automatiquement avec la fonction “Create Batch Group”, dans l’idéal, j’aimerai qu’au lieu de créer les Batch Group seulement, ces derniers soient ranger chacun dans un desktop différent, car dans notre façon de travailler, chaque effet à son Desktop. Crois-tu que cela soit possible directement dans le module “Confort” sans passer par “Create Batch Group”, ou alors avec une fonction qui permette de ranger automatiquement chaque Batch Group dans une arborescence préalablement définie par un script?
J’espère que ça roule pour toi, Gros Bisous et merci
Sebquismoke
Salut Seb,
Merci pour l’info, c’est corrigé, lien vers le script et code aussi dans la page.
Faute de temps et pour quelques autres raisons je ne pense pas faire un script d’install. Je vais réfléchir a poster quelque chose qui expliquerait comment modifier des scripts pour qu’ils apparaissent de la manière convenant a chacun.
Pour ton workflow, je ne suis pas sur que le shot creator soit une bonne base, meme si tu peux utiliser des parties pour tel ou tel truc.
Le problème depuis une timeline est qu’il n’est pas encore possible de sauver un segment vers quelque part dans le media panel (comme un desktop). Je n’ai pas encore regardé s’il était possible d’utiliser la fonction flame “Create Batch Group” avec python, et de hacker un peu, aucune idée 🙂
Je vais y réfléchir un peu plus …
Tout va bien ici, pareil pour toi !
La bises amigo !
Stef
Salut Stef,
Merci pour m’avoir répondu rapidement et pour la modif.
J’ai touché deux mots à Michael Vaglienty (de PyFlame) pour cette histoire d’installation de scripts extérieurs via son script “PyFlame installer” et apparemment il y réfléchi de son côté.
Pour ce qui est de ma demande sur ton script Create Shot Folders Structure, il n’est pas question de prendre un segment d’une timeline, mais plutôt de prendre les batch créés à partir de la partie “Conform” à l’aide de la touche “Create Batch Group” qui se retrouvent dans la library et de les déplacer ou copier chacun dans un Desktop différent.
Merci Stef, La Grosse BiZ
Seb
Ton lien vers le download demande une autorisation de téléchargement que tu as du recevoir par mail, je pense qu’il y a un kouak
Bis
ca devrait marcher maintenant.
Ah ok je comprends. Tu peux piocher dans la partie batchgroups mais il n’y a pas grand chose dans ce script qui concerne ce que tu décris.
Je n’ai pas trop de temps en ce moment, mais si tu veux m’envoyer un screengrab de ton genre de library je peux y réfléchir.
Sinon pioche ce que tu peux et je pourrais peut-etre d’aider pour la suite.
La bise
Merci Stef,
Ok pour le téléchargement.
Je reviendrai vers toi au besoin. Je vais essayer de mon côté, je kiffe ça.
A bientôt
Seb
Bien cool !
T’as reçu mon email?
Oui, je regarde ça et te tiens au jus au plus vite.
Merci
Yo!
j’ai bricolé un peu et ca a l’air de marcher. Testé sur mac Flame 2020.1
hi, The code is not working and the download link is also unavailable,
can u plz fix the download link.
Hi Ashutosh Maurya,
Sorry for the long delay …
The link should be fixed now.