Spezifikationen zum Pfadformat
Auf dieser Seite wird das Pfadeformat beschrieben. Dort finden Sie Anleitungen zum Bearbeiten der Daten in diesem Format mithilfe der Funktionen, die in den Pfadewerkzeugen enthalten sind.
Formatspezifikationen
*uv\_pos* soll eine 2D-Adresse (z. B. $pos) eines Pixels des oberen Teils sein.
Im restlichen Dokument:
- top[uv_pos].XYZW bezieht sich auf die 4 schwebenden Elemente, die im Pixel des oberen Teils gespeichert sind.
top[uv_pos] == sample_color(paths, uv_pos) - bottom[uv_pos].XYZW bezieht sich auf die 4 schwebenden Elemente, die im entsprechenden Pixel des unteren Teils gespeichert sind.
bottom[uv_pos] == sample_color(paths, uv_pos + Float2(0, 0.5))
top[uv_pos] und bottom[uv_pos] bilden zusammen eine semantische Einheit U[uv_pos] des Dokuments, die aus 8 Gleitkommas besteht.
Dokumentkopfzeile
Jedes Pfade-Dokument beginnt mit einer Dokumentkopfzeile. Es ist die erste semantische Einheit U[(0,0)]:
Die Anzahl der Pfade (sollte eine positive ganze Zahl in [0; 16777216]).
Wenn einige Pfade leer sind, zählen sie hier trotzdem. Man kann sich das als “Anzahl der zu decodierenden Pfade” vorstellen.
YZ
Die Pixelgröße für dieses Dokument (also genau Float2(1,1) / $size).
Dies ist nützlich, wenn Sie die Pfade beispielsweise von einem Pixelprozessor oder einer Fx-Map lesen, deren Ausgabegröße unterschiedlich ist.
W
1/16 = 0,0625 (Header-Flag)
Die Adresse des letzten in diesem Dokument definierten Scheitelpunkts. Dies ist nützlich, um neue Daten anzufügen.
Es kann also tatsächlich eine beliebige Adresse sein, die größer ist (in Scannline-Reihenfolge) als die Adresse des letzten Scheitelpunkts. Es muss im Bereich ]0, 1[×]0,.5[ liegen
ZW
Nicht verwendet, Fließkommazahl2(0, 1)
Path Headers
Auf die Dokumentkopfzeile folgt unmittelbar die Pfadanzahl = top[(0,0)].X Pfadkopfzeilen, eine nach semantischen Einheiten.
E.g. Wenn das Dokument 3 Pfade enthält, werden sie in U[(0,1)*pixel_size], U[(0,2)*pixel_size] und U[(0,3)*pixel_size] (mit pixel_size = top[(0,0)].YZ) gespeichert.
Wenn es mehr Pfade gibt, als eine Zeile Pixel enthalten kann, werden die restlichen Pfad-Header in die nächste Zeile(n) geschrieben, und zwar in der eingescannten Reihenfolge.
Es darf keine Pfad-Header (top[...].XYZW = Float4(0,0,0,0)) enthalten. Ein solcher Pfad könnte immer noch einen leeren Pfad enthalten.
Der Pfad-Header des N-ten Pfads wird an der Adresse path\_addr definiert und wird wie folgt definiert:
Anzahl der Scheitelpunkt in diesem Pfad. Muss im Bereich [0, 16777216] liegen.
Wenn sich der Anfangs- und der Endpunkt eines geschlossenen Scheitelpunkts an derselben Position befinden, werden sie immer noch für 2 Scheitelpunkt gezählt.
Ein Pfad mit 0 Scheitelpunkten ist ohnehin ein gültiger Pfad.
J
Is_closed Flag: 1, wenn der Pfad geschlossen ist (z. B. ein Kreis), andernfalls 0 (z. B. eine gerade Linie).
Z
Der Pfadindex N. Es muss absolut mit path_addr übereinstimmen (siehe Hinweis unten).
W
Das Flag header: 1/16 = 0,0625.
Startadresse (oder erste Adresse) des Scheitelpunkts.
ZW
Adresse des letzten (oder letzten) Scheitelpunkts.
path\_addr aus N mithilfe der Funktion Utils/pixel\_index\_to\_position in den Pfaden_tools.sbs berechnen: 2path\_addr = pixel\_index\_to\_position(N+1)Informationen zu Scheitelpunkten
Scheitelpunkt können an beliebiger Stelle im Bild nach den Kopfzeilen (Dokument- oder Pfadkopfzeilen) gefunden werden. Scheitelpunkt können verschiedene “Typen” haben (Start, Mid oder End) und sie werden explizit mit 2 Adresszeigern (“Links”) miteinander verknüpft.
Start- und End-Scheitelpunkt sind in dieser Hinsicht besonders: Um die Darstellung von geschlossenen Pfaden oder eines beliebigen Netzwerks von miteinander verknüpften Pfaden zu ermöglichen, wird einer der Links tatsächlich verwendet, um eine kreisförmige, vorwärts verknüpfte Liste aller anderen Start- oder End-Scheitelpunkte zu bilden, die denselben Scheitelpunkt darstellen. Solche Scheitelpunkte, die zueinander passen, werden als “Geschwister” bezeichnet. [Illustration begrüßt]
Formal ist jeder Scheitelpunkt an der Adresse “*vert\_addr*” folgendermaßen definiert:
Die Position des Scheitelpunkts. Koordinaten können beliebige Gleitkommawerte sein, die nicht NaN oder ±inf sind. Es gibt keine Vorstellung von Kachelung auf dieser Ebene (sie kann durch die Implementierung jedes Filters gehandhabt werden oder nicht), also sollen Pfade auf der euklidischen Ebene definiert werden.
Z
Der Pfadindex des Scheitelpunkts. Ein Scheitelpunkt kann nur zu einem Pfad gehören. (Wie bereits erwähnt, können die Scheitelpunkte “Anfang” und “Ende” jedoch gleichrangige Elemente enthalten.) Der Pfadindex kann verwendet werden, um den Pfad-Header abzurufen (siehe Abschnitt Path Headers oben). Stellen Sie daher sicher, dass er synchron bleibt.
W
Scheitelpunkt. Es wird zwischen dem Vorzeichen des Werts und seinem absolute Wert aufgeteilt:
Auf der Vorzeichenseite würde ein Wert von 0 bedeuten, dass es hier keinen Scheitelpunkt gibt (alle anderen Komponenten sollten ebenfalls 0 sein). Ein negativer Wert bedeutet, dass der Scheitelpunkt als “Ecke” gekennzeichnet ist. eine positive, dass der Scheitelpunkt “glatt” ist. Der Scheitelpunkt “Ecken” vs. “Glätten” ist ein reines, isoliertes Attribut, das keine Auswirkungen oder Auswirkungen auf den Rest der Pfade-Codierung hat.
Auf dem absolute Wert-Teil sind die Pixelart (Anfang, Mitte oder Ende) und ein weiteres Flag (trivial_link) kodiert:
-
0.125: End-Scheitelpunkt (letzter Scheitelpunkt der Form; immer nicht triviale Links, siehe unten)
-
0.25: Start-Scheitelpunkt (der erste Scheitelpunkt der Form; immer nicht triviale Links, siehe unten)
-
0.5: Mittlerer Scheitelpunkt mit nicht trivialen Links
-
1: Mittlerer Scheitelpunkt mit trivialen Links
“Triviale Links” bezieht sich darauf, dass der vorherige und der nächste Scheitelpunkt (in der Liste der Scheitelpunkt des aktuellen Pfads) in dem Pixel links (vert_addr-(0,pixel_size)) bzw. rechts (vert_addr+(0,pixel_size)) gespeichert sind, während “nicht triviale Links” bedeutet, dass mindestens einer dieser Links an einer anderen Stelle gespeichert ist.
Unabhängig von der “Trivialität” der Links werden vertrauenswürdige Werte der Links im unteren Teil gespeichert:
XY
Die Adresse des vorherigen Scheitelpunkts dieses Pfads. Bei Start-Scheitelpunkten zeigt dies auf den nächsten gleichgeordneten Scheitelpunkt.
wenn |top[vert_addr].W| = 1, dann bottom[vert_addr].XY = vert_addr - (0,pixel_size)
ZW
Die Adresse des nächsten Scheitelpunkts dieses Pfades. Bei End-Scheitelpunkten zeigt dies auf den nächsten gleichgeordneten Scheitelpunkt.
wenn |top[vert_addr].W| = 1, dann bottom[vert_addr].ZW = vert_addr + (0,pixel_size)
Informationen zu Pfaden lesen und schreiben
Wenn Sie eigene Knoten zur Pfadverarbeitung erstellen möchten, stehen Ihnen verschiedene Tools zur Verfügung.
Die Grundlagen werden von den Scheitelpunkt Paths Processor und Paths Scheitelpunkt Processor Simple bereitgestellt, die im Grunde wie ein Pixelprozessor verwendet werden können.
Wenn Sie Features benötigen, die über die Möglichkeiten der Knoten des Pfade-Scheitelpunkts hinausgehen (mehr Eingabetexturen oder mehr vorherige oder nächste Scheitelpunkte), kann das Kopieren der Implementierung dieses Diagramms ein guter Ausgangspunkt sein (vorausgesetzt, Sie ersetzen den Knoten Get(“%perVertex”) durch Ihre benutzerdefinierte Verarbeitung).
Aber für den Fall, dass Sie etwas Außerirdischeres tun möchten, als eine Pro-Vertex-Funktion anzuwenden, gibt es hier eine detaillierte Erklärung der Werkzeuge, die Sie verwenden können. Dies sind normalerweise kleine Hilfsfunktionen, die im selben Paket wie die anderen Pfade-Knoten (Pfade_tools.sbs) gefunden werden können. (Diese Funktionen werden nicht im Bibliotheks und Knotenmenü verfügbar gemacht.)
Lesen-Funktionen
Unter dem Ordner “Read” finden Sie mehrere dieser Optionen, die hilfreich sind, um Informationen über die Pfade zu sammeln:
Einige können Ihnen Informationen zu einem bestimmten Pixel geben. Sie alle nehmen den abgetasteten Float4-Wert im *top* Teil als Eingabe. Wenn man sich ihre Implementierung ansieht, sind sie supereinfach. Es geht darum, mehr Bedeutung zu vermitteln als nur Atomknoten:
is\_header handelt und dass current\_pixel\_is\_document\_header “false” zurückgegeben hat.is\_vertex nicht zuerst überprüfen).is\_vertex nicht zuerst überprüfen).is\_vertex nicht zuerst überprüfen).is\_start\_vertex || is\_mid\_vertex. Nützlicher für die Fx-Map-basierte Verarbeitung, um jedes Segment maximal einmal zu verarbeiten.is\_vertex zu überprüfen: wenn die Antwort wahr ist, sind Sie auf einem Scheitelpunkt (sicher). Bitte erinnern Sie daran, dass dieses Flag noch nicht von offiziellen Knoten unterstützt wird.Wenn das ein Scheitelpunkt ist, sagt aus, ob Sie die Position des vorherigen und nächsten Scheitelpunkts leicht ableiten können, ohne den unteren Teil zu testen. (Hinweis: Ein Nicht-Scheitelpunkt gibt immer “false” zurück.)
Wahrscheinlich möchten Sie dies nicht direkt verwenden, sondern eine der sample\_next\*- oder sample\_prev\*-Funktionen verwenden, die sich darum kümmern.
Gibt den nächsten (bzw. vorherigen) Scheitelpunkt-Top-Part-Sampling-Wert für den obersten Teil des Sampling-Werts *sampled* und dessen Position *sampled\_position* zurück und setzt eine Fließkommazahl2-Variable *next\_sampled\_pos* auf die Position (im obersten Teil) dieses Nachbarn (d. h. <Rückgabewert> = SampleColor(next_sampling_pos, image0). *input0PixSize* muss der Pixelgröße des Pfades entsprechen (top[(0,0)].YZ).
Wenn das aktuelle Pixel (*sampled*) ein Start-Scheitelpunkt ist, gibt sample_prev das nächste gleichgeordnete Element dieses Scheitelpunkts zurück. entsprechend, wenn es sich um einen End-Scheitelpunkt handelt, gibt sample_next das nächste gleichgeordnete Element dieses Scheitelpunkts zurück (d. h. vielleicht nicht das, was Sie möchten). Siehe *sample\_next\_advanced* und *sample\_prev\_advanced* unten, um dieses Problem zu lösen.
Bitte beachten Sie, dass aus Gründen der Einfachheit davon ausgegangen wird, dass Pfade-Informationen in input0! gespeichert sind. Außerdem müssen Sie im Gegensatz zu den Dokumentstatus der Funktion *next\_sampled\_pos* nicht vorab deklarieren. *[out]next\_sampled\_pos* ist ein Dummy-Parameter, der Sie daran erinnert, dass dieser zweite “Rückgabewert” vorhanden ist.
Sie können *paths\_trace* Fx-Map im Parameter “Iterationen” des dritten Iterateknotens nach einem Beispiel für dessen Verwendung durchsuchen.
Write-Funktionen
Im Ordner “Write” finden Sie kleine Helfer, die eine Fließkommazahl4 erstellen, die von einer Fx-Map geschrieben werden kann.
Tatsächlich multipliziert die Fx-Map RGB vor dem Zeichnen mit Alpha, sodass die tatsächlichen Werte nicht vormultipliziert werden, um dies zu kompensieren. Wenn Sie diese Funktion z. B. in einem Pixelprozessor verwenden möchten, empfehlen wir Ihnen, die Vormultiplikation erneut anzuwenden oder eine benutzerdefinierte Version zu schreiben (besser für Ihren Anwendungsfall optimiert und einfacher zu verwenden).
*nbVertices*”, dem Flag “*isClosed*” und dem Flag “*pathIndex*”.Erstellt den oberen Teil eines Scheitelpunkts und legt die Position, den Typ und andere Optionen entsprechend fest.
Über mid_vertex und den hasTrivialLinks-Parameter: Idealerweise sollten Sie den entsprechenden Wert festlegen, aber wenn Sie aus irgendeinem Grund nicht sagen können, ob Links trivial sind oder nicht, können Sie ihn sicher auf “false” setzen (auf Kosten einer langsameren Verarbeitung des generierten Pfads).
Es gibt keinen Bottom-Part-Generator für Pfadkopfzeilen oder Scheitelpunkte: Beide codieren zwei Verknüpfungen zum oberen Teil, sodass diese Funktion im Wesentlichen ein Vector Float4-Konstruktor aus zwei Float2 wäre. Vergessen Sie nicht, XYZ durch W zu teilen, wenn Sie unter Verwendung einer Fx-Map schreiben (W ist das Y einer Adresse, es sollte nie Null sein).
Ein entsprechendes Beispiel für die Verwendung dieser Funktionen finden Sie im Paket Pfade_polygon.sbs mit dem Knoten Pfade Polygon.
Verfahren zum Verarbeiten von Pfaden
Sie werden wahrscheinlich entweder einen Pixelprozessor oder eine Fx-Map verwenden, um Ihre benutzerdefinierte Verarbeitung zu implementieren, von denen jede ihre Stärken und Schwächen hat:
Die Fx-Map-basierte Lösung wird in der Regel bevorzugt, wenn ein Vorgang auf hoher Ebene durchgeführt wird, der eine globale Kenntnis des gesamten Pfades (oder Pfade) oder eines kumulativen Pfades erfordert (z. B. Umpacken von Scheitelpunkten nach Dezimierung oder Tesselierung). Es ist auch der einfachste Ansatz. Wenn Sie also zum ersten Mal eine benutzerdefinierte Verarbeitung durchführen, sollten Sie möglicherweise eine Fx-Map verwenden, obwohl möglicherweise langsamer ist.
Sie müssen sich zunächst mit Fx-Map auskennen. Wenn dies nicht der Fall ist, überprüfen Sie die spezifische Dokumentation.
Es wird empfohlen, sich die Implementierung von Preview Paths in Pfaden_trace.sbs und Pfade Polygon in Pfaden_polygon.sbs anzusehen, um eine Vorstellung davon zu erhalten, wie ein Pfad mit einer Fx-Map gelesen bzw. geschrieben werden kann.
Die Lösung für den Pixelprozessor passt, wenn Sie nur “lokale” Informationen benötigen. Hier meinen wir “lokal” nicht räumlich (der Abstand zwischen Elementen), sondern topologisch (miteinander verbundene Eckpunkte). So wird der Vertex-Prozessor implementiert. Der Pixelprozessor ist bei dieser Art von Operation in der Regel schneller als die Fx-Map, da die Funktion jedes Pixels parallel ausgewertet wird, während nur eine begrenzte Datenmenge abgerufen wird. Der Implementierungsaufwand könnte jedoch weitaus wichtiger sein, da Sie nur das aktuelle Pixel ändern können.
Wir werden nicht ins Detail gehen, da es je nach Anwendungsfall so viel zu sagen gibt, aber als Erstes müssen wir überprüfen, wo Sie sich befinden:
Sind Sie im oberen ($pos.y < 0,5) oder unteren ($pos.y > 0,5) Teil? Wir empfehlen, sich daran zu erinnern, dass in einer dedizierten Variablen (z. *isTop*), und dass Sie einen *vert.addr*-Float2 erstellen, ist dieser Wert *$pos* für den oberen Teil und $pos - (0,0.5) für den unteren Teil.
Was befindet sich unter vert.addr? Nehmen Sie es auf und prüfen Sie, ob etwas vorhanden ist (W != 0), wenn es etwas gibt, was genau. Ein Header (W = 0,0625) (mit *Read/is\_header* prüfen) oder ein Scheitelpunkt (mit Read/is\_vertex prüfen)? Und wenn es eine Kopfzeile ist, ist es die Dokumentkopfzeile oder eine Pfadkopfzeile? (Sie können *Read/current\_pixel\_is\_document\_header* verwenden, um dies zu überprüfen.) Verwenden Sie eine oder mehrere der Hilfsfunktionen, um das für Sie interessante zu finden.