def on_show_prompt_instance_delay_menu(self): prompt_instance_state = cmds.optionVar(query='MTT_prompt_instance_state') if prompt_instance_state == PROMPT_INSTANCE_WAIT: elapsed_time = time() - cmds.optionVar(query='MTT_prompt_instance_suspend') if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state]) else: mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time)) elif prompt_instance_state == PROMPT_INSTANCE_SESSION: if 'mtt_prompt_session' not in __main__.__dict__: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state]) self.instance_menu.clear() prompt_delay = QActionGroup(self) prompt_delay.setExclusive(True) for i in range(len(PROMPT_INSTANCE_STATE.keys())): current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay) current_delay_action.setCheckable(True) current_delay_action.setChecked(prompt_instance_state == i) current_delay_action.triggered.connect( partial(self.view.on_choose_instance_delay, i, prompt=i != 0)) self.instance_menu.addAction(current_delay_action)
def rename_maya_node(self, node_name, wanted_name, deferred=False): """ Rename node and return new name :param node_name: :param wanted_name: :param deferred: :return: """ if cmds.lockNode(node_name, query=True, lock=True)[0] \ or cmds.referenceQuery(node_name, isNodeReferenced=True): mtt_log('%s is locked, cannot perform rename' % node_name, verbose=False) return node_name wanted_name = self.validate_node_name(wanted_name) # get node namespace if exists and prefix wanted name if ':' in node_name: namespace = '{}:'.format(node_name.rsplit(':', 1)[0]) if not wanted_name.startswith(namespace): wanted_name = namespace + wanted_name if deferred: cmd = 'import maya.cmds as cmds;cmds.rename("%s", "%s")' % ( node_name, wanted_name) return cmds.evalDeferred(cmd) else: return cmds.rename(node_name, wanted_name)
def on_show_prompt_instance_delay_menu(self): prompt_instance_state = cmds.optionVar( query='MTT_prompt_instance_state') if prompt_instance_state == PROMPT_INSTANCE_WAIT: elapsed_time = time() - cmds.optionVar( query='MTT_prompt_instance_suspend') if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar( iv=['MTT_prompt_instance_state', prompt_instance_state]) else: mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time)) elif prompt_instance_state == PROMPT_INSTANCE_SESSION: if 'mtt_prompt_session' not in __main__.__dict__: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar( iv=['MTT_prompt_instance_state', prompt_instance_state]) self.instance_menu.clear() prompt_delay = QActionGroup(self) prompt_delay.setExclusive(True) for i in range(len(PROMPT_INSTANCE_STATE.keys())): current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay) current_delay_action.setCheckable(True) current_delay_action.setChecked(prompt_instance_state == i) current_delay_action.triggered.connect( partial(self.view.on_choose_instance_delay, i, prompt=i != 0)) self.instance_menu.addAction(current_delay_action)
def database_dump_sql(self): sql_file = os.path.join(os.path.dirname(__file__), 'debug_db.sql') with open(sql_file, 'w') as f: for line in self.db.iterdump(): f.write('%s\n' % line) mtt_log('SQL Dump write into : %s' % sql_file, add_tag='DEBUG', verbose=False) cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
def show_image(self, texture_path): if os.path.isfile(texture_path): self.texture_path = texture_path self.graphics_view.is_loading_fail = False self.update_status(is_loading=True) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.graphics_view.show_texture(texture_path) QApplication.restoreOverrideCursor() else: self.texture_path = None mtt_log('File not found.', add_tag='VIEWER', msg_type='warning', verbose=False) self.graphics_view.is_loading_fail = True self.graphics_view.reset_image()
def database_dump_csv(self): c = self.db.cursor() c.execute('SELECT * FROM NodesTable as N ' 'LEFT JOIN FilesTable as F ON N.FileId=F.FileId ' 'LEFT JOIN RefTable as R ON N.RefName=R.RefName') import csv file_path = os.path.join(os.path.dirname(__file__), 'debug_db.csv') csv_file = open(file_path, "w") csv_file_writer = csv.writer(csv_file, delimiter=';') csv_file_writer.writerows(c.fetchall()) csv_file.close() mtt_log('CSV Dump write into : %s' % file_path, add_tag='DEBUG', verbose=False) cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
def database_dump_csv(self): c = self.db.cursor() c.execute( 'SELECT * FROM NodesTable as N ' 'LEFT JOIN FilesTable as F ON N.FileId=F.FileId ' 'LEFT JOIN RefTable as R ON N.RefName=R.RefName') import csv file_path = os.path.join(os.path.dirname(__file__), 'debug_db.csv') csv_file = open(file_path, "w") csv_file_writer = csv.writer(csv_file, delimiter=';') csv_file_writer.writerows(c.fetchall()) csv_file.close() mtt_log('CSV Dump write into : %s' % file_path, add_tag='DEBUG', verbose=False) cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
def export_as_csv(self): """ Export texture listing in csv file """ file_content = self.get_database_content_as_csv() # check if current scene is empty if not file_content: mtt_log('Nothing to save. Operation aborted.', msg_type='warning', verbose=False) return # clean output convert_nicename = {n: t for t, n, a in MTTSettings.SUPPORTED_TYPE} for i, row in enumerate(file_content): node_type = convert_nicename[row[1]] ref_str = 'True' if row[2] == 1 else '' missing_str = 'True' if row[3] == -1 else '' file_content[i] = (row[0], node_type, ref_str, missing_str, row[4], row[5]) # query file to write scene_name = os.path.basename(cmds.file(query=True, sceneName=True)) file_path = os.path.join( cmds.workspace(query=True, rootDirectory=True), scene_name) csv_path = cmds.fileDialog2(fileFilter='Texture List (*.csv)', caption='Save Texture List', startingDirectory=file_path, fileMode=0) # fill file if csv_path is not None: import csv file_path = csv_path[0] scene_name = cmds.file(q=True, sceneName=True) or 'Scene UNTITLED' with open(file_path, "w") as csv_file: csv_file_writer = csv.writer(csv_file, delimiter=';') csv_file_writer.writerow([scene_name]) csv_file_writer.writerow([ 'NODE NAME', 'NODE TYPE', 'IS REF', 'MISSING', 'INSTANCE COUNT', 'FILE PATH' ]) csv_file_writer.writerows(file_content) csv_file.close() mtt_log('CSV file saved to %s' % file_path, verbose=False) cmds.launchImageEditor( viewImageFile=os.path.dirname(file_path))
def create_nodes(define_path='', define_type=None): dialog = MTTFilterFileDialog( define_path=define_path, define_type=define_type) if dialog.exec_(): files = dialog.get_selected_files() node_type = dialog.get_node_type() node_attr = [ attr for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE if node_type == n_type][0] current_selection = cmds.ls(selection=True) MTTSettings.set_value('suspendRenameCallbacks', True) nodes = list() for f in files: n_name = os.path.basename(f).rsplit('.')[0] node_name = n_name if not n_name[0].isdigit() else '_%s' % n_name new_node = cmds.shadingNode(node_type, name=node_name, asTexture=1) convert = MTTSettings.value('forceRelativePath') if convert: f = convert_to_relative_path(f) set_attr(new_node, node_attr, f, attr_type='string') if MTTSettings.IMPORT_POLICY: try: exec MTTSettings.IMPORT_POLICY exec_import_policy( current_selection, node_name, os.path.basename(f) ) except RuntimeError: mtt_log('Fail to run import policy.', msg_type='error', verbose=False) nodes.append(new_node) MTTSettings.set_value('suspendRenameCallbacks', False) MTTSettings.remove('suspendRenameCallbacks') if nodes: cmds.select(nodes, replace=True) dialog.deleteLater()
def create_nodes(define_path='', define_type=None): dialog = MTTFilterFileDialog(define_path=define_path, define_type=define_type) if dialog.exec_(): files = dialog.get_selected_files() node_type = dialog.get_node_type() node_attr = [ attr for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE if node_type == n_type ][0] current_selection = cmds.ls(selection=True) MTTSettings.set_value('suspendRenameCallbacks', True) nodes = list() for f in files: n_name = os.path.basename(f).rsplit('.')[0] node_name = n_name if not n_name[0].isdigit() else '_%s' % n_name new_node = cmds.shadingNode(node_type, name=node_name, asTexture=1) convert = MTTSettings.value('forceRelativePath') if convert: f = convert_to_relative_path(f) set_attr(new_node, node_attr, f, attr_type='string') if MTTSettings.IMPORT_POLICY: try: exec MTTSettings.IMPORT_POLICY exec_import_policy(current_selection, node_name, os.path.basename(f)) except RuntimeError: mtt_log('Fail to run import policy.', msg_type='error', verbose=False) nodes.append(new_node) MTTSettings.set_value('suspendRenameCallbacks', False) MTTSettings.remove('suspendRenameCallbacks') if nodes: cmds.select(nodes, replace=True) dialog.deleteLater()
def __init__(self, watcher=None): """ Init model """ QAbstractTableModel.__init__(self) self.table_view = None self.watcher = watcher self.watcher.fileChanged.connect(self.file_watch_file_change) self.watcher.directoryChanged.connect(self.file_watch_directory_change) self.is_reloading_file = False self.suspend_force_sort = False self.supported_format_dict = dict( [(n_type, nodeAttr) for n_type, nice, nodeAttr in MTTSettings.SUPPORTED_TYPE]) self.db = None # create database table try: self._database_create_table() except sqlite3.Error, e: mtt_log('Error init DB :\n\t>> %s <<\n' % e, msg_type='error', verbose=False) sys.exit(1)
def export_as_csv(self): """ Export texture listing in csv file """ file_content = self.get_database_content_as_csv() # check if current scene is empty if not file_content: mtt_log('Nothing to save. Operation aborted.', msg_type='warning', verbose=False) return # clean output convert_nicename = {n: t for t, n, a in MTTSettings.SUPPORTED_TYPE} for i, row in enumerate(file_content): node_type = convert_nicename[row[1]] ref_str = 'True' if row[2] == 1 else '' missing_str = 'True' if row[3] == -1 else '' file_content[i] = (row[0], node_type, ref_str, missing_str, row[4], row[5]) # query file to write scene_name = os.path.basename(cmds.file(query=True, sceneName=True)) file_path = os.path.join(cmds.workspace(query=True, rootDirectory=True), scene_name) csv_path = cmds.fileDialog2( fileFilter='Texture List (*.csv)', caption='Save Texture List', startingDirectory=file_path, fileMode=0) # fill file if csv_path is not None: import csv file_path = csv_path[0] scene_name = cmds.file(q=True, sceneName=True) or 'Scene UNTITLED' with open(file_path, "w") as csv_file: csv_file_writer = csv.writer(csv_file, delimiter=';') csv_file_writer.writerow([scene_name]) csv_file_writer.writerow(['NODE NAME', 'NODE TYPE', 'IS REF', 'MISSING', 'INSTANCE COUNT', 'FILE PATH']) csv_file_writer.writerows(file_content) csv_file.close() mtt_log('CSV file saved to %s' % file_path, verbose=False) cmds.launchImageEditor(viewImageFile=os.path.dirname(file_path))
def __init__(self, watcher=None): """ Init model """ QAbstractTableModel.__init__(self) self.table_view = None self.watcher = watcher self.watcher.fileChanged.connect(self.file_watch_file_change) self.watcher.directoryChanged.connect(self.file_watch_directory_change) self.is_reloading_file = False self.suspend_force_sort = False self.supported_format_dict = dict([ (n_type, nodeAttr) for n_type, nice, nodeAttr in MTTSettings.SUPPORTED_TYPE ]) self.db = None # create database table try: self._database_create_table() except sqlite3.Error, e: mtt_log('Error init DB :\n\t>> %s <<\n' % e, msg_type='error', verbose=False) sys.exit(1)
def change_node_attribute(self, node_name, new_attribute_value): if cmds.lockNode(node_name, query=True, lock=True)[0] \ or cmds.referenceQuery(node_name, isNodeReferenced=True): mtt_log('%s is locked, cannot perform changePath\n' % node_name, verbose=False) return False if self.is_reloading_file: return False # get original data for current node c = self.db.cursor() c.execute( 'SELECT Attribute, FilePath, InstanceCount, FileId ' 'FROM NodesTable LEFT JOIN FilesTable USING (FileId) ' 'WHERE Name=?', (node_name, )) node_attr, node_file_path, instance_count, old_file_id = c.fetchone() new_absolute_attr_value = self.get_attribute_absolute_file_path( node_name, new_attribute_value) key_path = self.convert_to_key_path(new_absolute_attr_value) # check if new_attribute_value already exist c.execute('SELECT EXISTS (SELECT 1 FROM FilesTable WHERE KeyPath=?)', (key_path, )) if c.fetchone()[0] > 0: # instance found c.execute('SELECT FileId FROM FilesTable WHERE KeyPath=?', (key_path, )) new_file_id = c.fetchone()[0] else: # new entry c.execute( 'INSERT ' 'INTO FilesTable(KeyPath, FilePath, State, InstanceCount) ' 'VALUES (?, ?, ?, ?)', (key_path, new_absolute_attr_value, self.get_file_state(new_absolute_attr_value), 0) ) new_file_id = c.lastrowid self.file_watch_add_path(new_absolute_attr_value) # update old file instance count and state c.execute('SELECT InstanceCount FROM FilesTable WHERE FileId=?', (old_file_id, )) if c.fetchone()[0] == 1 and node_file_path != new_absolute_attr_value: c.execute('DELETE FROM FilesTable WHERE FileId=?', (old_file_id, )) else: c.execute( 'UPDATE FilesTable SET InstanceCount=InstanceCount - 1 ' 'WHERE FileId=?', (old_file_id, )) c.execute( 'UPDATE FilesTable SET State=? ' 'WHERE FileId=?', (self.get_file_state(node_file_path), old_file_id)) # set new values c.execute('UPDATE NodesTable SET Attribute=? WHERE Name=?', (new_attribute_value, node_name)) c.execute('UPDATE NodesTable SET FileId=? WHERE Name=?', (new_file_id, node_name)) c.execute('UPDATE FilesTable SET InstanceCount=InstanceCount + 1 ' 'WHERE FileId=?', (new_file_id, )) c.execute('UPDATE FilesTable SET State=? WHERE FileId=?', (self.get_file_state(new_absolute_attr_value), new_file_id)) self.db.commit() # notify data changed index = self.get_node_model_id(node_name) self.dataChanged.emit(index, index) return True
def show_texture(self, texture_path): # create pointers width_util = om.MScriptUtil() width_util.createFromInt(0) width_ptr = width_util.asUintPtr() height_util = om.MScriptUtil() height_util.createFromInt(0) height_ptr = height_util.asUintPtr() # create Maya native MImage maya_texture = om.MImage() maya_texture.readFromFile(texture_path) maya_texture.verticalFlip() maya_texture.getSize(width_ptr, height_ptr) # get texture info width_value = width_util.getUint(width_ptr) height_value = height_util.getUint(height_ptr) texture_size = width_value * height_value * 4 # convert to Qt format image_format = QImage.Format_ARGB32_Premultiplied \ if MTTSettings.value('Viewer/premultiply') \ else QImage.Format_RGB32 show_default = False qt_image = None try: self.image_buffer = ctypes.c_ubyte * texture_size self.image_buffer = self.image_buffer.from_address(long(maya_texture.pixels())) qt_image = QImage(self.image_buffer, width_value, height_value, image_format).rgbSwapped() self.is_loading_fail = False mtt_log('%s loaded' % os.path.basename(texture_path), add_tag='VIEWER', verbose=False) except Exception as e: mtt_log('%s\n%s' % (type(e), e), add_tag='VIEWER', msg_type='error', verbose=False) mtt_log('Fail to load %s' % os.path.basename(texture_path), add_tag='VIEWER', msg_type='error', verbose=False) self.is_loading_fail = True if MTTSettings.value('Viewer/recoverMode'): try: import time start = time.clock() qt_image = QImage(width_value, height_value, QImage.Format_ARGB32) pixel_ptr = maya_texture.pixels() for y in xrange(height_value): for x in xrange(1, width_value): i = (y * width_value) + x i = 4 * (i - 1) r = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i) g = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i + 1) b = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i + 2) a = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i + 3) qt_image.setPixel(x, y, QColor(r, g, b, a).rgba()) end = time.clock() mtt_log('Image read in %.3fs' % (end - start), verbose=False) except Exception as e: mtt_log(e, add_tag='VIEWER', msg_type='error', verbose=False) show_default = True else: show_default = True except RuntimeError as e: mtt_log('%s\n%s' % (type(e), e), add_tag='VIEWER', msg_type='error', verbose=False) mtt_log('Fail to load %s' % os.path.basename(texture_path), add_tag='VIEWER', msg_type='error', verbose=False) self.is_loading_fail = True show_default = True if show_default: self.reset_image() return self.current_texture = QPixmap.fromImage(qt_image) # display texture in QGraphicsView self.__add_texture_item(False) self.update_status()
def change_node_attribute(self, node_name, new_attribute_value): if cmds.lockNode(node_name, query=True, lock=True)[0] \ or cmds.referenceQuery(node_name, isNodeReferenced=True): mtt_log('%s is locked, cannot perform changePath\n' % node_name, verbose=False) return False if self.is_reloading_file: return False # get original data for current node c = self.db.cursor() c.execute( 'SELECT Attribute, FilePath, InstanceCount, FileId ' 'FROM NodesTable LEFT JOIN FilesTable USING (FileId) ' 'WHERE Name=?', (node_name, )) node_attr, node_file_path, instance_count, old_file_id = c.fetchone() new_absolute_attr_value = self.get_attribute_absolute_file_path( node_name, new_attribute_value) key_path = self.convert_to_key_path(new_absolute_attr_value) # check if new_attribute_value already exist c.execute('SELECT EXISTS (SELECT 1 FROM FilesTable WHERE KeyPath=?)', (key_path, )) if c.fetchone()[0] > 0: # instance found c.execute('SELECT FileId FROM FilesTable WHERE KeyPath=?', (key_path, )) new_file_id = c.fetchone()[0] else: # new entry c.execute( 'INSERT ' 'INTO FilesTable(KeyPath, FilePath, State, InstanceCount) ' 'VALUES (?, ?, ?, ?)', (key_path, new_absolute_attr_value, self.get_file_state(new_absolute_attr_value), 0)) new_file_id = c.lastrowid self.file_watch_add_path(new_absolute_attr_value) # update old file instance count and state c.execute('SELECT InstanceCount FROM FilesTable WHERE FileId=?', (old_file_id, )) if c.fetchone()[0] == 1 and node_file_path != new_absolute_attr_value: c.execute('DELETE FROM FilesTable WHERE FileId=?', (old_file_id, )) else: c.execute( 'UPDATE FilesTable SET InstanceCount=InstanceCount - 1 ' 'WHERE FileId=?', (old_file_id, )) c.execute('UPDATE FilesTable SET State=? ' 'WHERE FileId=?', (self.get_file_state(node_file_path), old_file_id)) # set new values c.execute('UPDATE NodesTable SET Attribute=? WHERE Name=?', (new_attribute_value, node_name)) c.execute('UPDATE NodesTable SET FileId=? WHERE Name=?', (new_file_id, node_name)) c.execute( 'UPDATE FilesTable SET InstanceCount=InstanceCount + 1 ' 'WHERE FileId=?', (new_file_id, )) c.execute('UPDATE FilesTable SET State=? WHERE FileId=?', (self.get_file_state(new_absolute_attr_value), new_file_id)) self.db.commit() # notify data changed index = self.get_node_model_id(node_name) self.dataChanged.emit(index, index) return True
def show_texture(self, texture_path): # create pointers width_util = om.MScriptUtil() width_util.createFromInt(0) width_ptr = width_util.asUintPtr() height_util = om.MScriptUtil() height_util.createFromInt(0) height_ptr = height_util.asUintPtr() # create Maya native MImage maya_texture = om.MImage() maya_texture.readFromFile(texture_path) maya_texture.verticalFlip() maya_texture.getSize(width_ptr, height_ptr) # get texture info width_value = width_util.getUint(width_ptr) height_value = height_util.getUint(height_ptr) texture_size = width_value * height_value * 4 # convert to Qt format image_format = QImage.Format_ARGB32_Premultiplied \ if MTTSettings.value('Viewer/premultiply') \ else QImage.Format_RGB32 show_default = False qt_image = None try: self.image_buffer = ctypes.c_ubyte * texture_size self.image_buffer = self.image_buffer.from_address( long(maya_texture.pixels())) qt_image = QImage(self.image_buffer, width_value, height_value, image_format).rgbSwapped() self.is_loading_fail = False mtt_log('%s loaded' % os.path.basename(texture_path), add_tag='VIEWER', verbose=False) except Exception as e: mtt_log('%s\n%s' % (type(e), e), add_tag='VIEWER', msg_type='error', verbose=False) mtt_log('Fail to load %s' % os.path.basename(texture_path), add_tag='VIEWER', msg_type='error', verbose=False) self.is_loading_fail = True if MTTSettings.value('Viewer/recoverMode'): try: import time start = time.clock() qt_image = QImage(width_value, height_value, QImage.Format_ARGB32) pixel_ptr = maya_texture.pixels() for y in xrange(height_value): for x in xrange(1, width_value): i = (y * width_value) + x i = 4 * (i - 1) r = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i) g = om.MScriptUtil.getUcharArrayItem( pixel_ptr, i + 1) b = om.MScriptUtil.getUcharArrayItem( pixel_ptr, i + 2) a = om.MScriptUtil.getUcharArrayItem( pixel_ptr, i + 3) qt_image.setPixel(x, y, QColor(r, g, b, a).rgba()) end = time.clock() mtt_log('Image read in %.3fs' % (end - start), verbose=False) except Exception as e: mtt_log(e, add_tag='VIEWER', msg_type='error', verbose=False) show_default = True else: show_default = True except RuntimeError as e: mtt_log('%s\n%s' % (type(e), e), add_tag='VIEWER', msg_type='error', verbose=False) mtt_log('Fail to load %s' % os.path.basename(texture_path), add_tag='VIEWER', msg_type='error', verbose=False) self.is_loading_fail = True show_default = True if show_default: self.reset_image() return self.current_texture = QPixmap.fromImage(qt_image) # display texture in QGraphicsView self.__add_texture_item(False) self.update_status()