## popup message -A disappearing message def popupMessage(function_name): """ Displays an in-view message indicating that a function has been copied to the clipboard. :param function_name: #The name of the function that has been copied. :return: """ mc.inViewMessage(amg="Copied!!\nFunction name '{0}' has been copied to the clipboard.".format(function_name), pos='midCenter', fade=True) # Test function is provided to test main function popupMessage def test_popupMessage(): popupMessage(function_name='exampleFunction') # Since mc.inViewMessage affects the UI, manual verification is required. print("popupMessage executed successfully.") test_popupMessage()
top of page

โœจ๐ŸŽฏ ๐˜ฟ๐™–๐™ฎ04 -100-๐˜ฟ๐™–๐™ฎ๐™จ ๐˜พ๐™ค๐™™๐™š ๐™Ž๐™ฃ๐™ž๐™ฅ๐™ฅ๐™š๐™ฉ๐™จ ๐˜พ๐™๐™–๐™ก๐™ก๐™š๐™ฃ๐™œ๐™š ๐Ÿš€๐ŸŽจ

Writer's picture: Subbu AddankiSubbu Addanki

โœจ๐ŸŽฌ ๐™‰๐™š๐™ฌ ๐™๐™ค๐™ค๐™ก ๐™„๐™ฃ๐™ฉ๐™ง๐™ค: "AssetLocator" ๐ŸŒ

Hey there, fellow Maya professionals! ๐Ÿ‘‹

Day 04ย of the 100-Days Challenge brings you an exciting and essential toolโ€”AssetLocatorโ€”designed to help you locate and manage assetsย across complex Maya projects. Whether you're working with multiple references, texture files, or external assets, keeping track of everything can get tricky. AssetLocatorย does the heavy lifting by automating the process of finding missing or broken file references, ensuring that your projects are always in sync.

๐˜ž๐˜ฉ๐˜ข๐˜ต ๐˜ผ๐™จ๐™จ๐™š๐™ฉ๐™‡๐™ค๐™˜๐™–๐™ฉ๐™ค๐™ง Offers:

  • Asset Tracking:ย Quickly locate missing file references, including textures, models, and external files.

  • Path Fixing:ย Automatically repair broken file paths or prompt the user for correct locations.

  • Cross-Project Compatibility:ย Works seamlessly with multiple Maya projects and references.

๐Ÿ› ๏ธ ๐˜ผ๐™จ๐™จ๐™š๐™ฉ๐™‡๐™ค๐™˜๐™–๐™ฉ๐™ค๐™ง (maya.cmds Version):



##1

import maya.cmds as mc

import os


def locate_and_fix_missing_files(base_path="", fix_paths=False):

"""

Locates missing file textures and references in the Maya scene.

Optionally attempts to fix broken paths using a base path.

Parameters:

base_path (str): The base directory to search for missing assets.

fix_paths (bool): If True, attempts to fix broken paths by searching in the base_path.

Returns:

dict: A dictionary with 'missing_files' and 'fixed_files' lists.

"""

missing_files = set()

fixed_files = []


# Check for missing file texture nodes

file_nodes = mc.ls(type='file')

for node in file_nodes:

file_path = mc.getAttr(node + '.fileTextureName')

if file_path and not os.path.exists(file_path):

missing_files.add(file_path)

if fix_paths and base_path:

potential_file = os.path.join(base_path, os.path.basename(file_path))

if os.path.exists(potential_file):

mc.setAttr(node + '.fileTextureName', potential_file, type='string')

fixed_files.append(potential_file)


# Check for missing references

references = mc.file(query=True, reference=True)

for ref_file in references:

if not os.path.exists(ref_file):

missing_files.add(ref_file)

if fix_paths and base_path:

potential_file = os.path.join(base_path, os.path.basename(ref_file))

if os.path.exists(potential_file):

ref_node = mc.file(ref_file, query=True, referenceNode=True)

mc.file(potential_file, loadReference=ref_node)

fixed_files.append(potential_file)


if missing_files:

print("Missing Files Detected:")

for file in missing_files:

print("Missing: {}".format(file))

if fix_paths and base_path:

if file in fixed_files:

print("Fixed: {}".format(file))

else:

print("Cannot locate: {}".format(file))

else:

print("No missing files found.")


