PyWinAuto + Maya 3D – Notizen eines unerfahrenen Automatisierers / Sudo Null IT News

Warum ist es wichtig, die Details zu kennen, bevor Sie mit der Arbeit beginnen?

Es gab eine Aufgabe: ungefähr einhundertdreißig Aufnahmen zu machen, die Beleuchtung darin anzupassen, Probleme zu beheben, falls es welche gibt, und sie zum Rendern zu schicken. Die Software ist Autodesk Maya, und jede Aufnahme ist eine separate Datei mit Animation und allen Torten. Und so fünfundzwanzig Mal, weil fünfundzwanzig Folgen.

Als ich die Aufgabe übernahm, dachte ich naiv, dass man eine Folge pro Monat herausbringen könnte. Ungefähr die gleichen Timings wurden von Kunden angekündigt.

Ich habe mich grausam geirrt: Zuerst hat es sich gelohnt, das Arbeitsverfahren herauszufinden, da es jemand hat.
Als ich es herausfand, war ich entsetzt. Es sah aus, als würde es für eine Episode davonfliegen ab eineinhalb Monaten.

Wie man lebt, wenn man die Details nicht gelernt hat

Nachdem ich den krampfhaften Wunsch, neue Kunden zu finden, überwunden hatte, setzte ich mich hin, um darüber nachzudenken, was unter diesen Umständen getan werden könnte.

Ich habe den Prozess dokumentiert und temporäre Ressourcen gemalt.

Bei vielen Operationen ist der 3D-Künstler untätig. Zum Beispiel dauert das Laden von Maya nur ein oder zwei Minuten.

Klingt komisch, ich verstehe. Es hört auf, lustig zu sein, wenn Sie dieses Zeichen betrachten:

109 Stunden nur um zu öffnen!  Es ist fast ein Monat.109 Stunden nur um zu öffnen! Es ist fast ein Monat.

Bei allen sechs Operationen macht eine Person ein paar Klicks auf die Operation und starrt dann nachdenklich auf den Monitor. Ich mag dieses Arbeitsformat wirklich nicht, es zieht die ganze Aufmerksamkeit in ein paar Stunden auf sich.

Die Optimierung der Pipeline ist problematisch: Die Modelle sind russisch, die Animation ist iranisch, alles wird von einem Drittanbieter zusammengestellt, die Plugins für das Projekt werden auch von Iranern geschrieben.
Mit den Händen in all diese Pracht zu klettern, ist beängstigend: Erstens besteht die Gefahr, dass Sie sich für immer verirren, und zweitens, wenn Sie eine Pause aus einer Stapeldatei entfernen, können Sie versehentlich den ganzen Wagen beschädigen.

Aber Sie können einen PC-Operator mit einer Python imitieren! Ich habe Informationen von Kollegen über Fehler gesammelt, die im Arbeitsprozess auftreten. Ich war überzeugt, dass die meisten von ihnen typisch sind und auch nicht in das Drehbuch eingreifen werden. Und er fing an, über einen Fluchtplan nachzudenken, der die Ausfallzeit des Betreibers abkürzen würde.

Zunächst habe ich die Aufgaben mit zwei Farben markiert: Die Anwesenheit des Gehirns während der Ausführung ist obligatorisch und optional.

Also habe ich Operationen isoliert, die problemlos in ein Skript übertragen werden können.

Wie wurde entschieden

Nachdem ich die PyWinAuto-Bibliothek mehrmals verwendet hatte, wandte ich mich erneut ihr zu.

Es gibt viele Leute auf dem Render und sie haben unterschiedliche Autos, also wurde der koordinierte Ansatz zur Automatisierung verworfen – ich werde die Knöpfe beim Namen fangen.

gehen

Importieren Sie die erforderlichen Bibliotheken.

import pywinauto as pw # zum Arbeiten mit der GUI import os # zum Arbeiten mit Dateien und Ordnern von time import sleep # für Timer import logging # zum Protokollieren import sys # zum Anzeigen von Informationen auf dem Terminal von PIL import ImageGrab # für Screenshots von datetime import datetime # um die Zeit in den Titel des Screenshots zu schreiben import matplotlib.pyplot als plt # falls Sie dringend ein paar Graphen erstellen möchten

Das erste, was Sie wollen, ist zügellose Protokollierung! Vielleicht sogar mit Screenshots. Aber das ist nicht genau, also werden wir den Screenshot an die Palstekne hängen.

