Un exemple simple: la nappe

Avant de paramètrer la simulation, il faut en premier lieu créer le fichier .cth de départ.

Ecrire un fichier .cth

Le format .cth a été défini de telle manière à pouvoir être lu et écrit à l'aide des directives d'entrée/sortie fichiers de POV-Ray (#fopen, #read, #write, #fclose). On va donc écrire la macro suivante:

#macro WriteClothFile(nomfile, n1, n2, nlng, ks, ht)
    #debug "\nWriting new .cth file\n"
    #fopen file nomfile write
    #write(file, n1, ",", n2, ",", nlng, ",", ks, ",\n")
    #local l1 = nlng*(n1-1);
    #local l2 = nlng*(n2-1);
    #local st = seed(1234);
    #local i=0;
    #while (i < n1)
        #local j=0;
        #while (j < n2)
            #local tempx = -l1/2 + i*nlng;
            #local tempz = -l2/2 + j*nlng;
            #local tempy = ht + (-1+2*rand(st))*nlng*0.1;
            #write(file, tempx, ",", tempy, ",", tempz, ", 0.0, 0.0, 0.0,\n")
            #local j=j+1;
        #end
        #local i=i+1;
    #end
    #fclose file
#end

Après avoir ouvert le fichier (#fopen), on écrit la première ligne (#write) qui contient le nombre de points du tissu dans les deux dimensions (n1, n2), la distance normale entre chaque points (nlng), et le coefficient de raideur des ressorts (ks).

Ensuite, les différents points sont distribués dans un rectangle de dimension (nlng*(n1-1)) sur (nlng*(n2-1)), parallèle au plan (xz), et à une hauteur ht, centré autour de l'axe y. Un peu de perturbation est ajoutée sur la coordonnée y de chaque point (rand()). Ne pas oublier de fermer le fichier (#fclose)...

Une nappe, ça va sur une table...

On va définir une table le plus simplement possible:

#declare Table = union {
    cylinder { .8*y, .9*y, .8 }
    torus { .8, .05 sturm translate .85*y }
    cylinder { .85*y, 0, .05 }
    cylinder { 0, .05*y, .4 }
}

Visualiser la position de départ du tissu

Il suffit de faire appel à simcloth avec 0 itérations, avec en option la création d'un mesh:

WriteClothFile("nappe.cth", 50, 50, 1.8/50, 10, .95)

simcloth {
    iterations 0
	input "nappe.cth"
	mesh_output "nappe.msh"
	uv_mesh on
}

#declare Nappe = mesh {
    #include "nappe.msh"
    uv_mapping
    texture {
        pigment {
            checker color rgb<1, .5, .2> color rgb<1, .8 ,.4>
            scale <1/10, 1/10, 1/10>
        }
    }
}

On rajoute le sol, les murs, de la lumière, une caméra, et on obtient ceci:

On pose la nappe

Et pour ça, rien de mieux que la gravité (-.4*y). De plus, la table est rugueuse (et le tissu aussi), on va donc mettre le coefficient de frottement à 0. Comme la distance entre chaque point est assez faible, on va prendre un intervalle de temps entre chaque itérations assez faible également (0.03).

simcloth {
    environment Table
    friction 0
    gravity -.4*y,
    damping .9,
    intervals 0.03
    iterations 50
    input "nappe.cth"
    output "nappe.cth"
    mesh_output "nappe.msh"
    smooth_mesh on
    uv_mesh on
}

Pensez à vérifier la fenêtre des messages (sous Windows) ou le flux de sortie (sous Unix) pour savoir si la simulation s'est bien passée ou pas (problème d'ouverture de fichier, manque de mémoire, etc...).

Le fichier .cth de départ peut être calculé une seule fois. En mettant la macro WriteClothFile(...) en commentaire par la suite, chaque simulation reprendra là où la précédente s'est arrétée.

Afin d'éviter les surfaces coïncidentes, on va réduire très légèrement les dimensions de la table, et remonter un peu la nappe lors de l'affichage...

object { Nappe translate 0.001*y }
object { Table scale <.98, 1, .98>
    texture { T_Wood23 rotate <10, 20, 0> }
}

Pour les fainéants, le script complet: nappe.pov

Après 50 itérations...
... 50 itérations supplémentaires...
... et 100 de plus.