Specifiche formato tracciati
Questa pagina descrive il formato Tracciati e fornisce indicazioni per la modifica dei dati in tale formato utilizzando le funzioni incluse negli strumenti Tracciati.
Specifiche del formato
Sia *uv\_pos* un indirizzo 2D (ad esempio $pos) di un pixel della parte ‘superiore’.
Nel resto del documento:
- top[uv_pos].XYZW farà riferimento ai 4 float memorizzati nel pixel della parte superiore.
top[uv_pos] == esempio_color(percorsi, uv_pos) - bottom[uv_pos].XYZW farà riferimento ai 4 float memorizzati nel pixel corrispondente della parte inferiore.
bottom[uv_pos] == esempio_color(paths, uv_pos + Virgola mobile 2(0, 0.5))
top[uv_pos] e bottom[uv_pos] insieme formano un’unità semantica U[uv_pos] del documento, composta da 8 float.
Intestazione documento
Ogni documento Tracciati inizia con un’intestazione di documento. Si tratta della prima unità semantica U[(0,0)]:
Numero di percorsi (deve essere un numero intero positivo in [0; 16777216]).
Se alcuni tracciati sono vuoti, vengono comunque contati qui. Quindi puoi immaginarlo come un “numero di intestazioni di tracciati da decodificare”.
YZ
Dimensione in pixel per il documento (ovvero, esattamente Float2(1,1) / $size).
Ciò è utile quando si leggono i percorsi da un processore pixel o da una mappa-FX, ad esempio, le cui dimensioni di output sono diverse.
L
1/16 = 0,0625 (flag di intestazione)
L’indirizzo dell’ultimo vertice definito in questo documento. Questo è utile per aggiungere nuovi dati.
Può quindi essere qualsiasi indirizzo maggiore (in ordine di scansione) dell’indirizzo dell’ultimo vertice. Deve trovarsi nell’intervallo ]0, 1[×]0,.5[
ZW
Non utilizzato, deve essere Float2(0, 1)
Intestazioni tracciato
L’intestazione del documento è immediatamente seguita da number-of-paths = top[(0,0)].X path-headers, uno per unità semantica.
E.g. se il documento contiene 3 tracciati, questi verranno memorizzati nei formati U[(0,1)*pixel_size], U[(0,2)*pixel_size] e U[(0,3)*pixel_size] (con pixel_size = top[(0,0)].YZ).
Se sono presenti più tracciati di quanto possa contenere una riga di pixel, le intestazioni rimanenti del tracciato vengono scritte una sulla riga o sulle righe successive, in ordine di scansione.
È consentito avere intestazioni di percorso null (top[...].XYZW = Float4(0,0,0,0)). Tale percorso potrebbe comunque essere un percorso vuoto.
L’intestazione del percorso Nth verrà definita all’indirizzo path\_addr come segue:
Numero di vertici in questo percorso. Deve essere compreso nell’intervallo [0, 16777216].
Se i vertici iniziale e finale di un tracciato chiuso si trovano nella stessa posizione, contano comunque per 2 vertici.
Un percorso con 0 vertici è comunque un percorso valido.
A
Flag_closed: 1 se il percorso è chiuso (ad esempio un cerchio), 0 in caso contrario (ad esempio una linea retta).
Z
L’indice del percorso N. Deve assolutamente corrispondere a percorso_addr (vedi nota sotto).
L
Flag di intestazione: 1/16 = 0,0625.
Indirizzo di vertice iniziale (o primo).
ZW
Indirizzo di fine (o ultimo) vertice.
path\_addr da N utilizzando la funzione Utils/pixel\_index\_to\_position in paths_tools.sbs: path\_addr = pixel\_index\_to\_position(N+1)Informazioni sui vertici
I vertici si trovano ovunque nell’immagine dopo le intestazioni (intestazioni di documenti o tracciati). I vertici possono essere di vari “tipi” (Inizio, Metà o Fine) e sono collegati in modo esplicito mediante 2 puntatori di indirizzo (“collegamenti”).
I vertici Inizio e Fine sono speciali a questo proposito: per consentire la rappresentazione di tracciati chiusi o di una rete arbitraria di tracciati collegati tra loro, uno dei collegamenti viene in realtà utilizzato per formare un elenco circolare collegato in avanti di tutti gli altri vertici Inizio o Fine che rappresentano lo stesso vertice. Tali vertici che corrispondono tra loro sono chiamati “fratelli”. [Illustrazione accolta]
Formalmente, ogni vertice all’indirizzo *vert\_addr* è definito nel modo seguente:
Posizione del vertice. Le coordinate possono essere qualsiasi valore float diverso da NaN o ±inf. Non c’è alcun concetto di affiancamento a questo livello (può essere maneggiato o meno dall’implementazione di ogni filtro), quindi i percorsi dovrebbero essere definiti sul piano euclideo.
Z
Indice del percorso dei vertici. Un vertice può appartenere a un solo tracciato. (Come accennato in precedenza, i vertici Inizio e Fine possono tuttavia avere pari livello.) L’indice dei percorsi può essere utilizzato per recuperare l’intestazione dei percorsi (vedi Sezione Intestazioni percorso sopra), quindi assicurati di mantenerla sincronizzata.
L
Tipo di vertice. Viene divisa tra il segno del valore e il suo valore assoluto:
Nella parte segno, un valore pari a 0 significa che in realtà non esiste alcun vertice in questo punto (anche tutti gli altri componenti dovrebbero essere 0). Un valore negativo indica che il vertice è contrassegnato come un “angolo”, un valore positivo indica che il vertice è “arrotondato”. Il vertice Angolo o Arrotondato è un attributo puro e isolato e non ha alcun impatto o significato sul resto della codifica Tracciati.
Nella parte relativa al valore assoluto, sono codificati il tipo di pixel (Inizio, Metà o Fine) e un altro flag (banale_link):
-
0.125: vertice finale (ultimo vertice della forma; collegamenti sempre non banali, vedere di seguito)
-
0.25: vertice iniziale (il primo vertice della forma; collegamenti sempre non banali, vedere di seguito)
-
0.5: vertice centrale con collegamenti non banali
-
1: vertice centrale con collegamenti banali
“Collegamenti banali” si riferisce al fatto che i vertici precedente e successivo (nell’elenco dei vertici del percorso corrente) sono memorizzati rispettivamente nel pixel a sinistra (vert_addr-(0,pixel_size)) e a destra (vert_addr+(0,pixel_size)), mentre “collegamenti non banali” significa che almeno uno di questi è memorizzato altrove.
Indipendentemente dai collegamenti “banalità”, i valori affidabili dei collegamenti vengono memorizzati nella parte inferiore:
XY
L’indirizzo del vertice precedente di questo percorso. Per i vertici iniziali, questo punta al vertice di pari livello successivo.
se |top[vert_addr].W| = 1, quindi bottom[vert_addr].XY = vert_addr - (0,pixel_size)
ZW
L’indirizzo del vertice successivo di questo percorso. Per i vertici finali, punta al vertice di pari livello successivo.
se |top[vert_addr].W| = 1, quindi bottom[vert_addr].ZW = vert_addr + (0,pixel_size)
Lettura e scrittura delle informazioni sui percorsi
Se desiderate creare nodi di elaborazione tracciati personalizzati, avete a disposizione diversi strumenti.
Le nozioni di base sono fornite dai nodi Paths Vertex Processor e Paths Vertex Processor Simple, che possono essere utilizzati nello stesso modo di un Pixel Processor.
Se sono necessarie funzionalità che vanno oltre quelle offerte dai nodi del processore vertici percorsi (più texture di input o più vertici precedenti o successivi), la copia dell’implementazione di questo grafico potrebbe essere un buon punto di partenza (supponendo di sostituire il nodo Get(“%perVertex”) con l’elaborazione personalizzata).
Ma se volete fare qualcosa di più alieno che applicare una funzione per vertice, ecco una spiegazione dettagliata degli strumenti che potete usare. Si tratta in genere di piccole funzioni di supporto che si trovano nello stesso pacchetto degli altri nodi Percorsi (percorsi_tools.sbs). Queste funzioni non sono disponibili nel menu Libreria e Nodo.
Funzioni ‘Read’
Nella cartella Read, puoi trovare alcuni di questi elementi, utili per raccogliere informazioni sui percorsi:
Alcuni possono fornire informazioni su un determinato pixel. Tutti accettano come input il valore Virgola mobile 4 campionato nella parte *top*. Se guardate alla loro implementazione, sono molto semplici. Il loro scopo è quello di trasmettere più significato dei semplici nodi atomici:
is\_header e che current\_pixel\_is\_document\_header abbia restituito false.is\_vertex).is\_vertex).is\_vertex).is\_start\_vertex || is\_mid\_vertex. Più utile per l’elaborazione basata su Fx-Map, per elaborare ogni segmento al massimo una volta.is\_vertex: se la risposta è vera, si è sicuramente su un vertice). Ricorda che questo flag non è ancora supportato dai nodi ufficiali.Se si tratta di un vertice, indica se è possibile dedurre facilmente la posizione dei vertici precedente e successivo senza campionare la parte inferiore. (Nota: un non vertice restituirà sempre false).
È probabile che non si desideri utilizzare questa funzionalità direttamente, ma utilizzare una delle funzioni sample\_next\* o sample\_prev\* che si occupano automaticamente di questo aspetto.
Dato il valore campionato della parte superiore *sampled* e la sua posizione *sampled\_position*, restituisce il valore campionato della parte superiore del vertice successivo (rispettivamente precedente) e Imposta una variabile Virgola mobile2 *next\_sampled\_pos* sulla posizione (nella parte superiore) di questo vicino (ovvero <valore restituito> = SampleColor(next_samples_pos, image0)). *input0PixSize*deve essere uguale alla dimensione in pixel del tracciato (top[(0,0)].YZ).
Se il pixel corrente (*sampled*) è un vertice Inizio, esempio_prev restituirà il fratello successivo di questo vertice; allo stesso modo, se è un vertice Fine, campione_successivo restituirà il fratello successivo di questo vertice (ovvero, potrebbe non essere quello desiderato). Per risolvere il problema, vedere *sample\_next\_advanced* e *sample\_prev\_advanced* di seguito.
Si noti che per semplicità, si presume che Le informazioni sui percorsi vengano memorizzate in input0! Inoltre, a differenza degli stati del documento della funzione, non è necessario pre-dichiarare *next\_sampled\_pos*. *[out]next\_sampled\_pos* è un parametro fittizio per ricordare che questo secondo “valore restituito” esiste.
È possibile controllare *paths\_trace* Fx-Map, nel parametro Iterazioni del terzo nodo iterato, per un esempio di come utilizzarlo.
Funzioni ‘Write’
Nella cartella Write, troverai piccoli helper che creano una Virgola mobile4 pronta per essere scritta da un Fx-Map.
In effetti, Fx-Map moltiplica RGB per Alpha prima di disegnare, quindi i valori effettivi non vengono premoltiplicati per compensare. Se desideri utilizzare queste funzioni, ad esempio in un Elaboratore pixel, ti consigliamo di applicare nuovamente la premoltiplicazione o di scrivere una versione personalizzata (più ottimizzata per il tuo caso d’uso e più facile da usare).
*nbVertices*, al flag *isClosed* e al *pathIndex*.Crea la parte superiore di un vertice, impostando la posizione, il tipo e le altre opzioni di conseguenza.
Informazioni sul parametro mid_vertex e hasTrivialLinks: se preferisci impostare il valore appropriato, ma se alla fine non riesci a stabilire se i collegamenti sono banali o meno, puoi impostarlo su false (a scapito di un’elaborazione più lenta del percorso generato).
Non esiste un generatore di parti inferiori per le intestazioni di percorso e i vertici: entrambi codificano due collegamenti alla parte superiore, quindi questa funzione sarebbe essenzialmente un costruttore Vettore Float4 da due Virgola mobile2. Non dimenticare di dividere XYZ per W se scrivi utilizzando una Mappa Fx (dove W è la Y di un indirizzo e non deve mai essere null).
Troverai un esempio pertinente di come utilizzare queste funzioni nel pacchetto paths_polygon.sbs che ospita il nodo Paths Polygon.
Metodi per l’elaborazione dei tracciati
È probabile che per implementare l’elaborazione personalizzata si utilizzi un Elaboratore pixel o una mappa Fx, ognuno dei quali ha i propri punti di forza e di debolezza:
La soluzione basata su Fx-Map sarà in genere preferita quando si eseguono operazioni di alto livello che richiedono una conoscenza globale dell’intero percorso (o percorsi) o una conoscenza cumulativa (ad esempio, se si esegue il reinserimento dei vertici dopo la decimazione o la tassellatura). È anche il metodo più semplice da utilizzare, quindi se si esegue un’elaborazione personalizzata per la prima volta, è possibile utilizzare una mappa Fx, nonostante potrebbe essere più lenta.
Per prima cosa devi acquisire familiarità con Fx-Map. In caso contrario, consulta la documentazione specifica.
Si consiglia di esaminare l’implementazione di Anteprima tracciati in tracciati_trace.sbs e Tracciati poligono in tracciati_poligono.sbs per ottenere un’idea su come leggere e scrivere (rispettivamente) un tracciato utilizzando una mappa Fx.
La soluzione Elaboratore pixel sarà adatta se sono necessarie solo informazioni “locali”. Qui intendiamo “locale” non spazialmente (la distanza tra gli elementi) ma piuttosto topologicamente (vertici collegati tra loro). Questo è il modo in cui viene implementato il Processore Vertice. L’Elaboratore pixel è in genere più veloce della mappa Fx per questo tipo di operazione, poiché la funzione di ciascun pixel viene valutata in parallelo, mentre si accede solo a una quantità limitata di dati. Lo sforzo di implementazione potrebbe tuttavia essere molto più importante, in quanto è possibile modificare solo il pixel corrente.
Non entreremo nei dettagli, poiché c’è così tanto da dire a seconda del tuo caso d’uso specifico, ma la prima cosa da fare è verificare dove sei:
Sei nella parte superiore ($pos.y < 0.5) o inferiore ($pos.y > 0.5)? Si consiglia di tenere presente che in una variabile dedicata (ad esempio *isTop*) e di creare un *vert.addr* Float2 tale valore è *$pos* per la parte superiore e $pos - (0,0.5) per la parte inferiore.
Che cos’è vert.addr? Campionarlo e controllare se c’è qualcosa (W != 0) poi, se c’è, cosa esattamente. Intestazione (W = 0,0625) (controllo con *Read/is\_header*) o vertice (controllo con Read/is\_vertex)? E se è un’intestazione, è l’intestazione del documento o un’intestazione Percorso? Puoi utilizzare *Read/current\_pixel\_is\_document\_header* per verificarlo. Utilizzare una o più delle funzioni di supporto per trovare la soluzione più appropriata.