Spécifications de format des tracés

Cette page décrit le format Tracés et fournit des instructions sur la manipulation des données dans ce format à l’aide des fonctions incluses dans les outils Tracés.

Spécifications de format

Cette section explique comment un document Chemins d’accès (ou une image) est codé :

Un document Tracés est une liste de tracés, chacun décrivant une liste de segments, codés dans une texture de couleurs à virgule flottante de 32 bits.

La texture est divisée en parties « supérieures » ($pos.y < 0.5) et « inférieures » ($pos.y > 0.5).

Toutes les données d’un pixel dans la partie ‘supérieure’ sont sémantiquement étroitement liées au pixel correspondant dans la partie ‘inférieure’, et vice-versa.

Tracés de données codées en polygone
NOTE
Les données de tracés nécessitent une précision de 32 bits et une résolution inférieure produira des résultats incorrects.
Par conséquent, veillez à définir le paramètre « Format de sortie » des nœuds générant des données de chemins sur « HDR Haute précision (32F) ».

Soit *uv\_pos* une adresse 2D (telle que $pos) d’un pixel de la partie supérieure.

Dans la suite de ce document :

  • top[uv_pos].XYZW fera référence aux 4 flotteurs stockés dans le pixel de la partie supérieure.
    top[uv_pos] == sample_color(paths, uv_pos)
  • bottom[uv_pos].XYZW fera référence aux 4 flotteurs stockés dans le pixel correspondant de la partie inférieure.
    bottom[uv_pos] == sample_color(paths, uv_pos + Flottant 2(0, 0.5))

top[uv_pos] et bottom[uv_pos] forment ensemble une unité sémantique U[uv_pos] du document, composée de 8 flotteurs.

En-tête de document

Chaque document Tracés commence par un en-tête de document. Il s’agit de la toute première unité sémantique U[(0,0)]:

Haut X

Le nombre de tracés (doit être un entier positif dans [0 ; 16777216]).

Si certains tracés sont vides, ils comptent toujours ici. Vous pouvez donc l’envisager comme un « nombre d’en-têtes de chemins à décoder ».

YZ

Taille de pixel de ce document (c’est-à-dire exactement Float2(1,1) / $size).

Cela est utile lors de la lecture des tracés à partir d’un Processeur de pixels ou d’un Fx-Map, par exemple, dont la taille de sortie est différente.

W

1/16 = 0,0625 (indicateur d’en-tête)

Bas XY

Adresse du dernier vertex défini dans ce document. Ceci est utile pour ajouter de nouvelles données.

