Esri CityEngine

Posté le Tue 08 March 2016 dans SIG / Géographie
Temps de lecture estimé : 4 minute(s).

Il y a quelques jours, j'ai décidé de tester Esri CityEngine, l'outil d'Esri permettant de modéliser des villes en 3 dimensions :

J'ai donc téléchargé la version d'évaluation de 30 jours, et j'ai pris un peu de mon temps libre pour suivre 3 formations en ligne :

J'ai ensuite passé quelques heures à jouer avec cet outil, et honnêtement, j'ai été bluffé par ce qu'on peut faire, et surtout par la facilité avec laquelle on peut modéliser une ville, ou un village, en 3 dimensions. Bien entendu, si on veut créer la représentation fidèle d'une ville (comme dans la vidéo ci-dessus), en respectant les hauteurs des différents bâtiments, en utilisant les bonnes textures, en faisant attention à la forme et la couleur des toitures, en plaçant les arbres où il faut, etc., cela prendra un certain temps (bien plus que les quelques heures que j'y ai consacré).

Mais par contre, on peut assez rapidement obtenir une représentation schématique d'une ville en générant un certain nombre de paramètres de manière aléatoire. C'est ce que j'ai décidé de faire avec mon village.

Pour la petite histoire, mon village s'appelait jusqu'à fin 2015 Ammertzwiller, mais les villages de Bernwiller et d'Ammertzwiller ont fusionné, et depuis début 2016, les deux communes ont été regroupées sous le nom de Bernwiller. En gros j'ai changé de village, et donc d'adresse postale, le tout sans démanager. Pas mal, non ? :-)

Allez, c'est parti !

Étape 1 : récupérer les données 2D d'OpenStreetMap

Ça, c'est facile. On va sur OpenStreetMap, et on utilise la fonction Exporter :

On obtient alors un fichier .osm.

Étape 2 : intégrer le modèle 2D dans CityEngine

Bon, je ne veux pas faire un tutoriel, donc je passe les détails, mais en gros, un simple drag&drop du fichier .osm que je viens de télécharger, et voilà qu'on obtient :

Étape 3 : Générer le modèle 3D

Là, ça devient intéressant. CityEngine permet de définir un script de règles à appliquer à nos objets 2D pour en faire des objets 3D. J'ai donc défini de manière aléatoire des hauteurs, des formes de toiture à appliquer à tous les bâtiments de mon village. Et voilà ce que j'obtiens :

Je peux ensuite modifier chaque bâtiment individuellement pour que ça corresponde mieux à la réalité. J'ai par exemple augmenté la hauteur de l'église, diminué la hauteur des bâtiments autour, et changé la forme de certains toits. J'obtiens alors un modèle qui commence à beaucoup se rapprocher de la réalité :

Étape 4 : Ajouter des textures

Là encore, c'est assez génial. En modifiant le script, on peut appliquer de manière aléatoire des textures à nos bâtiments, et ensuite modifier chaque maison, chaque immeuble individuellement pour lui mettre la texture correspondant le mieux à la réalité. On peut également ajouter des textures aux routes, définir la largeur des trottoirs, ajouter des arbres, etc... Voilà ce que ça donne :

Étape 5 : Jouer avec le Soleil

CityEngine nous permet ensuite de jouer avec le Soleil. On peut définir un mois de l'année, une heure, et on voit alors les ombres des bâtiments se déplacer. Cela permet de voir quel bâtiment fait de l'ombre à quel autre bâtiment par exemple. Plus particulièrement, lorsqu'on projette de construire une résidence, on peut se faire une idée du résultat final, et voir dans quelle mesure cela va impacter l'ensoleillement des voisins.

Voici par exemple une projection au mois de juillet, à 8h le matin :

Le même endroit, à midi :

Et enfin le soir, à 18h :

Étape 6 : Partager sur ArcGis Online

Enfin, on peut exporter et partager notre superbe modélisation sur ArcGis Online :

Et tout ça avec un tout avec un tout petit script de rien du tout :

version "2015.2"
attr WallTexture = fileRandom("assets/Walls/*.jpg")
attr RoofTexture = fileRandom("assets/Roof/*.jpg")

@Range (3,30)
attr Height = randomHeight
randomHeight =
    20% : 3
    20% : 5
    20% : 7
    20% : 9
    10% : 11
    5% : 13
    3% : 15
    else : 17

@Range ("Gable", "Hip", "Flat", "Shed")
attr RoofType = randomRoofType
randomRoofType =
    case scope.sx > 30 || scope.sy > 30 : "Flat"
    case p(0.3) : "Gable"
    case p(0.3) : "Hip" 
    else : "Shed" 

@StartRule 
Build -->
    extrude(Height)
    comp (f) {top:Roof|side:Wall}

Wall -->
    Texture("Wall")

Texture(whichFace) -->
    case whichFace == "Wall":
        setupProjection(0, scope.xy, scope.sx, scope.sy)
        projectUV(0)
        texture(WallTexture)
    case whichFace == "Roof":
        setupProjection(0, scope.xy, scope.sx, scope.sy)
        projectUV(0)
        texture(RoofTexture)
    else :
        FinalTexture.

Roof -->
    RoofShape

RoofShape -->
    case RoofType == "Gable" : 
        roofGable(30, 0.5, 0.5)
        comp (f) {aslant:Texture("Roof") | side:Texture("Wall")}
    case RoofType == "Shed" : 
        roofShed(9)
        comp (f) {top:Texture("Roof") | side:Texture("Roof")}
    case RoofType == "Hip" : 
        roofHip(45, 0.5)
        comp (f) {aslant:Texture("Roof") | side:Texture("Roof")}
    case RoofType == "Flat" : 
        extrude (0.5)
        comp (f) {top:Texture("Roof") | side:Texture("Roof")}
    else : print ("unknown roof type")

Si c'est pas génial Esri CityEngine !