Holen Sie sich Alembic-Informationen mit Python

SOP, DOP, Wrangle scheint mit Material bedeckt zu sein: dancer_tone5: Also würde ich gerne Python-Material schreiben. Die Version ist ab Houdini 15.5. Da Houdini ein knotenbasiertes System ist, das visuelle Programmierung ermöglicht, gibt es meiner Meinung nach weniger Möglichkeiten für die Skripterstellung mit Python als mit anderer 3D-CG-Software. Wo benutzt du Python? : Punch_Tone1: Ich spreche darüber, aber schließlich ist die Pipeline-Entwicklung die Hauptsache. Wenn beispielsweise HQueue, ein Standard-Houdini-Dispatcher, als Standard verwendet wird, besteht der Ablauf darin, den Rendering-Job nach Abschluss der Simulation aller Frames an einen anderen Client zu übergeben. Wenn Sie jedoch Python verwenden, ** 1-Frame-Simulation Wenn Sie fertig sind, können Sie ** den Rendering-Job an einen anderen Client übergeben. Da Sie eine Python-Skriptdatei mit der Option -P des Mantra-Befehls angeben können, können Sie auch die ** IFD-Rendering-Eigenschaften ** (z. B. Subpixel) überschreiben, die Sie bereits exportiert und gerendert haben, also Subpixel. Sie können sich die Mühe sparen, das IFD erneut zu ändern und auszugeben. : zwinker: Sie können Python auch verwenden, um die ** Objekttransformationsinformationen ** in der Alembic-Datei zu lesen, wenn sie gelesen werden. HQueue selbst ist kostenlos, sucht jedoch nach Houdini Indie-Lizenzen oder höheren Lizenzen (ich erhalte keine Lizenz), und der IFD-Export ist nur mit der kommerziellen Version von Houdini / Engine möglich. Daher sind dies nützliche Informationen für Apprentice- und Indie-Benutzer ** Python Ich möchte vorstellen, wie Sie Informationen über Alembic ** erhalten. : entspannt:

Houdinis Python bietet ein Modul namens ** _alembic_hom_extensions **. Wenn Sie Houdini mit Python steuern, beginnen Sie normalerweise mit dem Modul ** hou **, aber diese ** _alembic_hom_extensions ** ist unabhängig vom Modul ** hou **. Mit anderen Worten, wenn Sie nur dieses Modul verwenden, ist keine Lizenz erforderlich. Aber es macht nicht viel Sinn, da Sie die meisten Alembic-Informationen zur Verarbeitung an Houdini weitergeben: schreien_katze: Mit diesem Modul können Sie hauptsächlich die Objekthierarchie, die Objekttransformation und die Sichtbarkeit der angegebenen Almembic-Datei abrufen. Sie können auch den Wert der Benutzereigenschaft des Objekts (im Fall von Alembic von Houdini die zusätzlich für das Kameraobjekt festgelegte Auflösung) und den Zeitbereich der Objektanimation abrufen. Die Funktionen dieses Moduls sind: Lesen Sie durch: zzz: Fahren wir mit der nächsten Erklärung fort.


python


alembicArbGeometry(abcPath, objectPath, name, sampleTime) → (value, isConstant, scope)

Gibt ein Taple von None oder (value, isConstant, scope) zurück. Der Inhalt dieses Taples ist der Wert des Attributs, der Boolesche Wert, der angibt, ob das Attribut auf der Zeitachse konstant ist, und der Bereich ("Variieren", "Scheitelpunkt", "Variieren", "Uniform", "Konstante", "Unbekannt"). ') ist. </ sup>

python


alembicClearArchiveCache()

Leert den internen Cache der Alembic-Datei. </ sup>

python


alembicGetArchiveMaxCacheSize()

Gibt die Größe des Alembic-Dateicaches zurück. </ sup>

python


alembicGetCameraDict(abcPath, objectPath, sampleTime)

Gibt ein Wörterbuch mit Kameraparametern für das angegebene Objekt zurück. </ sup>

python


alembicGetCameraResolution(abcPath, objectPath, sampleTime)

Gibt einen Taple zurück, der None oder zwei Floats enthält. Der erste Wert ist die X-Auflösung der Houdini-Kamera. Der zweite Wert ist die Y-Auflösung der Houdini-Kamera. Einige Kameras (z. B. Maya-Kamera) haben keine Auflösung, daher wird in diesem Fall keine zurückgegeben. </ sup>