return {'missing_files': list(missing_files), 'fixed_files': fixed_files}


# Example usage:

# To locate missing files without attempting to fix paths:

locate_and_fix_missing_files()


# To locate and attempt to fix missing files using a base path:

# base_path = "/path/to/your/assets"

# locate_and_fix_missing_files(base_path=base_path, fix_paths=True)

๐Ÿ› ๏ธ ๐˜ผ๐™จ๐™จ๐™š๐™ฉ๐™‡๐™ค๐™˜๐™–๐™ฉ๐™ค๐™ง (PySide2 Version):

import maya.cmds as mc

import os

from PySide2 import QtWidgets, QtCore, QtGui

import maya.OpenMayaUI as omui

from shiboken2 import wrapInstance


def maya_main_window():

"""

Returns Maya's main window as a QWidget instance.

"""

main_window_ptr = omui.MQtUtil.mainWindow()

return wrapInstance(long(main_window_ptr), QtWidgets.QWidget)


class AssetLocatorUI(QtWidgets.QDialog):

"""

AssetLocatorUI helps locate and fix missing file references in a Maya project.


This UI has a sleek, stylish look with orange highlights and a dark theme.

"""

instance = None # Singleton instance


def __init__(self, parent=None):

super(AssetLocatorUI, self).__init__(parent or maya_main_window())


# Set window properties

self.setWindowTitle('Asset Locator')

self.setObjectName('AssetLocatorUI')

self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowStaysOnTopHint)

self.resize(500, 400)


# Apply advanced styling

self.setStyleSheet("""

QWidget#AssetLocatorUI {

background-color: #2C2C2C; /* Dark background */

border: 2px solid #FF914D; /* Orange border */

border-radius: 10px;

font-family: 'Agave';

color: #F5F5F5;

}

QLabel {

font-family: 'Agave';

color: #F5F5F5;

}

QPushButton {

font-family: 'Agave';

background-color: #4A4A4A;

color: #FFFFFF;

border: 2px solid #FF914D;

border-radius: 8px;

padding: 8px 15px;

transition: all 0.3s ease;

}

QPushButton:hover {

background-color: #FF914D;

color: #2C2C2C;

border: 2px solid #F5F5F5;

}

QPushButton:pressed {

background-color: #FF7043;

border: 2px solid #FF914D;

}

QLineEdit {

background-color: #3A3A3A;

border: 2px solid #FF914D;

border-radius: 5px;

padding: 4px;

color: #F5F5F5;

}

QScrollArea {

background-color: #2C2C2C;

border: none;

}

""")


self.fix_paths = False

self.base_path = ""


# Set layout

self.layout = QtWidgets.QVBoxLayout()

self.layout.setContentsMargins(10, 10, 10, 10)


# Status label

self.status_label = QtWidgets.QLabel("Click 'Locate Missing Files' to begin.")

self.layout.addWidget(self.status_label)


# Scroll area for missing files

self.scroll_area = QtWidgets.QScrollArea()

self.scroll_area.setWidgetResizable(True)

self.scroll_content = QtWidgets.QWidget()

self.scroll_layout = QtWidgets.QVBoxLayout(self.scroll_content)

self.scroll_area.setWidget(self.scroll_content)

self.layout.addWidget(self.scroll_area)


# Base path input

base_path_layout = QtWidgets.QHBoxLayout()

self.base_path_label = QtWidgets.QLabel("Base Path:")

self.base_path_input = QtWidgets.QLineEdit()

self.base_path_input.setPlaceholderText("Enter base path to search for assets")

base_path_layout.addWidget(self.base_path_label)

base_path_layout.addWidget(self.base_path_input)

self.layout.addLayout(base_path_layout)


# Fix paths checkbox

self.fix_paths_checkbox = QtWidgets.QCheckBox("Attempt to fix broken paths")

self.layout.addWidget(self.fix_paths_checkbox)


# Locate button

self.locate_button = QtWidgets.QPushButton("Locate Missing Files")

self.locate_button.clicked.connect(self.locate_files)

self.layout.addWidget(self.locate_button)


# Cancel button

self.cancel_button = QtWidgets.QPushButton("Close")

self.cancel_button.clicked.connect(self.close)

self.layout.addWidget(self.cancel_button)


# Set layout

self.setLayout(self.layout)