def log(file_name, massage, screenshot = False): logging.basicConfig( format=”%(asctime)s %(message)s”, encoding=’utf-8′, level=logging.DEBUG, handlers=[
logging.FileHandler(“log\\” + file_name + ‘.log’),
logging.StreamHandler(sys.stdout)
]) logging.debug(massage) if screenshot == True: now = datetime.now() current_time = now.strftime(“%H_%M_%S_”) myscreen = ImageGrab.grab() myscreen.save(“log\\ ” + aktuelle_zeit + dateiname + ‘.jpg’)

Die zweite besteht darin, eine Liste von Dateien mit Anwesenheiten und Passwörtern zu erhalten. Die Quelldateien befinden sich in einem separaten Ordner neben dem Skript, sodass alles bequem ist.

def get_files_list(): path = os.getcwd() # die Adresse des Arbeitsverzeichnisses abholen files = os.listdir(path + ‘\\animate’) # die Liste zur Verarbeitung sammeln return(files)

Die dritte besteht darin, jede Datei zu verarbeiten. Ich werde das Design zusammenstellen, das ich weiter ergänzen werde.

def process(): files = get_files_list() für file in files: open_shot(file) bake_animation_curves(file) get_assembly(file)

Lassen Sie uns die Datei in der Stirn über den Explorer öffnen. Ich gebe zu, dass es einfachere Methoden gibt.

def open_shot(file): pw.Application().start(‘explorer.exe “C:\\Program Files”‘) # Explorer-App starten = pw.Application(backend=”uia”).connect(path=”explorer .exe”, title=”Programmdateien”) # damit verbinden dlg = app[“Program Files”] # mit dem dlg-Fenster verbinden[‘Address: C:\Program Files’].wait(“ready”) # warten, bis der Suchstring bereit ist dlg.type_keys(“%D”) # mit einem Hotkey dorthin wechseln dlg.type_keys(file, with_spaces=True) # dort die Datei eingeben dlg. type_keys(“{ENTER}”) app.kill() # Explorer schließen

Dreißig Sekunden nach dem Zugriff auf die Datei erscheint das Maya-Fenster. Lassen Sie uns eine Funktion schreiben, die das Erscheinungsbild des Fensters überprüft und gleichzeitig dem Skript Zugriff auf Maya gewährt.

def maya_connect(): try: # Versuch, eine Verbindung zum Fenster herzustellen: app = pw.Application(backend=”uia”).connect(title_re=”.* – Autodesk Maya 2020.4:”) print(“Connected!”) return app # wenn es kein Fenster gibt: außer pw.findwindows.ElementNotFoundError: # Sie können einfach time.sleep() nehmen, aber das wird # den Benutzer wissen lassen, dass das Skript für i nicht hängen bleibt [‘. ‘, ‘.. ‘, ‘…’]: sys.stdout.write(‘\r'”Connecting” + i) sleep(1) return maya_connect()

Jetzt müssen Sie verstehen, dass die Datei geöffnet wurde und Sie damit arbeiten können. Die Option, an einem Timer zu hängen, ist nicht gut: Die Dateien wiegen unterschiedlich, sie brauchen unterschiedlich lange zum Herunterladen.

PyWinAuto schlägt app.wait_cpu_usage_lower(threshold=5) vor – guter Plan!
Sehen wir uns an, wie Mayas CPU-Verbrauchskurve aussieht:

der Code

def get_app_load(app):

Ladepunkte = [1] # Liste zum Laden von Aufzeichnungen # beginnt bei eins, um den Loop-Timer auszuführen = [0] # Liste zum Zählen der Sekunden seit Beginn des Ladedatensatzes n = 0 # Zeitzähler # bis die Summe der Ladewerte der letzten 60 Sekunden Null wird, # die Werte sammeln während sum(load_points[-60:]) != 0: load = app.cpu_usage() if load < 0.5: # zufällige Spitzen entfernen load = 0 load_points.append(load) n += 1 timer.append(n) sleep(1) plt.plot(timer, Ladepunkte) plt.show() Maja startenMaja starten

Maya gibt während des Betriebs diskret CPU-Ressourcen frei, sodass es keinen Sinn macht, auf cpu_lower zu warten.

Kompatible Timer- und CPU-Lastprüfung:

def app_status(app): “””wenn Maya den Prozessor in den letzten 30 Sekunden nicht berührt hat, gehen wir davon aus, dass er frei ist””” load_points = [1]
while sum(load_points[-30:]) != 0: load = app.cpu_usage() if load < 0.5: # zufällige Spitzen entfernen load = 0 load_points.append(load) for i in ['. ', '.. ', '...']: sys.stdout.write('\r'"Maya funktioniert jetzt" + i) sleep(0.33)