python


alembicGetObjectPathListForMenu(abcPath)

Gibt ein Tupel von Zeichenfolgen in dem Format zurück, das für Menürückrufe erforderlich ist. </ sup>

python


alembicGetSceneHierarchy(abcPath, objectPath) → (object_name, object_type, (children))

Gibt 3 Taples zurück. Jeder Taple hat die folgende Struktur: (object_name, object_type, (children)) (Kinder) ist ein Taple, das untergeordnete Knoten enthält. object_type enthält einen der folgenden Typen (kann auch andere Typen enthalten): --cxform konstanter Transformationsknoten --xform Animation Transform Node

python


alembicHasUserProperties(abcPath, objectPath)

Gibt None zurück, wenn das -Objekt keine Benutzereigenschaften hat. Wenn ja, wird zurückgegeben, ob die Benutzereigenschaft über die Zeit konstant ist. </ sup>

python


alembicSetArchiveMaxCacheSize(size)

Legt die maximale Anzahl von Alembic-Dateien fest, die gleichzeitig zwischengespeichert werden. </ sup>

python


alembicTimeRange(abcPath, [objectPath=None]) → (start_time, end_time)

Gibt ein Taple von None oder (start_time, end_time) zurück. Dieser Taple enthält die globale Start- / Endzeit des Archivs gemäß den FPS-Informationen im Alembic-Archiv. Wenn Sie objectPath angeben, wird die Start- / Endzeit dieses Objekts berechnet. Gibt None zurück, wenn das Archiv konstant ist. </ sup>

python


alembicUserProperty(abcPath, objectPath, name, sampleTime) → (value, isConstant)

Gibt ein Taple von None oder (value, isConstant) zurück. Dieses Taple enthält den Wert des Attributs und einen Booleschen Wert, der angibt, ob das Attribut über die Zeit konstant ist. </ sup>

python


alembicUserPropertyMetadata(abcPath, objectPath, sampleTime)

Gibt None oder JSON Dictionary zurück. Dieses JSON-Wörterbuch enthält eine Zuordnung von Benutzereigenschaftsnamen-> Benutzereigenschaftsmetadaten. </ sup>

python


alembicUserPropertyDictionary(abcPath, objectPath, sampleTime)

Gibt None oder JSON Dictionary zurück. Dieses JSON-Wörterbuch enthält eine Zuordnung von Benutzereigenschaftsnamen-> Benutzereigenschaftswerten. </ sup>

python


alembicUserPropertyValuesAndMetadata(abcPath, objectPath, sampleTime)

Gibt None oder Taple zurück. Dieser Taple enthält zwei JSON-Wörterbücher. Das erste Wörterbuch enthält eine Karte mit Benutzereigenschaften und -werten. Das zweite Wörterbuch enthält eine Karte der Benutzereigenschaften und die Metadaten, die zur Interpretation des ersten Wörterbuchs verwendet werden. </ sup>

python


alembicVisibility(abcPath, objectPath, sampleTime, [check_ancestor=False]) → (value, isConstant)

Gibt ein Taple von None oder (value, isConstant) zurück. Dieses Taple enthält die Sichtbarkeit des Objekts und einen Booleschen Wert, der angibt, ob die Sichtbarkeit über die Zeit konstant ist. Der Sichtbarkeitsrückgabewert 0 bedeutet versteckt, 1 bedeutet sichtbar und -1 bedeutet verzögert (abhängig von der Sichtbarkeit der Eltern). </ sup>

python


getLocalXform(abcPath, objectPath, sampleTime) → (xform, isConstant, inherit)

Gibt einen Tipp von zurück (xform, isConstant, erbt). Dieses Tapple ist eine lokale Transformation, ein Boolescher Wert, der angibt, ob die Transformation über die Zeit konstant ist, und ein Boolescher Wert, der angibt, ob der Knoten die übergeordnete Transformation erbt (oder mit dieser verbunden ist). Beinhaltet. </ sup>

python


getWorldXform(abcPath, objectPath, sampleTime) → (xform, isConstant, inherit)

