Appliquer un script à toutes les scenes Maya du dossier
Par Narann le vendredi, 29 mai 2009, 22:20 - Script et code - Lien permanent
Il peut arriver en cours de prod d'avoir à appliquer un petite modification sur un grand nombre de scène (en général quand on en arrive là c'est qu'on a des failles dans les rouages quelque part :siffle: ). Je vous propose donc ici un méthode (il y en à d'autres) qui se révèle assez simple pour appliquer un script à l'intégralité des scènes d'un dossier.
Le principe
Comme vous le savez surement déjà, vous pouvez lancez maya en ligne de commande. Pour plus d'information, RTFM! Allez dans l'aide Maya:
User Guide > General > Basics > Interface overview > Work with menu items, tools, and options > Start Maya from the command line
Nous allons donc créer un batch qui lance Maya et exécute un script.
Nous auront besoin de trois choses choses:
- Un premier .bat: Qui contiendra les commandes maya que Windows exécute.
- Un .mel: Qui sera le script exécuté par Maya à l'ouverture.
- Un second .bat: Qui appellera le premier bat une fois pour chaque fichier du dossier.
On pourrait s'y prendre avec un seul .bat mais ça complexifie un peu l'écriture.
On approfondi
La ligne de commande du premier bat ressemble grosso modo à ça (patchFolderScenes.bat):
maya -batch -script <monSuperScript.mel> -file <maSceneMaya.ma>
Le script (monSuperScript.mel):
proc monSuperScript() //declaration de la procedure { print("patchFolderScenes -> Launched...\n"); //on affiche le message de demarrage (facultatif) //mes commandes mel file -save; //on sauvegarde à la fin sinon les modifications ne seront pas apporté à la scene print("patchFolderScenes -> Finished...\n"); //on affiche le message de fin (facultatif) } monSuperScript(); //on lance la procedure
Et pour finir, le second bat qui lancera le premier pour chaque scène maya du dossier en cours (applyPatchToAllScenes.bat):
for <tout les fichier .ma ou .mb> do call patchFolderScenes.bat <nom du fichier>
C'est celui là qu'on lancera.
Du concret
Bon, maintenant que vous connaissez le principe, nous allons appliquer tout ça.
Je vous propose de créer un fichier test.bat et de l'ouvrir avec un éditeur de texte. Il existe des "trucs" (désolé, j'ai pas trouvé d'autres noms) pour afficher les répertoires. Je m'explique:
En batch, les fichiers argument sont des variables écrites comme ça:
%1 << Premier argument du bat %2 << Second argument du bat etc...
Taper dans votre test.bat:
echo %1 pause
- Ouvrez un invite de commande Windows
- Cliquez-glissez votre test.bat
- Mettez un espace
- Glissez un fichier quelconque derrière
- Lancez tous ça!
C:\Documents and Settings\user\testFolder>test.bat monfichier.txt C:\Documents and Settings\user\testFolder>echo monfichier.txt monfichier.txt C:\Documents and Settings\user\testFolder>pause Appuyez sur une touche pour continuer...
Maintenant, mettez:
echo %0 pause
Lancez le:
C:\Documents and Settings\user\testFolder>test.bat C:\Documents and Settings\user\testFolder>echo test.bat test.bat C:\Documents and Settings\user\testFolder>pause Appuyez sur une touche pour continuer...
Oooh... Surprise... %0 correspondau fichier bat lui même.
Ça me fait une belle jambe...
Du calme, ce n'est pas tout :sourit:
"~" (tilde) suivi d'une lettre (cf: petite documentation) va nous permettre de récupérer le chemin du répertoire.
%~0 -> Enlève les guillemets si il y en a. %~f0 -> C:\Documents and Settings\user\testFolder\test.bat %~d0 -> C: %~p0 -> \Documents and Settings\user\testFolder\ %~n0 -> test %~x0 -> .bat %~s0 -> C:\DOCUME~1\user\TESTFO~1\test.bat %~a0 -> --a------ (les attributs du fichier) %~t0 -> 29/05/2009 22:06 (Date de la dernière modification... Pratique hein? ;) ) %~z0 -> 9 (taille en octet, pratique aussi)
Vous l'aurez compris:
echo %~dp0 pause
Donne:
C:\Documents and Settings\user\testFolder>test.bat C:\Documents and Settings\user\testFolder>echo C:\Documents and Settings\user\testFolder\ C:\Documents and Settings\user\testFolder\ C:\Documents and Settings\user\testFolder>pause Appuyez sur une touche pour continuer...
Nous avons maintenant le dossier dans lequel on exécute le bat!
Pour simplifier la procédure, nous allons considérer que votre .mel à exécuter se trouve dans le même répertoire que le .bat :hehe: .
Donc:
echo %~dp0monSuperScript.mel pause
Donne:
C:\Documents and Settings\user\testFolder>test.bat C:\Documents and Settings\user\testFolder>echo C:\Documents and Settings\user\testFolder\monSuperScript.mel C:\Documents and Settings\user\testFolder\monSuperScript.mel C:\Documents and Settings\user\testFolder>pause Appuyez sur une touche pour continuer...
On viens de récupérer le chemin du script qu'on souhaite exécuter. Nous n'avons plus qu'a stocker cette information dans une variable:
SET scriptPath=%~dp0patchFolderScenes.mel
Écrire le début de la ligne de commande avec laquelle on appel Maya:
maya -batch -script "%scriptPath%"
Ajouter l'argument "file" pour dire quel fichier il doit ouvrir
maya -batch -script "%scriptPath%" -file %1
Rappelez vous, %1 est le premier argument donné après le bat.
Votre test.bat:
SET scriptPath=%~dp0patchFolderScenes.mel maya -batch -script "%scriptPath%" -file %1
Si vous lancez:
C:\Documents and Settings\user\testFolder>test.bat maScene.ma
Vous aurez Maya qui ouvrira votre scène, lancera le script et quittera. Aussi simple que ça! Vous pouvez aussi cliquer glissez votre scène sur le .bat:
Renommez votre "test.bat" en "patchFolderScenes.bat".
Nous avons fait la moitié! Prochaine étape, faire un .bat qui appel patchFolderScenes.bat pour chaque fichier .ma ou .mb du fichier.
Patch mes scènes j'te dis!
Créez (toujours dans le même répertoire) un fichier "allPatchFolderScenes.bat" et ouvrez le avec un éditeur de texte.
Et là, attention, c'est du gros!
Dans un premier temps, nous allons apprendre à appeler un .bat depuis un autre .bat :hehe: . Pour cela, nous allons utiliser la commande "call" (sans déconner...). Créez un fichier "allPatchFolderScenes.bat" et entrez y:
call patchFolderScenes.bat maScene.ma
Et double cliquez dessus. C'est comme si vous aviez lancez:
C:\Documents and Settings\user\testFolder>patchFolderScenes.bat maScene.ma
Maintenant, il faut intégrer ça à une boucle de batch.
La boucle
La boucle for en batch se fait sur une ligne...:baffed: La notre prendra la forme:
for %%f in (*.mb *.ma) do [...pleins de choses...]
Cette boucle va récupérer tout les fichiers (sous la variable %%f) et faire: [...pleins de choses...] (En l'occurrence, vous l'aurez compris, un "call patchFolderScenes.bat maScene.ma")
Si vous êtes du genre pressez et que vous tapez:
for %%f in (*.mb *.ma) do call patchFolderScenes.bat %%f
Vous aurez quelques soucis... En effet %%f est juste un nom de fichier. Et il lui faut un chemin complet vers un fichier.
Ni une, ni deux, je vous donne la méthode sans explications (La vérité c'est que je ne me souvient plus moi même comment je l'ai trouvé! :siffle: )
for %%f in (*.mb *.ma) do call patchFolderScenes.bat %%~dpf%%f
Vous n'avez plus qu'a double-cliquer sur "allPatchFolderScenes.bat" et il appellera, pour chaque fichier .ma ou .mb du dossier, "patchFolderScenes.bat" avec comme argument, le chemin de la scène.
Vous pouvez vous redresser et admirer votre ordinateur s'épuiser à ouvrir les 300 plans pour changer la couleur du poil de cul d'un des objet de vos scènes (que vous vous maudissez de ne pas avoir importé en référence externe pour le coup) parce que la femme de votre client à trouvé que c'était "mieux en rose bonbon sur font vert-fuschia"...
Bref, vous y trouverez surement un intérêt! En cas de problème n'hésitez pas à laisser un commentaire, j'ai testé la manipulation mais il se peut que j'ai oublié deux trois détails.
A bientôt!
Dorian
Commentaires
Très intéressant vos commentaires informatiques...
j'y apprends énormément
Félicitation
Si c'est pas du floutage de gueule ça! ^^
Sympas ce tuto. J'ai mis juste une plombe à me rappeler que mon pc n'avait pas la variable environnement de maya....
J'ai modifié une variable dans le "allPatchFolderScenes.bat" pour que ça cherche aussi dans tous les sub-folders :
for /R %%f in (*.ma) do call patchFolderScenes.bat %%~dpf%%f
J'aime bien la nouvelle présentation du blog
PS : Vraiment sympas de voir tous ces mayas s'ouvrir =)
Tres intéressant. Merci pour l'info.
Cela dit, ça fait longtemps que je n'ai pas fait un .bat (ni un .sh d'ailleurs). Si j'avais a faire un tel .bat maintenant, je le ferais en Python.
C'est tellement plus simple. ^^
EDIT :
La ligne de code était mauvaise :
for /R %%f in (*.ma) do call patchFolderScenes.bat %%f
Là le scripte s'applique partout :)
Au lieu d'un .mel, tu mets un .py ?
Il y a peut-être un autre moyen je suppose.
Par contre le %%~dpf%%f, il faut juste mettre %%f ^^'
Merci pour le tuto en tout cas, ça dépanne bien :)
Non, je disais:
- Le script qui va lancer Maya pour chaque scene d'un dossier, je le fais en python direct.
- Et ce n'est plus un .mel que j’exécute mais un .py. :D
Okay, du coup, j'ai jeté un coup d'oeil du côté de mayapy.
Pour ceux qui seraient intéressé pour faire ça en python, je copie ici la procedure et un template de script :
Tout d'abord, dans "C:\Program Files\Autodesk\Maya20xx\bin\", il y a mayapy.exe. Lorsque vous exécutez ce programme, vous avez une fenêtre DOS où vous pouvez copier/coller un script python et l'exécuter en batch :
"""Commencer votre script par ces deux lignes (c'est nécessaire pour lancer un batch)"""
import maya.standalone
maya.standalone.initialize(name='python')
"""Vous pouvez commencer votre script de la manière habituelle"""
import maya.cmds as cmds
import os
"""Lister tous les ".ma" du dossier et des sous-dossier"""
"""Path du dossier:"""
topdir = 'D:\\myFolder'
""" L'extension de fichier que je cherche"""
exten = '.ma'
""" Stocker tous les path de scène dans la variable 'myFiles' """
results = str()
myFiles =
for dirpath, dirnames, files in os.walk(topdir):
for name in files: if name.lower().endswith(exten): results = '%s' % os.path.join(dirpath, name) myFiles.append(results)
"""Les commandes à exécuter dans chaque scènes :"""
"""La boucle:"""
for i in myFiles:
cmds.file(i, force=True, open=True)
"""La ou les commandes que vous voulez appliquer """
cmds.polySphere(sx=5, sy=5, n="Awesome_Batched_Sphere")
""" Save the file"""
cmds.file(save=True, force=True)
Voilà, j'espère que cela peut-être utile à ceux qui passe par ici (le script s’exécute 10 fois plus vite, même plus le temps de prendre un café u.u)
Pour plus de ressources :
- http://www.chadvernon.com/blog/reso...
- http://www.toadstorm.com/blog/?p=13...
Cool merci!
Par contre je te conseil de passer par pastebin car les commentaires gèrent mal le code.