Il peut donc s’agir en fait de toute adresse supérieure (par ordre de balayage) à l’adresse du dernier vertex. Il doit être compris entre ]0, 1[×]0,.5[

ZW

Inutilisé, doit être Flottant 2(0, 1)

En-têtes de tracé

L’en-tête du document est immédiatement suivi de number-of-paths = top[(0,0)].X path-headers, one by semantic unit.
E.g. s’il y a 3 tracés dans le document, ils seront stockés en U[(0,1)*pixel_size], U[(0,2)*pixel_size] et U[(0,3)*pixel_size] (avec pixel_size = top[(0,0)].YZ).

S’il y a plus de tracés que ce qu’une ligne de pixels peut contenir, les en-têtes de tracé restants sont écrits sur la ou les lignes suivantes, dans l’ordre des lignes de numérisation.
Il est autorisé d’avoir des en-têtes de chemin d’accès nuls (top[...].XYZW = Float4(0,0,0,0)) ; un tel chemin d’accès peut toujours être vide.

L’en-tête de chemin du Nième chemin sera défini à l’adresse path\_addr comme :

Haut X

Nombre de vertex dans ce chemin. Doit être compris dans la plage [0, 16777216].

Si les vertex de début et de fin d’un tracé fermé se trouvent à la même position, ils comptent toujours pour 2 vertex.
Un chemin avec 0 vertex est un chemin valide.

Y

Indicateur Est_fermé : 1 si le tracé est fermé (par exemple, un cercle), 0 dans le cas contraire (par exemple, une ligne droite).

Z

L’index de chemin N. Il doit absolument correspondre à path_addr (voir remarque ci-dessous).

W

Indicateur d’en-tête : 1/16 = 0,0625.

Bas XY

Adresse de début (ou première) du vertex.

ZW

Fin (ou dernière) adresse du vertex.

NOTE
Vous pouvez calculer path\_addr à partir de N à l'aide de la fonction Utils/pixel\_index\_to\_position dans paths_tools.sbs : path\_addr = pixel\_index\_to\_position(N+1)

informations sur les vertex

Les vertex se trouvent n’importe où dans l’image après les en-têtes (en-têtes de document ou de chemin). Les vertex peuvent être de différents « types » (Début, Milieu ou Fin) et ils sont explicitement liés entre eux à l’aide de 2 pointeurs d’adresse (« liens »).

Les vertex Début et Fin sont spéciaux à cet égard : pour permettre la représentation de tracés fermés ou d’un réseau arbitraire de tracés liés entre eux, l’un des liens est en fait utilisé pour constituer une liste circulaire avant liée de tous les autres vertex Début ou Fin qui représentent le même vertex. Ces vertex qui se correspondent sont appelés « frères et sœurs ». [Illustration accueillie]

Formellement, chaque vertex à l’adresse *vert\_addr* est défini comme ceci :

Haut XY

La position vertex. Les coordonnées peuvent être n’importe quelle valeur flottante autre que NaN ou ±inf. Il n’y a pas de notion de répétition à ce niveau (elle peut être gérée ou non par la mise en œuvre de chaque filtre), les chemins sont donc supposés être définis sur le plan euclidien.

Z

Index de chemin de vertex. Un vertex ne peut appartenir qu’à un seul chemin. (Comme mentionné précédemment, les vertex de début et de fin peuvent toutefois avoir des frères.) L’index de chemin peut être utilisé pour récupérer l’en-tête de chemin (voir la section En-têtes de chemin de section ci-dessus). Assurez-vous donc qu’il est synchronisé.

W

type de vertex. Il est divisé entre le signe de la valeur et sa valeur absolue :

Sur la partie signe, une valeur de 0 signifierait qu’il n’y a pas de vertex ici en fait (tous les autres composants devraient également être 0). Une valeur négative signifie que le vertex est marqué comme un « coin » ; une valeur positive signifie que le vertex est « lisse ». Le vertex d’arrondi et le calque d’arrondi sont des attributs purs et isolés qui n’ont aucun impact ni aucune signification sur le codage des autres tracés.

Sur la partie valeur absolue, le type de pixel (Début, Milieu ou Fin) et un autre drapeau (trivial_link) sont codés:

  • 0.125 : vertex de fin (dernier vertex de la forme ; liens toujours non triviaux, voir ci-dessous)

  • 0.25 : vertex de début (premier vertex de la forme ; liens toujours non triviaux, voir ci-dessous)

  • 0.5 : vertex moyen avec des liens non triviaux

  • 1 : milieu de vertex avec des liens insignifiants

Par « liens non triviaux », on entend le fait que les vertex précédent et suivant (dans la liste des vertex du tracé courant) sont stockés respectivement dans le pixel à gauche (vert_addr-(0,pixel_size)) et à droite (vert_addr+(0,pixel_size)), tandis que par « liens non triviaux », on entend qu’au moins l’un d’entre eux est stocké ailleurs.

Bas

Indépendamment de la « banalité » des liens, les valeurs fiables des liens sont stockées dans la partie inférieure :

XY

Adresse du vertex précédent de ce chemin. Pour les vertex de démarrage, cette option pointe vers le vertex apparenté suivant.
si |top[vert_addr].W| = 1, puis bottom[vert_addr].XY = vert_addr - (0,pixel_size)

ZW

Adresse du vertex suivant de ce chemin. Pour les vertex d’extrémité, cette option pointe vers le vertex apparenté suivant.
si |top[vert_addr].W| = 1, puis bottom[vert_addr].ZW = vert_addr + (0,pixel_size)

Informations sur les chemins de lecture et d’écriture

Si vous souhaitez créer vos propres nœuds de traitement des tracés, vous disposez de plusieurs outils.

Les bases sont fournies par les nœuds Processeur de Vertex de tracés et Processeur de Vertex de tracés simple, qui peuvent être utilisés de la même manière qu’un Processeur de pixels.

Si vous avez besoin de fonctionnalités au-delà de ce que proposent les nœuds du processeur de Vertex Paths (plus de textures d’entrée, ou plus de vertex précédents ou suivants), la copie de l’implémentation de ce graphe peut être un bon point de départ (en supposant que vous remplacez le nœud Get(« %perVertex ») par votre traitement personnalisé).

Mais au cas où vous voudriez faire quelque chose de plus étrange que l’application d’une fonction par vertex, voici une explication détaillée des outils que vous pouvez utiliser. Il s’agit généralement de petites fonctions d’assistant qui se trouvent dans le même package que les autres nœuds Paths (paths_tools.sbs). (Ces fonctions ne sont pas exposées dans le menu Bibliothèque et le menu Nœud.)

Fonctions de lecture

Sous le dossier Read, vous trouverez plusieurs de ces éléments, utiles pour collecter des informations sur les Chemins :

Certains peuvent vous donner des informations sur un pixel donné. Ils prennent tous la valeur Flottant 4 échantillonnée dans la partie *top* comme entrée. Si vous regardez leur mise en œuvre, ils sont super-simples. Leur but est de donner plus de sens que de simples noeuds atomiques :

is<>header
Vérifiez que la valeur actuellement échantillonnée est un en-tête de chemin d’accès ou de document.
path<>is<>close
Vérifiez l’indicateur Is_Closed (.Y) dans un en-tête de chemin. Il *suppose que vous avez déjà vérifié qu’il s’agit d’un chemin* avec is\_header et que current\_pixel\_is\_document\_header a renvoyé la valeur false.
is<>vertex
Vérifier que la valeur échantillonnée courante est un vertex, c’est-à-dire non un en-tête, ni un pixel vide.
is<>start<>vertex
Vérifiez si une valeur *top-part samples* est un vertex de démarrage (pas besoin de vérifier d’abord is\_vertex).
is<>mid<>vertex
Vérifiez si une valeur *top-part samples* est un vertex qui n’est pas un vertex de début ou de fin (pas besoin de vérifier d’abord is\_vertex).
is<>end<>vertex
Vérifiez si une valeur *top-part samples* est un vertex de fin (pas besoin de vérifier d’abord is\_vertex).
is<>segment<>start
Abréviation de is\_start\_vertex || is\_mid\_vertex. Plus utile pour le traitement basé sur Fx-Map, pour traiter chaque segment au plus une fois.
is<>corner
Vérifiez l’indicateur d’angle du vertex (pas besoin de vérifier d’abord is\_vertex : si la réponse est vraie, vous êtes sur un vertex pour sûr). Rappelez-vous que cet indicateur n’est pas encore pris en charge par les nœuds officiels.
has<>trivial<>links

S’il s’agit d’un vertex, indique si vous pouvez facilement déduire la position des vertex précédent et suivant sans échantillonner la partie inférieure. (Remarque : un non-vertex renvoie toujours la valeur false.)

Vous ne voulez probablement pas l’utiliser directement, mais utilisez plutôt l’une des fonctions sample\_next\* ou sample\_prev\*, qui s’en occupent pour vous.

sample<>next, sample<>prev

Compte tenu de la valeur échantillonnée de la partie supérieure *sampled* et de sa position *sampled\_position*, renvoie la valeur échantillonnée de la partie supérieure du vertex suivante (respectivement précédente) et Définit une variable Flottant 2 *next\_sampled\_pos* à la position (dans la partie supérieure) de ce voisin (c’est-à-dire <valeur renvoyée> = SampleColor(next_sampl_pos, image0)). *input0PixSize*doit être égal à la taille en pixels du tracé (top[(0,0)].YZ).

Si le pixel actif (*sampled*) est un vertex Début, sample_prev renvoie le frère suivant de ce vertex. De même, s’il s’agit d’un vertex Fin, sample_next renvoie le frère suivant de ce vertex (ce qui n’est peut-être pas ce que vous voulez). Voir *sample\_next\_advanced* et *sample\_prev\_advanced* ci-dessous pour résoudre ce problème.

Veuillez noter que pour plus de simplicité, les informations sur les chemins d’accès sont supposées être stockées dans input0 ! En outre, contrairement à ce qu’indique le document de la fonction, vous n’avez pas besoin de déclarer préalablement *next\_sampled\_pos*. *[out]next\_sampled\_pos* est un paramètre fictif pour vous rappeler que cette deuxième « valeur renvoyée » existe.

Vous pouvez vérifier le *paths\_trace* Fx-Map, dans le paramètre Itérations du troisième nœud d’itération, pour obtenir un exemple d’utilisation.

Cas d’utilisation minimal de samplenext

Cas d’utilisation de samplenext dans les chemins d’aperçu (pathtrace)

sample<>next<>advanced, sample<>prev<>advanced
Il est destiné à fonctionner sur des tracés fermés. Pour les tracés ouverts, le vertex de début ou de fin n’a pas de frère et, dans ce cas, les deux fonctions renvoient le même et seul voisin. Pour les vertex de début ou de fin ayant plusieurs éléments frères (Tracés connectés en tant que réseau), qui renvoie le vertex voisin du frère suivant dans la liste liée.

Fonctions ‘Write’

Sous le dossier Write, vous trouverez de petits assistants qui créent un Flottant 4 prêt à être écrit par un Fx-Map.

En effet, la Fx-Map multiplie le RGB par Alpha avant de dessiner, de sorte que les valeurs réelles ne sont pas prémultipliées pour compenser. Si vous souhaitez utiliser ces fonctions, par exemple dans un Processeur de pixels, nous vous recommandons de réappliquer la prémultiplication vous-même ou d’écrire une version personnalisée (plus optimisée pour votre cas d’utilisation et plus facile à utiliser).

document<>header
Génère la partie supérieure de l’en-tête du document, en déclarant le nombre de chemins d’accès que vous fournissez.
document<>last<>vertex<>spec
Crée la partie *bottom* de l’en-tête du document, qui spécifie le dernier vertex (voir A.1.).
path<>header
Crée la partie supérieure d’un en-tête de chemin, en fonction du nombre de vertex dans le chemin *nbVertices*, de l’indicateur *isClosed* et de l’indicateur *pathIndex*.
vertex<>début, vertex<>milieu, vertex<>fin

Crée la partie supérieure d’un vertex, en définissant la position, le texte et d’autres options en conséquence.

Environ mid_vertex et le paramètre hasTrivialLinks : idéalement, vous devez définir la valeur appropriée, mais si, pour une raison quelconque, vous ne parvenez pas à dire si les liens seront triviaux ou non, vous pouvez sans danger la définir sur false (au prix d’un traitement plus lent de votre chemin généré).

Il n’existe pas de générateur de partie inférieure pour les en-têtes de tracé ou les vertex : les deux codent deux liens vers la partie supérieure, de sorte que cette fonction serait essentiellement un constructeur Vecteur flottant4 de deux Flottant 2. N’oubliez pas de diviser XYZ par W si vous écrivez à l’aide d’une Fx-Map (W étant le Y d’une adresse, elle ne doit jamais être nulle).

Vous trouverez un exemple pertinent d’utilisation de ces fonctions dans le package chemins_polygon.sbs hébergeant le nœud polygone des chemins.

Procédés de traitement de tracés

Vous utiliserez probablement un Processeur de pixels ou un Fx-Map pour mettre en œuvre votre traitement personnalisé, chacun ayant sa force et ses faiblesses :

FX-Map

La solution basée sur Fx-Map est généralement préférée lors de l’exécution d’opérations de haut niveau nécessitant une connaissance globale de l’ensemble du (ou des) chemin(s), ou d’une connaissance cumulative (par exemple, le reconditionnement des vertex après décimation ou tessellation). Il s’agit également de l’approche la plus simple. Par conséquent, si vous effectuez un traitement personnalisé pour la première fois, vous pouvez utiliser une Fx-Map, même si est peut-être plus lent.

Vous devez d’abord vous familiariser avec Fx-Map. Si ce n’est pas le cas, consultez la documentation spécifique.

Nous vous recommandons d’examiner l’implémentation des chemins d’aperçu dans chemins_trace.sbs et du polygone des chemins dans chemins_polygone.sbs pour vous faire une idée de la lecture et de l’écriture (respectivement) d’un chemin à l’aide d’une Fx-Map.

Processeur de pixels

La solution Processeur de pixels conviendra si vous avez uniquement besoin d’informations « locales ». Ici, nous voulons dire « local » non pas spatialement (la distance entre les éléments) mais plutôt topologiquement (les vertex liés entre eux). C’est ainsi que le processeur de Vertex est implémenté. Le Processeur de pixels est généralement plus rapide que la Fx-Map pour ce type d’opération, car la fonction de chaque pixel est évaluée en parallèle, alors que seule une quantité limitée de données est accessible. L’effort d’implémentation peut être beaucoup plus important, car vous ne pouvez modifier que le pixel actuel.

Nous n’entrerons pas dans les détails, car il y a tant à dire en fonction de votre cas d’utilisation spécifique, mais la première chose à faire est de vérifier où vous êtes :

Êtes-vous dans la partie supérieure ($pos.y < 0,5) ou inférieure ($pos.y > 0,5) ? Nous vous recommandons de ne pas oublier que dans une variable dédiée (par exemple, *isTop*) et de créer un Flottant 2 *vert.addr*, cette valeur est *$pos* pour la partie supérieure et $pos - (0,0.5) pour la partie inférieure.

Qu’en est-il à vert.addr ? Échantillonnez-le et vérifiez s’il y a quelque chose (W != 0), puis, s’il y en a, quoi exactement. Un en-tête (W = 0,0625) (cochez avec *Read/is\_header*) ou un vertex (cochez avec Read/is\_vertex) ? S’il s’agit d’un en-tête, est-ce l’en-tête du document ou un en-tête Chemin ? (Vous pouvez utiliser *Read/current\_pixel\_is\_document\_header* pour vérifier cela.) Utilisez une ou plusieurs fonctions d’assistant pour trouver ce qui vous intéresse.

recommendation-more-help
substance-3d-designer-help-guide