Gibt ein Tupel von (xform, isConstant, erbt) zurück. Dieses Tapple ist eine Welttransformation, ein Boolescher Wert, der angibt, ob die Transformation über die Zeit konstant ist, und ein Boolescher Wert, der angibt, ob der Knoten die übergeordnete Transformation erbt (oder mit dieser verbunden ist). Beinhaltet. </ sup>


Wir verwenden nicht alle oben genannten Funktionen, daher konzentrieren wir uns nur auf diejenigen, die von Interesse sind.

python


alembicGetSceneHierarchy(abcPath, objectPath)

python


alembicTimeRange(abcPath, [objectPath=None])

python


getWorldXform(abcPath, objectPath, sampleTime)

Es hat erheblich abgenommen. Mal sehen, was wir mit diesen drei Funktionen machen können. Scene.gif NetworkEditor.png Ich habe cam1, Toy, Subnet (Pig, ShaderBall in diesem) erstellt. Anders als bei ShaderBall wird die Animation auf Objektebene festgelegt. Geben Sie diese ganze Szene in Alembic aus und laden Sie sie in eine neue Szene. NetworkEditorAlembic.png Die Daten werden in derselben Objekthierarchie wie Houdini erfasst und auch animiert. Wenn ich jedoch das zu animierende Objekt cam1 auswähle, zeigt der Animationseditor keine Animationskurven an. Wenn Sie mit CHOP vertraut sind, können Sie mit Object CHOP die in Motion FX View abgetastete Animationskurve anzeigen, oder? Ich denke du kannst denken. Wenn die ursprünglichen Alembic-Animationsdaten gebacken und linear interpoliert werden, ist das in Ordnung. Wenn dies nicht der Fall ist, möchten Sie auch die Gleitkomma-Frame-Werte erhalten. Sie möchten also die Animationskurve erhalten, oder? Hier kommt das Modul ** _alembic_hom_extensions ** ins Spiel. Als rauer Fluss,

Sie können verschiedene Pipelines mit entwickeln.

So erhalten Sie die Objekthierarchie und den Animationstyp von Alembic

Der Code ist unten.

python


import _alembic_hom_extensions as abc

abcPath = "C:/data/alembicFile.abc"

def expandChild(root,child,objectHierarchy,objectType):
    objectHierarchy.append(root+child[0])
    objectType.append(child[1])
    if len(child[2])==0:
        return
    else:
        return expandChild(root+child[0]+"/",child[2][0],objectHierarchy,objectType)

objectHierarchy=[]
objectType=[]    
childNodes = abc.alembicGetSceneHierarchy(abcPath, "/")[2]
for eachChildNode in childNodes:
    expandChild("/",eachChildNode,objectHierarchy,objectType)
print objectHierarchy
print objectType

python


#Ausgabeergebnis
['/Toy', '/Toy/testgeometry_rubbertoy1', '/cam1', '/cam1/cameraProperties', '/Subnet', '/Subnet/Pig', '/Subnet/Pig/testgeometry_pighead1', '/Subnet/Pig/testgeometry_pighead1/PigFace']
['xform', 'polymesh', 'xform', 'camera', 'cxform', 'xform', 'polymesh', 'faceset']

Sie können sehen, dass xform Animationsinformationen für dieses Objekt enthält und cxform keine Animationsinformationen enthält.

So erhalten Sie den Animationsbereich

Lassen Sie uns nun den Animationsbereich von cam1 untersuchen.

python


import _alembic_hom_extensions as abc

abcPath = "C:/data/alembicFile.abc"
objectPath = "/cam1"
print abc.alembicTimeRange(abcPath, objectPath)

python


#Ausgabeergebnis
(0.041666666666666664, 2.0)

Die Einheit des von dieser Funktion ausgegebenen Animationsbereichs ist Sekunden. Da diese Kamera Animationsbereiche von 1 Bild bis 48 Bildern mit FPS = 24 erfasst Das Ergebnis von (1.0 / 24.0, 48.0 / 24.0) wird angezeigt.

So erhalten Sie Kamerabewegungs-, Rotations- und Skalierungswerte im aktuellen Bild

Lassen Sie uns nun die Transformation des Objekts untersuchen.

python


import _alembic_hom_extensions as abc

abcPath = "C:/data/alembicFile.abc"

objectPath = "/cam1"

sampleTime = hou.frame()/hou.fps()