@classmethod

def display(cls):

"""

Displays the AssetLocatorUI, ensuring only one instance exists.

"""

if cls.instance is None or not cls.instance.isVisible():

cls.instance = AssetLocatorUI()

cls.instance.show()

else:

cls.instance.raise_()

cls.instance.activateWindow()


def locate_files(self):

"""

Locates missing files and updates the UI with their status.

"""

self.fix_paths = self.fix_paths_checkbox.isChecked()

self.base_path = self.base_path_input.text()


# Clear previous results

for i in reversed(range(self.scroll_layout.count())):

widget = self.scroll_layout.takeAt(i).widget()

if widget is not None:

widget.setParent(None)


missing_files = set()


# Check for missing file texture nodes

file_nodes = mc.ls(type='file')

for node in file_nodes:

file_path = mc.getAttr(node + '.fileTextureName')

if file_path and not os.path.exists(file_path):

missing_files.add(file_path)


# Check for missing references

references = mc.ls(type='reference')

for ref_node in references:

if ref_node == 'sharedReferenceNode':

continue # Skip the shared reference node

try:

ref_file = mc.referenceQuery(ref_node, filename=True)

if ref_file and not os.path.exists(ref_file):

missing_files.add(ref_file)

except RuntimeError:

# Handle unloaded or broken references

ref_file = mc.referenceQuery(ref_node, filename=True, unresolvedName=True)

if ref_file and not os.path.exists(ref_file):

missing_files.add(ref_file)


if missing_files:

self.status_label.setText("Missing Files Detected:")

for file in missing_files:

label = QtWidgets.QLabel("Missing: {0}".format(file))

self.scroll_layout.addWidget(label)

if self.fix_paths and self.base_path:

potential_file = os.path.join(self.base_path, os.path.basename(file))

if os.path.exists(potential_file):

# For file textures

file_nodes_with_path = mc.ls(type='file')

for node in file_nodes_with_path:

node_file_path = mc.getAttr(node + '.fileTextureName')

if node_file_path == file:

mc.setAttr(node + '.fileTextureName', potential_file, type='string')

label.setText("Fixed: {0}".format(potential_file))

# For references

reference_nodes = mc.ls(type='reference')

for ref_node in reference_nodes:

if ref_node == 'sharedReferenceNode':

continue

try:

ref_file = mc.referenceQuery(ref_node, filename=True)

except RuntimeError:

ref_file = mc.referenceQuery(ref_node, filename=True, unresolvedName=True)

if ref_file == file:

mc.file(potential_file, loadReference=ref_node)

label.setText("Fixed Reference: {0}".format(potential_file))

else:

label.setText("Cannot locate: {0}".format(file))

else:

self.status_label.setText("No missing files found.")


def closeEvent(self, event):

"""

Overrides the close event to reset the instance variable.

"""

AssetLocatorUI.instance = None

event.accept()


# Function to display the AssetLocatorUI

def show_asset_locator_ui():

AssetLocatorUI.display()


# Example usage

show_asset_locator_ui()





๐Ÿ” ๐˜ผ๐™จ๐™จ๐™š๐™ฉ๐™‡๐™ค๐™˜๐™–๐™ฉ๐™ค๐™ง Benefits:

  • Find & Fix:ย Quickly identify and resolve missing file references in large projects.

  • User-Friendly: The UI provides instant feedback on missing assets, guiding you through fixing broken paths.

  • Project Optimization:ย Maintain organized and error-free file management across different projects.

๐Ÿ”ง ๐™†๐™š๐™ฎ ๐˜ฝ๐™š๐™ฃ๐™š๐™›๐™ž๐™ฉ๐™จ:

โ€ข ๐ŸŒ Locate Broken Links:ย Ensure all your projectโ€™s file references are intact and accessible.

โ€ข ๐Ÿ› ๏ธ Auto Fix Paths:ย Automatically repair broken file paths by searching in specified directories.

โ€ข ๐Ÿ“ˆ Efficient File Management:ย Spend less time troubleshooting missing files and more time creating.

โœจ Ready to Keep Your Projects in Sync?Try out AssetLocatorย and keep your Maya projects running smoothly. Comment below or reach out to see it in action! ๐Ÿ’ช๐Ÿ”


10 views0 comments

Comments


bottom of page