Wir werden diese Konstruktion nutzen, um das Betriebsende abzuwarten.

Die Datei wurde geöffnet, jetzt können Sie etwas automatisieren

…zuvor mit Werkzeugen belegt. Wir brauchen:

Eine Funktion, die den Baum der Elemente im ausgewählten Dialog druckt:

# zum Drucken in Datei dlg.print_control_identifiers(Tiefe = None, Dateiname = “MayaControls.txt”) # oder einfach dlg.print_control_identifiers(Tiefe = None) ausgeben

Und eine Funktion, die ein grünes Rechteck um das ausgewählte Element zeichnet:

# oder nicht grün, wie man es einstellt 🙂 dlg.draw_outline(colour=”green”) dlg[‘ShowMenuItem2’].draw_outline(colour=”red”) dlg.MultyDoTask.draw_outline(colour=”blue”)

So greifen Sie auf Elemente zu

Dialog − dlg ist eine Box mit grafischen Elementen. Und das Hauptfenster der Anwendung ist auch ein Dialog, sodass Sie über dlg = pw.Desktop(backend=”uia”) auf das Fenster zugreifen können, das Sie interessiert.[“Anything”].

Unabhängig davon, wie Sie mit dem Dialog arbeiten, über connect() oder Desktop, müssen Sie definieren, was Dies Dialog unterscheidet sich von Brüdern. Oft reicht der auf dem Bildschirm angezeigte Name aus.

Innerhalb des Dialogs befinden sich nicht nur Grafiken, sondern Controller: Schaltflächen, Kontrollkästchen, dergleichen und … andere Dialoge.

Wir treten in den Dialog ein:

# so: dlg = pw.Desktop(backend=”uia”)[“Untitled – Notepad”]

# oder so: app = pw.application.Application(backend=”uia”).connect(title = “Untitled – Notepad”) dlg = app[“Untitled – Notepad”]

Dann suchen und machen wir etwas mit dem notwendigen Element:

dlg[“File”].click_input() # Klicken Sie auf die Schaltfläche “Datei”.

Python ist verdammt viel schneller als die grafische Oberfläche und noch mehr die monströse Software. Bevor wir also die Aktion ausführen, bitten wir das Skript zu warten:

# alle zusammen oder jede Kombination: dlg[“File”].wait(“existiert aktiviert sichtbar bereit aktiv”).click_input()

Wenn die gewünschte Schaltfläche in der Oberfläche vom Skript leicht anhand des Namens gefunden wird, ist alles in Ordnung.
Wenn der falsche gefunden wird, drucken wir die Bezeichner, finden den eindeutigen Namen des Buttons und alles ist wieder in Ordnung.

So könnte der ID-Baum aussehen seltsam.

Zunächst müssen Sie sicherstellen, dass das richtige Backend ausgewählt ist, wenn Sie sich mit der Anwendung verbinden:

In der Notepad-Illustration ist Mayas Elementbaum sehr verzweigt.In der Notepad-Illustration ist Mayas Elementbaum sehr verzweigt.

Es ist nicht erforderlich, die Elemente des gesamten Fensters anzuzeigen. Es lohnt sich, nur das Interessengebiet auszuwählen.

Nun, außerdem können Sie die Aushubtiefe anpassen:

# so dass nur die ersten beiden Schritte von dlg ausgegeben werden[“File”].print_control_identifiers (Tiefe = 2)In der Notepad-Illustration ist Mayas Elementbaum sehr verzweigt.In der Notepad-Illustration ist Mayas Elementbaum sehr verzweigt.

Dieses Wissen reicht aus, um mit Maya 3D zu beginnen, aber die Möglichkeiten von PyWinAuto sind viel größer.

Wir stolpern über Operationen, fügen eine Überprüfung des Ressourcenverbrauchs dazwischen ein und lassen das Skript frei schweben!

Endlich

Bei der Massenverarbeitung von Dateien lohnt es sich sehr, sehr, Konstruktionen in Try / Except zu verpacken: Es ist eine Schande herauszufinden, dass das Skript um zwei Uhr morgens abgestürzt ist und die Maschine die ganze Nacht im Leerlauf gestanden hat.

Das Projekt nähert sich dem Finale.

Zusätzlich zu den Prozessen haben wir die Szenen optimiert, was auch die Bearbeitungszeit schön verkürzt.

Ich möchte dem Entwickler PyWinAuto danken, denn ohne ihn habe ich mich hingelegt und bin gestorben.

Similar Posts

Leave a Reply

Your email address will not be published.