Pourquoi Povray ?

Dans le cas idéal, j'aurais souhaité un logiciel de modélisation 3D qui permette à la fois :

Autant vous le dire tout de suite, le Graal n'existe pas.

Au fur et à mesure des années, j'ai donc testé diverses approches : des moteurs de jeu (UDK, CryEngine), des logiciels de modélisation comme Blender ou 3DS Max, des langages web (X3D, WebGL), avant de revenir à Povray.
Je viens à l'instant de découvrir que la dernière version de Blender (d'avril 2012) gère enfin « BMesh, le nouveau système de maillage permettant de gérer des faces à plus de 4 sommets » . Il va donc être temps de tester à nouveau.

Mon exercice de test n°1 quand je débute dans un langage

Objectif : Dessiner un solide d'Archimède répondant au doux nom de Truncated cuboctahedron.

On va commencer par définir la distance entre le centre du polyèdre et les centres des cubes (en jaune), des hexagones (en bleu) et des octogones (en rouge)
Prenons une longueur d'arrête à 1 (toutes les arêtes du polyèdre ont la même longueur).
Sortez un papier, lancez les neurones et remémorez-vous le théorème de Pythagore (ou faites confiance à mes calculs).

// Distance du centre du polyèdre (placé en 0,0,0) au centre de l'octogone : d1
#declare d1=0.5+sqrt(2); // ~1,914213562373095
// Distance du centre du polyèdre au centre du carré : d2
#declare d2 = 1.5+1/sqrt(2); // ~2,207106781186548
// Distance du centre du polyèdre au centre de l'hexagone : d3
#declare d3 = 5/sqrt(6); // 2.04

Pour les faces octogonales et carrées, c'est assez simple : les octogones appartiennent tous à un cube centré en 0,0,0 et de côté 2*d1, et les carrés appartiennent à trois cubes centrés en 0,0,0 de côté 2*d2, et tournés chacun de 45° sur un des axes.
Les hexagones, eux, ne sont pas orthogonaux entre eux : ils appartiennent par contre à un octaèdre centré lui aussi en 0,0,0.

// Distance du centre du polyèdre au sommet de l'octaèdre : d4
#declare d4 = 1/2*sqrt(3)*(1+sqrt(2));

On réalise alors l'intersection des 4 cubes et de l'octaèdre :
Note : je n'ai pas utilisé de boucle pour que l'on puisse voir plus facilement ce qu'apporte chaque ligne du code.

#declare total = intersection{

box {d1*< -1, -1, -1 >, d1*< 1, 1, 1 > texture { pigment { color Red } finish { Polished }}}

box {d2*< -1, -1, -1 >, d2*< 1, 1, 1 > texture { pigment { color Yellow } finish { Polished }} rotate <45, 0, 0>}
box {d2*< -1, -1, -1 >, d2*< 1, 1, 1 > texture { pigment { color Yellow } finish { Polished }} rotate <0, 45, 0>}
box {d2*< -1, -1, -1 >, d2*< 1, 1, 1 > texture { pigment { color Yellow } finish { Polished }} rotate <0, 0, 45>}

plane{<-1,1,-1>,d4 texture { pigment { color Blue } finish { Polished }}}
plane{<-1,1,-1>,d4 texture { pigment { color Blue } finish { Polished }} rotate <0, 90, 0>}
plane{<-1,1,-1>,d4 texture { pigment { color Blue } finish { Polished }} rotate <0,180, 0>}
plane{<-1,1,-1>,d4 texture { pigment { color Blue } finish { Polished }} rotate <0,270, 0>}
plane{<-1,-1,-1>,d4 texture { pigment { color Blue } finish { Polished }}}
plane{<-1,-1,-1>,d4 texture { pigment { color Blue } finish { Polished }} rotate <0, 90, 0>}
plane{<-1,-1,-1>,d4 texture { pigment { color Blue } finish { Polished }} rotate <0,180, 0>}
plane{<-1,-1,-1>,d4 texture { pigment { color Blue } finish { Polished }} rotate <0,270, 0>}

}
object {total}

Et voilà, plus qu'à placer la(les) source(s) de lumière et la caméra.

light_source {
< 1, 3, -4 >
color White
}

camera {
//location < -7*cos(clock), 2*sin(clock*5), -7*sin(clock) > // exemple de caméra mobile
location <-4, 4, -8> // exemple de position fixe
look_at < 0, 0, 0 >
}