#Das erste Element des von getWorldXform zurückgegebenen Taples sind 16 Float-Tapples
xform = abc.getWorldXform(abcPath, objectPath, sampleTime)[0]
#Sie müssen in das Matrixformat konvertieren.Verwenden Sie Matrix4
xformMatrix = hou.Matrix4(xform)
#Extrahieren bewegen, drehen, skalieren
explodedDictionary = xformMatrix.explode()
print "translate:",explodedDictionary["translate"]
print "rotate",explodedDictionary["rotate"]
print "scale",explodedDictionary["scale"]

python


#Ausgabeergebnis
translate: [5.75595, 3.34021, 10.2852]
rotate [-11.6801, 28.4249, -1.25354e-06]
scale [1, 1, 1]
```

 Sie können es im obigen Einzelskript verwenden, aber ** Houdini-Ausdrücke können sowohl Python als auch HScript ** verwenden.
 Fügen Sie als Nächstes dem von Alembic importierten Kameraknoten einen Benutzerparameter (in Houdini als Ersatzparameter bezeichnet) wie folgt hinzu.
 Hier habe ich zwei Float Vector3 hinzugefügt und den Parameter Translate und Rotate vorbereitet.
 Ändern Sie dann den Ausdruckstyp in Python.
 ![UserParms.png](https://qiita-image-store.s3.amazonaws.com/0/154191/3c170758-182d-f349-6414-f89ccfb60957.png)
 Im Alembic Xform-Knoten sind die Parameter Dateiname, Objektpfad, Rahmen und Rahmen bereits vorbereitet. Daher möchte ich die Werte dieser Parameter verwenden, um Informationen über die Bewegung und Drehung der Kamera zu erhalten.
 Sie können mehrere Zeilen Python-Code über das Dialogfeld "Ausdruck bearbeiten" eingeben, das durch Drücken von Alt + E für die Parameter angezeigt wird. Es ist jedoch schwierig, häufig verwendeten Code einzeln einzugeben.
 Es ist bequem, häufig verwendeten Code als benutzerdefinierte Funktion zu registrieren.
 Eine Möglichkeit, eine benutzerdefinierte Funktion zu registrieren, besteht darin, eine Python-Datei in einem bestimmten Verzeichnis abzulegen und in den Pfad einzufügen. Dies würde jedoch zu einer umgebungsabhängigen Szenendatei führen.
 Ich möchte es vermeiden!
 Definieren wir also eine benutzerdefinierte Funktion in der Szenendatei.

#### So registrieren Sie eine benutzerdefinierte Funktion in einer Szenendatei
 Benutzerdefinierte Funktionen können mit dem Python Source Editor im Windows-Menü registriert werden.
 ![PythonSourceEditor.png](https://qiita-image-store.s3.amazonaws.com/0/154191/6022a0b5-fa4d-97ad-e550-6a4fe3141500.png)
 Geben Sie dann den Code wie unten gezeigt ein.
 ![PythonSourceEditorCode.png](https://qiita-image-store.s3.amazonaws.com/0/154191/6285343b-318f-656a-d176-36201529f123.png)
 Dieser Code ist eine Funktion, die mit Parametern auf dem Alembic Xform-Knoten arbeitet und die Transformationsinformationen für diesen Knoten zurückgibt.


#### **`python`**
```python

#Modus ist"translate"Dann Standortinformationen,"rotate"Dann Rotationsinformationen,"scale"Gibt Skaleninformationen zurück
#Wenn der Index 0 ist, ist es eine X-Komponente, wenn es 1 ist, ist es eine Y-Komponente, und wenn es 2 ist, ist es eine Z-Komponente.
def getAlembicTransform(mode="translate",index=0):
    import _alembic_hom_extensions as abc
    currentNode = hou.pwd()
    abcPath = currentNode.parm('fileName').eval()
    objectPath = currentNode.parm('objectPath').eval()
    sampleTime = currentNode.parm('frame').eval()/currentNode.parm('fps').eval()
    xform = abc.getWorldXform(abcPath, objectPath, sampleTime)[0]
    xformMatrix = hou.Matrix4(xform)
    explodedDictionary = xformMatrix.explode()

    return explodedDictionary[mode][index]
```
 Nach dem Registrieren des Codes im Python Source Editor-Fenster
 Sie können die benutzerdefinierte Funktion "getAlembicTransform" wie folgt aufrufen:
 ![ParameterExpression.png](https://qiita-image-store.s3.amazonaws.com/0/154191/380f944f-fa7b-6f00-98e3-c6ffd7d9344a.png)
 Klicken Sie mit der linken Maustaste auf den Parameternamen, um festzustellen, ob der Wert korrekt ist.
 ![ParameterExpressionEval.png](https://qiita-image-store.s3.amazonaws.com/0/154191/c8e5cc41-04e2-4412-55ac-3d802a64680b.png)

 Jetzt können Sie die Animationskurve des Alembic-Objekts im Animationseditor sehen.
 ![AnimationCurve.png](https://qiita-image-store.s3.amazonaws.com/0/154191/e4697ace-c750-d3b1-7f2a-64ff75d139f7.png)


 Sie haben jetzt die Transformationsinformationen von Alembic in die Parameterwerte aufgenommen.

 Das ist es. : umarmen:


Recommended Posts

Holen Sie sich Alembic-Informationen mit Python
Abrufen von Eigenschaftsinformationen durch Scraping mit Python
Holen Sie sich ein Date mit Python
[Python] Python-Paketinformationen mit der PyPI-API abrufen
Holen Sie sich CPU-Informationen von Raspberry Pi mit Python
Python-Skript zum Abrufen von Notizinformationen mit REAPER
Holen Sie sich den Ländercode mit Python
Holen Sie sich Twitter-Timeline mit Python
Holen Sie sich Youtube-Daten mit Python
Informationen erhalten Sie mit zabbix api
Holen Sie sich die Thread-ID mit Python
Beginnen Sie mit Python! ~ ② Grammatik ~
Holen Sie sich das Home-Verzeichnis mit Python
Holen Sie sich Tastaturereignis mit Python
[Python] Mit der API von Qiita erhalten Sie Benutzer- und Artikelinformationen
Holen Sie sich Informationen zu Videodateien mit ffmpeg-python
Beginnen Sie mit Python! ~ ① Umweltbau ~
Holen Sie sich Bewertungen mit Python Googlemap API
Holen Sie sich das Wetter mit Python-Anfragen
Holen Sie sich Web-Screen-Capture mit Python
Holen Sie sich das Wetter mit Python-Anfragen 2
[Python] Mit DataReader Wirtschaftsdaten abrufen
Erste Schritte mit Python
[Kleine Geschichte] Holen Sie sich mit Python einen Zeitstempel
Holen Sie sich Qiita-Trends mit Python-Scraping
[Python x Zapier] Erhalten Sie Warninformationen und benachrichtigen Sie mit Slack
Probieren Sie Juniper JUNOS PyEz (Python-Bibliothek) aus. Hinweis 2 ~ Informationen mit PyEz ~ abrufen ~
Holen Sie sich mit Python zusätzliche Daten zu LDAP
Holen Sie sich HTML von Element mit Python-Selen
[Hinweis] Mit Python Daten von PostgreSQL abrufen
Statistik mit Python
Python mit Go
[Python] Ruft den Variablennamen mit str ab
Twilio mit Python
Kartenmietinformationen auf einer Karte mit Python
In Python integrieren
Spielen Sie mit 2016-Python
AES256 mit Python
Getestet mit Python
Python beginnt mit ()
mit Syntax (Python)
Beginnen wir mit TopCoder in Python (Version 2020)
Bingo mit Python
Zundokokiyoshi mit Python
Kommen wir zu Python # 0 (Umgebungskonstruktion)
Erhalten Sie Informationen zur virtuellen Währung mit der API coin
Excel mit Python
Mikrocomputer mit Python
[Blender x Python] Beginnen wir mit Blender Python !!
PhytoMine-I hat versucht, mit Python die genetischen Informationen der Pflanze zu erhalten
Mit Python besetzen
[Yahoo! Weather Replacement Version] So erhalten Sie Wetterinformationen mit LINE Notify + Python
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Sammeln von Informationen von Twitter mit Python (Umgebungskonstruktion)
Python-Handspiel (Beginnen wir mit AtCoder?)
Holen Sie sich die neuesten AMI-Informationen mit der AWS CLI
Holen Sie sich ein Ticket für einen Themenpark mit Python
Ich habe versucht, CloudWatch-Daten mit Python abzurufen
Holen Sie sich den Git-Zweignamen und den Tag-Namen mit Python