Dans ce chapitre, nous allons tout d’abord présenter le cadre du mémoire : la recherche en modélisation moléculaire du Professeur Joël De Coninck. Nous présenterons brièvement les recherches effectuées dans le domaine des simulations dans les phénomènes de mouillage. De ces recherches, nous présenterons les besoins en images de synthèse et les outils qui ont été implémentés.
Nous donnerons les raisons qui ont poussé au choix d’OpenGL pour l’implémentation des différentes applications. Nous présenterons brièvement la librairie graphique OpenGL et ses possibilités. Nous expliquerons ensuite les modifications effectuées à cette librairie pour la représentation de molécules.
Nous présenterons ensuite les implémentations réalisées : la librairie « GL_PLUS » et l’application « MoleView », respectivement une librairie d’aide à la programmation de simulations temps réel de molécules, portable sur différentes plates-formes et un éditeur de films d’images de synthèse permettant une gestion efficace de la caméra virtuelle dans le cas d’images formées par des molécules.
Ces présentations comporteront, pour chacune des implémentations, le cahier des charges à respecter, la motivation des choix effectués dans leur cadre propre, un manuel technique donnant la philosophie générale et les descriptions techniques de l’implémentation et un manuel utilisateur destiné aux utilisateurs finaux des solutions.
Ce mémoire a été effectué dans le service de modélisation moléculaire du Professeur Joël De Coninck.
Les phénomènes de mouillage et l’étude par la Dynamique Moléculaire des interfaces de systèmes liquide–solide et liquide–liquide sont les principales préoccupations du Centre de Recherche en Modélisation Moléculaire.
Les phénomènes de mouillage sont omniprésents. Ils jouent un rôle primordial dans l’industrie des peintures et adhésifs mais aussi des cosmétiques et de la photographie. D’autres domaines d’applications sont la pollution des nappes phréatiques, la corrosion des métaux, la détérioration des façades,..
Citons un exemple concret de l’utilité de ces recherches dans la récupération pétrolière. Classiquement, 20 à 40 % de pétrole brut sont extraits d’un puits. Pour récupérer les 60 a 80 % de pétrole piégé dans les pores du puits d’exploitation, il est nécessaire d’injecter la bonne substance qui délogera le pétrole des anfractuosités de la roche.
Jusqu’il y a peu, ces phénomènes étaient étudiés par des modèles empiriques et théoriques se limitant aux aspects hydrodynamiques et macroscopiques. Mais l’accroissement des puissances de calcul en informatique et le développement des techniques optiques comme l’éllipsométrie permettent d’aborder une étude de ces phénomènes à l’échelle microscopique.
Les méthodes de la mécanique statistique rendent possibles la description du comportement d’un système de molécules ou d’atomes en définissant la manière dont ils interagissent les uns avec les autres. Le problème fondamental consiste à préciser le plus correctement possible la nature des interactions des molécules de liquide entre elles et avec le solide.
Ces interactions définies, il est possible de simuler sur ordinateur le comportement de centaines de milliers d’atomes ou molécules. Les lois de la thermodynamique statistique permettent, à partir des trajectoires de ces particules, d’accéder à des grandeurs macroscopiques du système comme la température, la pression, la viscosité, la tension interfaciale avec d’autres milieux,...
En confrontant les résultats obtenus aux données expérimentales, il est possible d’affiner le modèle numérique. Le but ultime est la compréhension des mécanismes physiques sous-jacents, à l’échelle moléculaire.
La dynamique moléculaire s’applique à des systèmes d’atomes ou de molécules dont on déduit les trajectoires par résolution des équations du mouvement (Newton).
Lorsqu’une goutte de liquide pur est mise en contact avec une surface solide, la goutte s’étale totalement ou partiellement : c’est le régime de mouillage total ou partiel.
La dynamique moléculaire, appliquée à l’étude des interactions « liquide - solide », tente de répondre à la question : comment un liquide de type X mouillera-t-il une surface solide de type Y ? Comment faut-il construire la molécule de liquide X ou quelle est l’épaisseur de la couche de Z qu’il faut appliquer sur le substrat Y pour que les conditions de mouillage partiel ou total soient rencontrées ?
Si certains problèmes peuvent être résolus exactement, d’autres doivent être traités suivant un schéma d’approximation qui ne permet pas toujours de rendre compte des propriétés des liquides. La simulation sur ordinateur, à mi-chemin entre la technique expérimentale et la technique purement numérique, permet de tester les méthodes d’approximation existantes et d’en dégager de nouvelles approches.
C’est dans le cadre d’une visualisation graphique des systèmes simulés que s’inscrit ce mémoire.
Une simulation classique pouvant durer plusieurs semaines sur un « DEC Alpha Server 8400 » (6 CPUs, Processeurs EV5 300 Mhz et 400 Mflops, 1 Gb de mémoire, 45 Gb d’espace disque), il est nécessaire de pouvoir contrôler une simulation en cours.
Un premier besoin est donc de disposer d’outils de création de films d’images de synthèse spécialisés pour l’animation de particules.
Il est utile de disposer d’une librairie destinée à l’animation de systèmes de molécules ou d’atomes dans le but de visualiser les particules en cours de simulation. L’utilisateur pourra focaliser l’affichage sur un groupe de particules pour essayer d’analyser leurs déplacements mutuels.
L’hétérogénéité du parc informatique (PC 486 et pentiums , MIPS indy et indigo 2 , DEC Stations Alpha 3800,) implique que cette librairie d’outils doit être portable sur différentes machines et systèmes d’exploitation.
L’animation d’un grand nombre de particules simulées doit pouvoir s’appuyer sur des outils optimisés pour ce type de visualisation.
Les progrès ont permis de descendre à l’échelle microscopique pour l’analyse des phénomènes de surface. De même, il serait intéressant, en présence d’un amas de molécules, de pouvoir plonger au sein de la matière afin de suivre une particule dans ses déplacements. Ce cheminement au cur même des éléments nous renseignerait efficacement sur les influences des proches voisins sur une particule. Les molécules adoptent-elles la même conformation lorsqu’elles s’approchent d’un substrat solide ? Un ion qui se déplace à proximité d’un solide chargé peut-il se déplacer dans la couche stagnante de fluide presqu’immobilisé au contact du solide ? Quel mécanisme adopte-t-il pour s’y déplacer ?
Autant de questions auxquelles cet outil de visualisation tentera d’apporter des éléments de réponse.
Afin de réaliser cette étude, il serait intéressant de disposer d’une application permettant de positionner une caméra virtuelle au sein d’une simulation : de pouvoir attacher cette caméra à une molécule tout au long de la simulation, de pouvoir déplacer cette caméra d’une molécule à l’autre, de pouvoir se positionner sur une molécule et suivre du regard une autre.
Il serait également utile de pouvoir sauver dans un film les observations faites par ce procédé.
OpenGL est une librairie graphique standardisée d'interfaces entre le software et le hardware graphique qui commence à se présenter comme une référence dans le monde CAO/PAO.
Les principaux services proposés par OpenGLÔ sont le rendu d'objets en deux et trois dimensions. Ces objets sont décrits par des séquences de points qui définissent des objets géométriques ou des séquences de pixels qui définissent des images. OpenGLÔ applique un certain nombre d'opérations à ces données afin de les transformer en pixels pour former l'image finale. Ces opérations sont entre autres : projections, perspectives, colorisations, effets de lumière, vu et caché, ombrages, lissage des couleurs, texturation des formes,...
Cette partie ne reprend pas l’entièreté du fonctionnement d'OpenGLÔ : elle ne reprend que les parties utiles à l’explication de la technique développée et les parties utiles au cas qui nous intéresse : la représentation moléculaire.
Pour plus d'informations sur ce sujet, on se référera utilement à :
L'aide de Microsoft Visual C++ 4.0. [MVC96]
"Graphic Library Toolkit guide" de chez Silicon Graphics. [SGI92]
" OpenGL Référence Manual" [ORM92] écrit par "the OpenGL Architecture Review Board" et "OpenGL Programming Guide" [OPG92] écrit par Jackie Neider, Tom Davis, and Mason Woo . Ces deux derniers livres ont été publiés par Addison-Wesley.
OpenGL permet de dessiner des primitives comme les points, les lignes ou les polygones dans différents modes. Les primitives sont spécifiées, les modes sont définis et les autres opérations qu’OpenGl permet sont décrites par des appels de fonctions.
Les primitives OpenGL sont décrites par un groupe d’un ou plusieurs vertex. Un vertex définit un point, un point d’extrémité d'une ligne ou un point intermédiaire d'un polygone où deux bords se rencontrent. Des données (constituées de coordonnées de vertex, de la couleur, de la normale, des coordonnées de la texture et du flag de "bord") sont associées à un vertex. Chaque vertex et ses données associées sont traités indépendamment, dans l'ordre et de la même façon.
Les commandes sont toujours traitées dans l'ordre dans lequel elles ont été reçues. Par contre, il peut y avoir un temps de délai avant qu'elles ne prennent effet: c'est-à-dire que chaque primitive est affichée complètement avant chaque séquence de commande qui suit. Cela veut aussi dire que toute demande d'informations renvoie des données qui sont consistantes avec l'exécution de toutes les primitives OpenGL qui la précèdent.
OpenGL permet le contrôle direct des opérations graphiques fondamentales en deux et trois dimensions. Ces spécifications incluent les matrices de transformation, les effets de lumière, des méthodes d'antialiasing et les opérateurs de mises à jour.
Le modèle d'interprétation des commandes OpenGL est le modèle client-serveur. Une application, le client, envoie ses commandes qui sont interprétées par OpenGL, le serveur. Le serveur peut ou non s'exécuter sur le même ordinateur que le client. Dans ce sens, OpenGL est "network-transparent"
OpenGL fonctionne par matrices de transformation. Les vertex et les normales sont transformés par matrices de projection et de vues du modèle ("modelview", sur l'espace lui-même) avant de produire l'image finale.
Il est possible d'utiliser des commandes de sélection du type de matrice ("modelview" ou de projection), de multiplication de matrices, ... Il est également possible d'appliquer des matrices de rotation, de translation, de dilatation ou directement la matrice de toutes les transformations afin de composer les transformations désirées. OpenGL permet également de sauvegarder et restaurer ces matrices sur des piles "LIFO" respectives.
En plus de spécifier la couleur et le vecteur normal, il est possible de définir les conditions d'éclairement (couleur de la lumière, intensité,...) et les propriétés du matériel utilisé pour le dessin.
OpenGLÔ permet de définir la couleur d'un objet mais aussi ses attributs : il est possible de définir le comportement d'un objet face à la lumière; s’il est très brillant ou non, s'il a des reflets d'une autre couleur, ...
Pour se faire, il est possible de définir la couleur "spéculaire", "diffuse" et "ambiante" de chaque face de l'objet. Il est également possible de définir la brillance et la couleur d'émission de celles-ci.
De plus OpenGLÔ effectue automatiquement le lissage de couleurs ( Phong ) en gérant les dégradés entre les points de couleurs différentes.
Pour la représentation de surfaces, il existe une panoplie de possibilités : polygone, quadrilatère, NURBS,... Mais la plus rapide en temps CPU est la représentation par triangle. Voici un bref explicatif de cette représentation par triangle, appelée dans la littérature «mesh».
Trois points sont nécessaires pour la définition d'une face , le sens de parcours des points a une importance : en effet il définit l'orientation de la face pour les effets de lumière.
Les "meshs" peuvent êtres regroupés pour former des formes non-planaires plus complexes: de cette façon un cube peut se construire en deux étapes par séries de six triangles.
Afin de permettre plus de flexibilité dans le rendu, il est possible de définir les normales en chaque extrémité de face : pour donner un effet plus lisse à un groupe de faces (par un lissage de Gouraud). Cette technique est intéressante pour l'animation car elle permet de définir, avec moins de faces, une sphère. (CFR Création de formes)
OpenGL permet d'accumuler certaines commandes dans une liste d'affichage pour pouvoir les utiliser plus tard.
Ces listes sont utiles pour la création d'objets fréquemment utilisés : par exemple, on peut créer une roue qui sera appelée, moyennant translations, quatre fois lors de la création d'une voiture et six fois lors de la création d'un camion. Une liste peut contenir une autre liste : une liste "voiture" peut contenir une liste "roue" et une liste "siège".
Ces listes sont plus rapides que des procédures regroupant ces mêmes primitives car ces listes sont compilées lors de l'exécution du programme : ce qui permet d'éviter des appels de fonctions qui utilisent du temps CPU précieux pour l'animation (environ trente cycles d'horloge).
OpenGLÔ permet d'appliquer des translations, des rotations et des dilatations (scale). Ces transformations sont appliquées par multiplication de matrices quatre fois quatre. Ces matrices de transformation sont appliquées à une matrice courante qui contient toutes les transformations successives.
Ce système de matrices permet la hiérarchisation des transformations : OpenGLÔ permet de stocker sur une pile ("Last In First Out") les matrices courantes et de les restaurer dans le futur. (cfr. Annexe Listing SOLAR)
OpenGLÔ permet d'utiliser des fonctions simples qui créent et appliquent les matrices de transformation, mais permet également de créer et d'appliquer ses propre matrices.
OpenGLÔ donne la possibilité de choisir pour l'animation entre le simple et le double buffering.
Le simple buffering qui est l'affichage direct à l'écran est le plus rapide mais occasionne un scintillement de l'affichage si celui-ci est trop rapide par rapport à la vitesse de rafraîchissement de l'écran . Si par contre l'affichage de l'image est trop lent, l'utilisateur pourra voir l'image se dessiner morceau par morceau.
Le double buffering est, quant à lui, le fait de dessiner l'image en mémoire et de faire une copie bit a bit entre celle-ci et la mémoire-écran. Cette copie se fait lorsque le faisceau de l'écran remonte ce qui permet d'éviter le scintillement (vertical retracé).
OpenGL est livré avec une librairie d'utilitaires qui permet la gestion des transformations de coordonnées, la manipulation d'images et de la texturation. Cette librairie permet également de créer des formes simples telles que : des sphères, des cylindres, des disques, mais aussi des NURBS (Non-Uniform Rational B-Spline).
Pour plus d'informations sur les NURBS, référez-vous à l'ouvrage : « L'indispensable pour la synthèse d'images » de J-P Couwenbergh édition Marabout [Cou95].
La librairie auxiliaire permet la gestion des fenêtres, des événements, des entrées clavier et de la souris dans l'environnement graphique. Cette librairie est différente suivant le système d'exploitation: "AUX" sous WINDOWS NT et "GLX" sous X-WINDOW. Elle porte deux noms différents afin d'éviter toute confusion entre les deux environnements graphiques.
Les exigences de l'animation temps réel étant importantes, une étude approfondie du code d'OpenGL s'avère indispensable.
La recherche d’informations sur OpenGL à débouché sur l’étude de Mesa : une implémentation d’OpenGL du domaine public fournie avec les sources. Mesa 2.0 est une implémentation de Brian Paul du centre "Space Science and Engineering" de l'université du Wisconsin (http://sec.wisc.edu).
L'étude de Mesa a permis la compréhension du fonctionnement interne de la librairie graphique: elle a conduit une réécriture de certaines fonctions trop générales dans le cas qui nous intéresse. La simplification de ces fonctions s'est traduite par un gain de performances non négligeable.
En modélisation moléculaire, la forme la plus importante est la sphère et le cylindre qui permettent de représenter les atomes et leurs liens.
En infographie, une sphère parfaite n'existe pas : c'est une approximation plus ou moins fidèle de la sphère théorique. Plus l'approximation est fidèle, plus elle nécessite de triangles (ou rectangles) et elle demande donc plus de temps CPU. Il est donc important de trouver un compromis entre approximation et vitesse d'exécution.
La figure 1 est une meilleure approximation que la figure 2 mais elle sera environ deux fois plus longue à afficher que l'autre.
Une autre constatation peut être faite : si une forme bouge vite ou est loin de l'observateur, il est difficile de différencier les formes qui se ressemblent tel qu'un icosaèdre, un dodécagone ou même une sphère. Or ces premiers sont plus rapides à afficher que la sphère, nous les utiliserons donc dans les animations.
Partant de ces principes, nous pouvons créer des formes qui serviront à représenter les atomes; voici les deux formes proposées alliant un minimum de faces (triangle) et suggérant la sphère (en mouvement):
La première forme est un cube légèrement aplati avec deux pyramides écrasées sur la face supérieure et inférieure. Cette forme ne possède que seize triangles, soit 4 de plus qu'un cube (6*2 triangles). Le temps d'affichage de cette forme est très proche de celui d'un cube qui, avec le tétraèdre et l'octaèdre, est la forme régulière convexe la plus rapide à afficher.
La deuxième forme ressemble beaucoup à la première mais la partie supérieure du cube a pivoté de 45 °. Cette légère modification permet d'arrondir cette face en mouvement : par exemple si on la regarde du haut elle semble avoir huit sommets à sa périphérie.
Cette dernière ne possède que quatre triangles de plus que le cube pour un résultat satisfaisant pour une animation comportant beaucoup d'atomes.
Ces formes ne servent pas à remplacer la sphère dans les animations. Elles ont juste pour but la diminution du temps de calcul pour les sphères loin de l'observateur. En effet, si le rendu d'une sphère se résume à quelques pixels à l'écran, il est inutile de les dessiner avec une grande précision; cette précision n'aurait pour effet que de ralentir l'affichage.
Pour plus d'informations sur ces formes, référez-vous au listing de la librairie GL_PLUS en annexe (fonction a_sphere et xplus_sphere).
Comme expliqué plus haut , il existe trois grandes façons de représenter les surfaces : par des triangles, des quadrilatères ou des polygones. Ces différentes représentations ne diffèrent à l'écran que par leur vitesse d'affichage.
L'intérêt d'avoir plusieurs types de faces vient de la facilité de dessiner les surfaces : un cube est facile à dessiner avec des quadrilatères, un dodécagone avec des polygones, une pyramide avec des triangles... Ce sont les triangles qui offrent la plus grande rapidité. En fait, les quadrilatères et les polygones sont transformés, en interne, en triangles; cette transformation engendre du temps CPU.
Dans un souci d'optimisation, toutes les formes qui seront utilisées ont été transformées dans le code en triangles.
Bien que le nombre de faces et la forme des faces utilisées soient primordiales dans le temps d'affichage, l'agencement des faces a également son importance.
Il faut savoir que chaque série de faces en OpenGL doit être précédée d'un "glBegin" et terminée par un "glEnd" : le glBegin ayant pour effet de définir le type des faces qui vont suivre (triangles, quadrilatères , polygones, ...). Le "glEnd" a lui pour effet de transférer les faces d'un buffer de travail vers le z-buffer (voir glossaire). Cette opération est très coûteuse étant donné qu’elle est répétée à chaque série de faces. Pour minimiser le temps d'affichage, il faut minimiser le nombre de séries de faces. Voici ce qui est entendu par série de faces (cette représentation peut ne pas être coplanaire) :
Une série de triangles se définit en donnant les points de 1 à N. A l'exception des deux premiers points, tous les nouveaux points définissent une nouvelle face formée de ces points et des deux précédents.
Autrement dit :
" i = 2..n Þ i , i-1 et i-2 forme une face.
Ainsi graphiquement les séries de faces destinées à dessiner un cube donnent:
Toutes les formes utilisées dans la librairie et l'application ont été optimisées de cette manière : cette optimisation a eu pour effet de réduire d'environ 5 à 15 %, selon la forme, le temps d'affichage.
Voici à titre informatif la représentation planaire du dodécagone et de l'icosaèdre.
Dodécagone :
Pour plus d'informations sur l'implémentation du dodécagone, on pourra consulter le listing de la fonction "DODEC" du listing de "GL_PLUS."
Icosaèdre :
Pour plus d'informations sur l'implémentation de l'icosaèdre, on pourra consulter le listing de la fonction "ICO" du listing de "GL_PLUS."
Toutes ces formes ont également subi des optimisations au niveau du code C lui-même : tous les tests inutiles ont été éliminés, toutes les variables ont été remplacées par leur valeur et toute boucle a été étendue autant de fois que possible.
Pour une représentation très soignée de molécules, deux représentations standards coexistent :
Soit on représente les atomes par des sphères et les liens qui les unissent par leur chevauchement.
Cette façon de représenter a un inconvénient majeur : son aspect dense ne permet pas de voir tous les atomes, ce qui peut être gênant pour l'analyse des molécules.
La deuxième représentation est celle qui a été retenue : elle consiste à représenter les atomes par des sphères et les liens qui les unissent par des tubes .
Cette représentation permet d'éliminer en partie le problème de son homologue plus dense. Mais cette représentation n'a pas que des avantages : le dessin des liens consomme un temps des calcul non négligeable qui peut aller jusqu'à 50 % du temps total.
Afin d'éviter cette perte de performances, une première idée était de remplacer ces tubes par des droites, mais cette idée ne permettait pas de distinguer, dans les vues où juste les liens étaient présents, les molécules éloignées des molécules proches. La solution apportée a été de faire varier l'épaisseur des lignes en fonction de la distance entre les deux atomes liés et l'observateur.
Pour plus d'informations sur l'implémentation de cette représentation, on pourra consulter le listing des "Drawmolec" et "SetLineWidth" du listing "GL_PLUS".
OpenGL gère certaines fonctions inutiles pour le cas qui nous intéresse : la texturation, par exemple, ne présente aucun intérêt pour la représentation de molécules. Cependant, OpenGL dans ses fonctions de dessin de formes standards permet la texturation; la gestion de ce cas de figure diminue sensiblement les performances des formes sans textures.
Dans les fonctions de dessin de formes standards qui ont été réécrites , tous ces tests ont été éliminés ce qui a eu pour effet une diminution du temps de calcul d'environ 1%, ce qui peut paraître ridicule mais qui a son importance dans l'animation temps réel.
Pour plus d'informations sur ces fonctions de dessin, on pourra consulter le listing des fonctions "dodec", "cube", "a_sphere", "ico", "plus_sphere", "xplus_sphere", "plus_ico" et "Drawico" du listing "GL_PLUS".
Dans un souci de facilité d'utilisation des couleurs, une fonction à été implémentée afin de définir pour l'utilisateur quelques couleurs par défaut :
Cette fonction définit les couleurs gris, rouge, vert, bleu, cyan, magenta et jaune. Ces couleurs sont définies en couleurs unies (sans effets de lumière) dans la fonction "Ini_matérial" de la librairie "GL_PLUS" et sont définies avec effets de lumière et aspect plastique dans la fonction "Ini_material_light" de cette même librairie.
L'appel aux listes définissant les couleurs se fait sur base binaire d'un nombre compris entre 1 et 7 et la correspondance
idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
Nbr | Binaire | R | G | B | Couleur | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
1 | 001 | - | - | X | Bleu | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
2 | 010 | - | X | - | Vert | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
3 | 011 | - | X | X | Cyan | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
4 | 100 | X | - | - | Rouge | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
5 | 101 | X | - | X | Magenta | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
6 | 110 | X | X | - | Jaune | <#0>idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
7 | 111 | X | X | X | Gris | idth1idth3idth816idth3idth1248idth3idth766idth3idth766idth3idth766idth3idth1591
La demande initiale était un code permettant l’affichage de systèmes de molécules portable sur différentes plates-formes. Mais j’ai proposé la création d’une bibliothèque de fonctions plus large.
La bibliothèque créée est plus souple et son utilisation peut donc être étendue à toute application utilisant OpenGL : en plus des fonctions initialement demandées, elle permet la gestion de l’environnement OpenGL, elle comporte une série de formes régulières optimisées ainsi que quelques fonctions de gestion de la fenêtre, de définition de matériaux couramment utilisés, ...
Les spécifications qui vont suivre ne sont donc pas les spécifications initiales mais une extension de celles-ci en vue d’étendre l’utilisation de la librairie « GL_PLUS » à d’autres domaines.
Le but de la première partie du problème est la création d'une librairie de fonctions facilitant l'implémentation future d'applications permettant la visualisation de molécules en trois dimensions. Ces applications quant à elles serviront, par exemple, à la vérification de modèles mathématiques.
Cette librairie doit faciliter l'utilisation d'OpenGL dans les applications : faciliter l'initialisation de l'environnement OpenGL, faciliter la simulation temps réel des modèles et la gestion de la configuration de la vue en trois dimensions des molécules.
Elle doit pouvoir être utilisée sur le plus grand nombre de plates-formes différentes et doit pouvoir être appelée par le plus grand nombre de langages possibles.
La librairie doit être simple d'utilisation et proposer le choix entre différentes représentations : sphères et liens entre les atomes, sphères sans liens, uniquement les liens,... Chacune de ces représentations doit être optimisée pour une rapidité maximum.
Elle doit permettre l'animation en double buffering d'images de molécules créées à partir de points.
Enfin, cette librairie doit permettre une configuration interactive de l'angle de vue de l'animation.
L'aspect non statique et hétérogène du parc de machines et de systèmes d'exploitation du service demande une librairie indépendante de la machine et du système d'exploitation. La librairie doit pouvoir fonctionner dans les environnements graphiques WIINDOWS et X-WINDOW. Elle doit être indépendante de la plate-forme, du moins pour la compilation et pour autant qu'une implémentation des librairies OpenGL existe sur ces machines et systèmes d'exploitation.
Simplicité d'utilisation :
La librairie doit être simple d'utilisation : son utilisation ne doit pas demander de connaissances du langage OpenGL. Elle doit être utilisable par la plupart des langages de programmation.
Elle doit fournir une configuration d'OpenGL minimale pour son utilisation. La librairie doit pouvoir animer les images successives en double buffering, sans que le programmeur ne doivent se soucier de tous les problèmes qui en découlent : échange des buffers, scintillement,...
Pour l'animation, le programmeur doit pouvoir ne donner que les positions des atomes, accompagnées de données de configuration telles que : rayon, couleur, molécule à laquelle l'atome appartient, ... pour chaque image. L'affichage d'une image et la gestion des buffers d'affichage doivent se résumer à une fonction. Les appels successifs de cette fonction avec les données relatives pour chaque image doivent fournir l'animation.
Afin que le programmeur puisse calibrer le temps d'affichage des images, le choix des formes utilisées pour la représentation des atomes doit être indépendant d'une image à l'autre.
Enfin, la vue et la position de l'observateur doivent pouvoir être configurées lors de l'affichage de la première image et être maintenues jusqu'à la terminaison de l'animation. Cette configuration doit être automatique en fonction de la position des atomes et doit être modifiable interactivement lors de l'exécution du programme et non pas définie lors de l'implémentation.
Non restrictive.
Bien que le programmeur ne doive pas connaître OpenGL pour utiliser la librairie, cet aspect ne doit pas être restrictif. Le programmeur doit toujours pouvoir utiliser OpenGL simultanément avec la librairie : pour, par exemple, des configurations supplémentaires, définitions de ses propres couleurs, ...
L'utilisation de la librairie de fonctions doit être compatible avec les spécifications d'OpenGL en ce sens qu'elle ne doit pas restreindre l'utilisation de la librairie standard : elle ne doit pas rendre inutilisables certaines fonctions qui, dans ces conditions, sont autorisées par les spécifications du standard OpenGL.
Configuration de la vue interactive.
La librairie doit permettre une configuration de l'angle de vue et de la position de l'observateur de la scène.
Elle doit fournir une configuration par défaut en fonction de la disposition des molécules de l'image. Cette configuration doit pouvoir être modifiable interactivement lors de l'exécution de l'application.
L'angle de vue et la position de l'observateur doivent êtres configurés lors de la première image, lors du premier appel de la fonction d'affichage. Une fois cette configuration effectuée, elle doit rester fixée tout au long de l'animation sauf demande explicite insérée dans l'implémentation.
Pour terminer, la librairie doit rendre possible une reconfiguration de la vue et de la position de l'observateur. Cette reconfiguration, qui doit être explicitement demandée dans l'implémentation, doit pouvoir s'effectuer au milieu de l'animation.
Choix des formes et des matériaux.
L’appel des fonctions d’affichage doit permettre à l’utilisateur de choisir la forme servant à représenter un atome.
L’application doit fournir des matériaux de couleurs de base pour les atomes et leurs liens entre eux : elle doit fournir des matériaux de couleurs rouge, vert, bleu, gris, cyan, magenta jaune et gris.
La librairie doit pouvoir gérer le fait que les atomes peuvent avoir des tailles différentes : il doit être possible de définir la taille de chaque atome.
Le programmeur doit pouvoir choisir entre plusieurs formes pour l’affichage des atomes : aucune, cube, icosaèdre, dodécagone, sphère,... Toutes ces formes doivent être les plus rapides possibles : elles doivent être l’objet d’une optimisation pointue en vue de diminuer leur temps d’affichage. De plus, l’utilisateur doit pouvoir fournir sa propre représentation des atomes.
En plus du choix entre les formes, le programmeur doit pouvoir choisir d’afficher ou non les liens qui unissent les atomes pour former les molécules, et ce indépendamment du choix de la forme.
En vue de pouvoir configurer l’application en fonction des performances de la machine, le programmeur doit pouvoir définir toutes ces propriétés indépendamment d’une image à l’autre.
Compilable avec tous les langages.
Le langage de programmation de la librairie doit être un langage standard et portable.
L’implémentation de la librairie doit pouvoir être compilée sur différentes plates-formes telles que Windows et X-WINDOW.
Le comportement de la librairie ne doit pas être différent selon que l’on se trouve sur l’une ou l’autre des plates-formes.
La librairie doit pouvoir être appelée par la plupart des langages de programmation existants.
Les manuels à fournir.
La librairie doit être fournie avec un manuel pour le programmeur. Celui-ci doit comporter tous les détails de l’implémentation qui peuvent influencer l’utilisation de la librairie et un manuel d’explication technique sur son utilisation.
La librairie doit également être fournie avec un manuel utilisateur destiné aux utilisateurs des programmes implémentés avec cette librairie. Ce manuel doit expliquer principalement la configuration de la vue lors de la première image.
La création d'animations d'images de synthèse nécessite un langage graphique de haut niveau gérant la 3D, les effets de lumières et le double buffering. Deux possibilités se présentent : GL sur Silicon Graphics et OpenGL.
Pourquoi avoir préféré OpenGL à GL ?
Bien que GL soit plus puissant sur quelques points, par exemple au niveau des listes (appelées dans celles-ci objets), le choix s'est porté sur OpenGL.
En effet GL n'étant disponible que chez Silicon Graphics, la portabilité du langage n'est restreinte qu'à cette marque.
OpenGL quant à lui est une normalisation de son ancêtre GL, Il est disponible sous WINDOWS NT (en version bêta sous WINDOWS 95), LINUX et UNIX (SOLARIS,IRIX,AIX,...). En général, les fabricants de matériels fournissent les librairies optimisées pour leurs produits : c'est le cas de DIGITAL, IBM, SGI, SNI, INTERGRAPH, SUN, MIRO pour sa carte accélératrice MATROX MILLENIUM, ....
OpenGL s'étant imposé comme référence, il est livré avec la plupart des systèmes d'exploitation ou est disponible gratuitement sur Internet.
Dans un souci de portabilité maximum, la disponibilité d'OpenGL sur la plupart des plates-formes a été prédominante dans le choix du langage graphique utilisé.
La philosophie d'OpenGL est de fournir un langage graphique indépendant de la machine et du système d'exploitation. Pour ne pas restreindre le domaine d'application, la librairie "GL_PLUS" se doit de pouvoir fonctionner dans le même parc qu’OpenGl.
De plus, "GL_PLUS" a pour but de fournir une aide dans l'implémentation d'applications futures. Le parc de machines et de systèmes d'exploitation présent dans le service étant assez hétérogène, cette application n'a pas d'environnement privilégié. La librairie "GL_PLUS" devait donc pouvoir tourner sur toutes les plates-formes, étant bien entendu qu'une implémentation d'OpenGL existe pour cette plate-forme.
Suite à ces hypothèses, l'utilisation future de la librairie "GL_PLUS" passe par une implémentation compilable sur toute machine et tout système d'exploitation (moyennant configuration du fichier en-tête).
Pour les mêmes raisons que ci-dessus, une implémentation "CROSS-PLATEFORM" nécessite un langage ayant les mêmes propriétés.
La librairie graphique OpenGL n'étant pas utilisable par tous les langages, il paraît évident que le langage utilisé pour l'implémantation de la librairie "GL_PLUS" pourra en faire usage.
De plus cette librairie doit pouvoir être interfacée avec d'autres langages, il est donc important d'utiliser un langage standardisé qui puisse l'être.
Comme l'animation demande un maximum de rapidité pour des raisons de fluidité, il est important que le langage soit rapide.
Le C standard (ANSI C) étant un des seuls langages rapides, standardisé sur tout le parc de machines et de systèmes d'exploitation, qui puisse utiliser directement OpenGL et qui puisse être interfacé avec n'importe quel langage, l' ANSI C est apparu comme un choix évident.
Afin de garder un champ d'actions maximum, la librairie "GL_PLUS" doit pouvoir fonctionner dans le mode console d'un environnement graphique. En effet, l'expérience montre que des librairies en mode graphique du type MFC sous Windows ne peuvent pas toujours fonctionner en mode console. L'inverse par contre permet d'utiliser une librairie de mode console dans un mode graphique.
La librairie graphique OpenGL, et plus particulièrement sa librairie auxiliaire "GLAUX" permet la gestion d'une fenêtre graphique à partir du mode console. La gestion des éléments graphiques étant différente pour chaque système d'exploitation, cette fonctionnalité a permis de se décharger d'une grande partie de l'implémentation.
Ces raisons tendent à montrer que le mode console est le meilleur choix pour l'implémentation de la librairie "GL_PLUS".
Le but de la librairie étant de fournir une aide à l’implémentation d’applications pour la représentation de molécules, celle-ci doit être simple d’utilisation pour le programmeur.
L’idée générale est de permettre la représentation de molécules en n’utilisant que trois fonctions. Ces trois fonctions pourront être combinées avec le reste des fonctions de la librairie «GL_PLUS» pour obtenir des résultats plus spécifiques : ces trois fonctions sont une fonction d’initialisation de fenêtre et d’environnement OpenGL , une fonction de sélection du type de matériel; lumineux ou non, et une fonction d’affichage qui prend en charge la configuration de l’affichage, le double buffering, ...
La librairie est fournie avec d’autres fonctions qui permettent de simplifier l’utilisation d’OpenGL dans les programmes de représentation de molécules : elle contient des formes optimisées pour la représentation des atomes, des fonctions de gestion de la fenêtre, des fonctions de configuration d’OpenGL et des fonctions de dessin de molécules.
L’utilisation de la librairie n’apporte pas de contraintes quant à l’utilisation d’OpenGL et de ses librairies : elle permet l’utilisation transparente des API, d’OpenGL, de GLU et de GLAUX. La librairie est une librairie qui utilise ses quatre entités sans en diminuer le domaine d’action.
L’utilisation de la librairie ne restreint pas le domaine d’OpenGL, si ce n’est que la fonction d’initialisation crée une fenêtre OpenGL munie d’un «rendering context», ce qui restreint les affichages OpenGL à celui-ci, vu les spécifications d’OpenGL.
Les parties qui suivent tentent d’expliquer le fonctionnement de la librairie « GL_PLUS » : elles expliquent les algorithmes principaux et les fonctions utilisées. Les manuels permettent de comprendre l’utilisation de la librairie en vue de l’implémentation d’application.
La structure « atome » :
La structure « atome » est une structure destinée à représenter un atome, elle doit comporter des données quant à sa position dans l’espace, sa taille et sa couleur.
Voici la définition en C de la structure « atome » :
typedef struct tagatome
{
GLfloat x,y,z;
GLfloat r;
GLint index;
}ATOME;
Où : « x », « y » et « z » sont les coordonnées cartésiennes de la position du centre de l’atome, « r » est son rayon et « index » est le numéro de la couleur utilisée pour la représentation.
Cette structure est l’élément de base de la représentation.
Le passage en paramètres des molécules :
Les données passées aux fonctions d’affichage sont un tableau « d’atomes » , un autre qui permet de décomposer celui-ci en molécules, le nombre de molécules et le type de formes désirés.
Pour des raisons de performances, l’échange de données entre le programme et la librairie doit être minimisé. C’est pourquoi, seules les adresses des tableaux sont données à la fonction d’affichage.
Pour des raisons de compatibilité entre différents langages, le nombre de molécules et le type de formes sont aussi passés par adresses.
Pour ces mêmes raisons et pour une simplicité de programmation, tous les atomes de toutes les molécules sont transmis à la fonction par un seul tableau.
Le nombre de molécules permet de donner la taille du deuxième tableau qui permet la décomposition du premier en molécules : tous les atomes sont donnés les uns à la suite des autres, le deuxième tableau permet de les décomposer en molécules et le nombre de molécules permet de savoir le nombre d’entrées du deuxième tableau.
Voici un exemple :
Supposons que le nombre de molécules soit quatre et que le deuxième tableau soit 5,8,6,9:
ceci indique que la première molécule est composée des cinq premiers atomes du premier tableau, la deuxième est composée des huit atomes suivant,...
idth1idth3idth1440idth3idth207idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth207idth3idth208idth3idth208
atomes | ||||||||||||||||||||||||||||
idth1idth3idth1440idth3idth1037idth3idth1661idth3idth1245idth3idth18692ième tableau | 5 | 8 | 6 | 9 | <#0>idth1idth3idth1440idth3idth1037idth3idth1661idth3idth1245idth3idth1869||||||||||||||||||||||||
idth1idth3idth1440idth3idth5812Nombre de molécules | 4 | idth1idth3idth1440idth3idth5812|||||||||||||||||||||||||||
Pour plus d’informations sur l’utilisation de ces structures de données, le lecteur peut se référer aux explications sur l’algorithme d’affichage.
La définition des couleurs de base se fait de façon mnémotechnique : la numérotation associée est, si on ne regarde que les trois derniers bits, la représentation binaire des composantes de couleurs RGB présentes dans la couleur.
Ainsi la composante bleue sera présente si le dernier bit est positionné à un. De même que la composante verte sera présente si l’avant-dernier bit est positionné à un et la composante rouge, si l’antépénultième bit est positionné à un.
Voici un tableau explicatif des associations :
idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434
Numéro | Binaire | Rouge | Vert | Bleu | Couleur | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434
idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth14341 | 001 | X | Bleu | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434||
idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth14342 | 010 | X | Vert | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434||
3 | 011 | X | X | Cyan | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434|
4 | 100 | X | Rouge | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434||
5 | 101 | X | X | Magenta | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434|
6 | 110 | X | X | Jaune | <#0>idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434|
idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth14347 | 111 | X | X | X | Gris | idth1idth3idth1354idth3idth1248idth3idth1208idth3idth941idth3idth981idth3idth1434
Deux configurations de couleurs sont possibles : l’utilisation de la librairie peut se faire en mode couleur normal ou en mode couleur utilisant les effets de lumières. Ces deux modes utilisent la même numérotation. Ces deux modes sont disponibles car l’utilisation de la lumière diminue les performances des algorithmes c’est pourquoi deux fonctions d’initialisation sont données : « Ini_material » pour les couleurs n’utilisant pas la lumière et « Ini_material_light » pour les couleurs utilisant la lumière.
Ces fonctions d’initialisation créent des listes OpenGL qui peuvent être modifiées par l’utilisateur de la librairie si celui-ci veut définir ses propres couleurs. Il peut également créer ses propres couleurs en définissant de nouvelles listes dont le numéro est différent et associer à l’atome le champ «index » correspondant.
Le type d’affichage de la scène est défini par le paramètre type des fonctions d’affichage .
Le programmeur peut choisir, par exemple, si les liens qui unissent les atomes doivent être ou non affichés. Il peut également choisir la forme qui va représenter les atomes : cube, icosaèdre, dodécagone, sphère,... et ce pour toute l’image. Il peut faire varier cet affichage d’image en image afin d’obtenir le résultat qu’il escompte.
Un seul paramètre suffit pour définir le type de représentation :
Si le type est supérieur ou égal à zéro, cela implique que les liens entre les atomes seront affichés.
La valeur absolue du type permet de sélectionner la forme destinée à représenter les atomes.
Afin de faciliter l’utilisation des mnémoniques permettant de représenter les formes, voici un tableau donnant un aperçu des formes prédéfinies :
idth1idth3idth2047idth3idth2970
Mnémonique. | Forme associée. | <#0>idth1idth3idth2047idth3idth2970
idth1idth3idth2047idth3idth2970CUBE. | Cube. | <#0>idth1idth3idth2047idth3idth2970
ICOS. | Icosaèdre. | <#0>idth1idth3idth2047idth3idth2970
DODE. | Dodécagone. | <#0>idth1idth3idth2047idth3idth2970
SPHE. | Sphère. | <#0>idth1idth3idth2047idth3idth2970
idth1idth3idth2047idth3idth2970USER. | Forme définie par l’utilisateur | idth1idth3idth2047idth3idth2970
Voici quelques exemples de types et leur résultat :
idth1idth3idth1261idth3idth2250idth3idth1194
Type. | Forme. | Liens. | <#0>idth1idth3idth1261idth3idth2250idth3idth1194
idth1idth3idth1261idth3idth2250idth3idth1194CUBE | Cube. | OUI. | <#0>idth1idth3idth1261idth3idth2250idth3idth1194
-ICOS. | Icosaèdre. | NON. | <#0>idth1idth3idth1261idth3idth2250idth3idth1194
DODE. | Dodécagone. | OUI. | <#0>idth1idth3idth1261idth3idth2250idth3idth1194
idth1idth3idth1261idth3idth2250idth3idth1194SPHE. | Sphère. | OUI. | idth1idth3idth1261idth3idth2250idth3idth1194
Représentation en utilisant le style de forme « CUBE ».
Représentation en utilisant le style de forme « - ICOS ».
Représentation en utilisant le style de forme « DODE ».
Représentation en utilisant le style de forme « SPHE ».
La mnémonique « USER » :
La constante « User » permet à l’utilisateur de créer dans une liste OpenGL sa propre forme avec sa propre couleur.
Si la forme associée aux atomes est « USER », le champ Index de l’atome donne le numéro d’index de la liste OpenGL, définie auparavant par l’utilisateur. Ce champ étant utilisé généralement pour la couleur, la liste OpenGL créée par le programmeur devra comporter des primitives de couleurs. Si l’utilisateur n’utilise pas de primitives OpenGL à cet effet, la couleur de l’atome précédent sera utilisée.
La hiérarchisation de la scène permet le positionnement de la caméra : la caméra étant plus haute que tous les objets dessinés, toutes les transformations se répercutent sur ceux-ci.
Le « ViewPort » et les lumières sont définis une fois pour toute.
La caméra, elle, est définie lors de la configuration et est stockée dans des tableaux contenant les transformations dans des variables locales à la librairie. Ces transformations sont appliquées pour chaque image juste avant d’afficher les entités graphiques.
Voici un tableau qui montre la hiérarchisation de la scène :
Les flèches montrent les domaines d’influences des transformations appliquées dans les entités.
Cette séparation de la caméra et des objets permet de modifier la caméra lors de la première image. Ce qui permet une configuration de l’angle de vue.
La fonction d’affichage des molécules est de conception assez simple : elle parcourt la totalité du tableau deux fois ; une fois pour afficher les atomes et une fois pour les relier.
Pour relier les atomes, l’algorithme parcourt le tableau en reliant les points sauf si l’atome courant est le dernier de la molécule.
Voici l’algorithme d’affichage :
Où,
« a_count[i] » est le nombre d’atomes dans la molécule numéro i.
« a[C] » est l’atome numéro C.
« Type » type de l’affichage »
Pour faciliter la compréhension, l’algorithme ne comporte pas les parties se référant à la largeur de la ligne en fonction de la position relative à la caméra.. Il ne contient pas non plus les actions utilisées uniquement pour la configuration de la première image.
Effacement du buffer d’affichage
Sauvegarde de la matrice de transformation
Positionnement de la caméra
C=0
Si affichage des lignes alors (Type >= 0)
Pour j allant de 0 à nombre de molécules
Définition de la couleur associée à a[C]
« Relier les points qui suivent »
Positionner a[C]
C=C+1
Pour i allant de 1 à a_count[j]
x=(a[C-1].x+a[C].x)/2;
y=(a[k-1].y+a[k].y)/2;
z=(a[k-1].z+a[k].z)/2;
Définition de la couleur associée à a[C]
Positionner a[C]
C=C+1
Fin pour
« fin relier les points qui suivent »
Fin pour
Fin Si
Si « type contient des formes pour les atomes » alors
C=0
Pour j allant de 0 à nombre de molécules
Pour i allant de 0 à a_count[j]
Si le rayon >0 alors
Sauvegarde de la matrice de transformation
Translation vers a[C]
Définition de la couleur associée à a[C]
Selon le type appeler la fonction d’affichage associée
Restauration de la matrice de transformation précédente
Fin Si
C=C+1
Fin Pour
Fin Pour
Fin Si
Restauration de la matrice de transformation précédente
Copie du buffer vers la fenêtre
Explications supplémentaires :
La sauvegarde et la restauration de la matrice de transformation se fait via une pile « first in first out ».
La copie du buffer vers la fenêtre se fait lors de la remontée du rayon de l’écran en vue d’éviter, tant que possible, le scintillement.
« Relier les points qui suivent » : c’est une fonctionnalité d’OpenGL . Après cette commande, tous les points positionnés sont reliés au précédent s‘il existe et ce jusqu’à la demande explicite de terminaison de cette commande.
Pour plus d’informations sur cette fonction, , on pourra consulter le listing de la fonction « drawmolec2 » du listing de la librairie « GL_PLUS ».
La configuration de la vue se fait lors de la première image. L’appel à cette fonction est transparent pour le programmeur : en effet son appel se fait via une fonction d’interface « DrawMolec » qui appelle soit la fonction d’affichage standard « DrawMolec2 », soit la fonction de configuration si c’est la première image. Rien n’empêche le programmeur de rappeler la fonction de configuration « ConfigView », avec les mêmes paramètres que la fonction standard, afin de reconfigurer la vue en cours d’animation.
La fonction de configuration de la vue a pour but essentiel d’initialiser les transformations appliquées à la caméra. Ces transformations seront appliquées sur chaque image qui suit la configuration et ce jusqu’à la fin de l’animation ou jusqu’à un nouvel appel à la fonction de configuration.
Voici l’algorithme de configuration de la vue :
Initialisation de la console
ready=0;
todraw=1;
Parcours de tous les atomes afin de définir une sphère comprenant tous les atomes.
mid = « Position du centre de cette sphère »
tmp = « Rayon de cette sphère »
Initialisation des translations (x, y et z) de la caméra a –mid (point de référence sur le centre)
Initialisation des angles de rotation de la caméra à 0
Affichage dans la console des touches de configuration.
Lire un caractère au vol à la console.
Tant que la touche "STOP_CONFIG" n'est pas pressée
Si todraw <> 0 alors
Afficher la scène dans la fenêtre (+ axe de configuration)
todraw=0;
Fin si
Modification des transformations selon la touche pressée
(si une touche est pressée todraw=1)
Lire un caractère au vol à la console.
Fin tant que
num_image=1;
Explications supplémentaires :
L’initialisation de la console se fait de façon différente selon que la librairie est utilisée dans l’environnement Windows ou X-WINDOW : cette partie contient des directives de compilation (#ifdef,....) qui permettent de choisir l’environnement désiré.
Parcours de tous les atomes afin de définir une sphère comprenant tous les atomes : l’idée générale est d’englober la scène dans une sphère afin de pouvoir placer la caméra pour avoir une vue globale de la scène.
A chaque touche de configuration, définie comme constante dans le fichier « GL_PLUS.H », est associée une modification des transformation de la caméra. Ces touches sont affichées dans la console lors de l’exécution du programme pour que l’utilisateur puisse visualiser les touches utiles et leur fonction.
Pour plus d’informations sur cette fonction, référez-vous au listing de « GL_PLUS » à la fonction « ConfigView ».
La librairie à été implémentée pour pouvoir tourner sur différentes plates-formes : la seule différence quant à l’utilisation de celle-ci est la présence ou non de la ligne «#define WINNT » dans le fichier « GL_PLUS.H ».
Cette directive de compilation permet de sélectionner dans les différentes fonctions les fonctions non-portables utilisées : ces fonctions sont des fonctions présentes, par exemple, dans des librairies standards différentes ou spécifiques à l’environnement.
Le comportement de la librairie est invariable d’une plate-forme à l’autre.
Pour plus d’informations, référez-vous au listing de la librairie « GL_PLUS ».
La définition des fonctions qui suivent est donnée sous forme de prototype C .
Les fonctions de configuration :
GLenum inigl(char *titre,GLint *x1,GLint *y1,GLint *x2, GLint *y2) :
Cette fonction est la fonction d’initialisation de l’environnement OpenGL et de la fenêtre de dessin.
Elle ouvre une fenêtre OpenGL et initialise la librairie avec une configuration par défaut.
Les paramètres sont :
Titre : le titre affiché dans la fenêtre.
X1 et Y1 : est la position (x,y) du coin supérieur gauche de la fenêtre OpenGL.
X2 et Y2 : est la position (x,y) du coin inférieur droit de la fenêtre OpenGL.
GLvoid CALLBACK resize( GLsizei width, GLsizei height ) :
Cette fonction est une fonction qui permet de reconfigurer OpenGL lorsque la fenêtre a été redimensionnée. Son format est un format utilisable par la librairie auxiliaire.
Ses paramètres sont :
Width : la largeur de la fenêtre qui à été redimensionnée.
Height : la hauteur de la fenêtre qui à été redimensionnée.
void ini_material() :
Cette fonction permet l’initialisation des matériaux de base comme expliqué plus haut : cette fonction correspond aux couleurs ne tenant pas compte de la lumière.
Elle n’utilise aucun paramètre.
void ini_material_light() :
Cette fonction permet l’initialisation des matériaux de base comme expliqué plus haut : cette fonction correspond aux couleurs tenant compte de la lumière.
Elle n’utilise aucun paramètre.
GLvoid defmat(GLuint Index,GLfloat Ambient[],GLfloat Diffuse[],GLfloat Specular[]) :
Cette fonction permet la création de nouveaux matériaux tenant compte de la lumière.
Elle crée une liste OpenGL qui définit le matériel.
Ses paramètres sont :
Index : le numéro d’index qui sera affecté à la nouvelle liste OpenGL.
Ambient : un tableau de quatre « Glfloat » définissant les composantes RGBA des propriétés du matériel à la couleur ambiante.
Diffuse : un tableau de quatre « Glfloat » définissant les composantes RGBA des propriétés du matériel à la couleur diffuse.
Specular: un tableau de quatre « Glfloat » définissant les composantes RGBA des propriétés du matériel à la couleur spéculaire.
void plus_enable(GLint type) :
Cette fonction encapsule la fonction OpenGL glEnable, elle active les propriétés.
Elle permet la définition de toutes les propriétés OpenGL et permet d’activer la propriété de ligne de largeur variant avec la distance à la caméra.
Son paramètre est un mnémonique qui peut être un de ceux utilisés par glEnable ou LINE_EYE.
void plus_disable(GLint type) :
Cette fonction encapsule la fonction OpenGL glDisable, elle active les propriétés.
Elle permet l’annulation de la définition de toutes les propriétés OpenGL et permet de desactiver la propriété de ligne de largeur variant avec la distance à la caméra.
Son paramètre est un mnémonique qui peut être un de ceux utilisés par glDisable ou LINE_EYE.
void setlinewidth(float x,float y,float z,float base) :
Le fonction « setlinewidth » permet de changer la largeur de la ligne en fonction d’une position : on donne la position de la ligne et la largeur de référence et elle redimensionne la largeur de ligne.
Attention : la largeur une fois modifiée reste la valeur courante de largeur de lignes.
Ses paramètres sont :
X, Y et Z : la position du point milieu de la ligne qui sert à calculer la largeur de la ligne.
Base : la largeur de référence des lignes.
Les fonctions d’affichage :
void drawaxe(GLfloat size) :
Cette fonction permet d’afficher les axes de repères de l’espace à trois dimensions.
L’affichage des axes se fait sur la position courante (0,0,0) qui est sujette aux transformations antérieures.
La couleur des axes permet de reconnaître les axes :
Rouge = X
Vert = Y
Bleu = Z
les couleurs citées ci-dessus sont les couleurs de base, si les listes OpenGL des couleurs de base ont été modifiées, les couleurs des axes le seront également.
Le paramètre est la taille des axes.
void drawmolec(ATOME a[],GLint a_count[],GLint *m_count,GLint *type) :
La fonction « drawmolec » est la fonction à appeler pour l’affichage des molécules.
C’est une fonction d’interface entre le programme principal et la librairie .
Lors du premier appel à la fonction, elle appelle la fonction de configuration de la vue « configview » et lors des appels suivants, elle appelle la fonction d’affichage des molécules « drawmolec2 ».
Ses paramètres sont ceux expliqués dans la description de l’algorithme d’affichage.
void configview(ATOME a[],GLint a_count[],GLint m_count,GLint type) :
Cette fonction est la fonction de configuration de la vue : elle permet de positionner la caméra.
Pour plus d’informations sur celle-ci, référez-vous à la description de la configuration de la vue.
Ses paramètres sont ceux expliqués dans la description de l’algorithme d’affichage.
void drawmolec2(ATOME a[],GLint a_count[],GLint m_count,GLint type) :
Cette fonction est la fonction d’affichage des molécules : elle permet d’afficher les molécules de différentes façons.
Pour plus d’informations référez-vous à la description de l’algorithme d’affichage des images.
Ses paramètres sont ceux expliqués dans la description de l’algorithme d’affichage.
void drawico(GLfloat size) :
« Drawico » est une fonction qui permet le dessin d’un icosaèdre de taille arbitraire.
L’affichage de l’icosaèdre se fait sur la position courante (0,0,0) qui est sujette aux transformations antérieures.
Son paramètre est la taille de l’icosaèdre : cette taille est fonction des primitives OpenGL de dilatation (glScale).
Les fonctions de création de formes :
Ces formes sont des formes qui peuvent être utilisées pour représenter un atome : elles sont toutes inclues dans une sphère et ont une vitesse d’affichage différente qui est fonction de la complexité de la forme. Cette complexité est fonction du nombre de triangulations nécessaires à leur affichage.
Toutes ces formes ont fait l’objet d’une optimisation exhaustive en vue d’accroître leur performance d’affichage.
Sauf contre-indications, les fonctions qui suivent créent une liste OpenGL dont le numéro est passé en paramètre.
void dodec(GLint index) :
Cette fonction permet de créer une liste OpenGL qui affiche un dodécagone de taille unitaire.
void cube(GLint index) :
Cette fonction permet de créer une liste OpenGL qui affiche un cube de taille unitaire.
void ico(GLint index) :
Cette fonction permet de créer une liste OpenGL qui affiche un icosaèdre de taille unitaire.
void sphere(GLint index,GLint slice) :
Cette fonction permet de créer une liste OpenGL qui affiche une approximation de sphère de taille unitaire.
Cette sphère est construite à l’aide de la librairie « GLU ».
Son paramètre supplémentaire est le nombre de longitudes et latitudes utilisées pour l’approximation de la sphère.
La figure 1 montre une approximation de sphère avec le paramètre « slice » égal à 30 et la figure 2 avec « slice » égal à 15.
void plus_sphere(GLint index,GLint slice) :
Cette fonction permet de créer une liste OpenGL qui affiche une approximation de sphère de taille unitaire.
Cette sphère est construite sur base de l’algorithme du code « Mesa 2.0 » de création de sphère.
Son paramètre supplémentaire est le nombre de longitudes et latitudes utilisées pour l’approximation de la sphère. (figure 1 et 2)
« Mesa 2.0 » est une implémentation du domaine public des librairies d’OpenGL due à Paul Brian du service « space science and Engeneering » de l’université du Wisconsin ( http:// www.ssec.wisc.edu)
void xplus_sphere(GLint index,GLint slice) :
Cette fonction permet de créer une liste OpenGL qui affiche une approximation de sphère de taille unitaire.
Cette sphère est construite en explicitant toutes les triangulations de l’approximation de la sphère.
Son paramètre supplémentaire n’est pas utilisé.
void a_sphere(GLint index) :
Cette fonction permet de créer une liste OpenGL qui affiche une forme qui est un cube dont les faces supérieures et inférieures sont remplacées par des pyramides.
Voici une représentation de cette forme :
void plus_ico(GLint index) :
Cette fonction permet de créer une liste OpenGL qui affiche une forme qui est un cube dont les faces supérieures et inférieures sont remplacées par des pyramides. De plus la partie supérieure de la forme a subi une rotation autour de l’axe des Z de 45°.
Voici une représentation de cette forme :
Pour le programmeur.
Les explications qui vont suivre se réfèrent aux explications données dans les paragraphes qui précèdent :
Pour plus d’informations sur les points qui suivent, , on pourra se référer à ces explications et aux commentaires présents dans le listing de la librairie « GL_PLUS ».
Vous trouverez un exemple complet d’implémentation dans l’annexe « molécule ».
Initialisation de l’animation :
L’initialisation de l’animation se fait en deux phases : une première pour initialiser l’environnement OpenGL et la fenêtre et la deuxième phase afin de définir le type de luminosité de la scène.
Voici le code C pour initialiser l’environnement OpenGL ( fenêtre avec titre « molécule » et coin supérieur gauche en (a,a) et coin inférieur droit en (b,b) ) et définir le type de matériel lumineux.
inigl("Molecule",&a,&a,&b,&b);
ini_material_light();
L’initialisation de l’environnement OpenGL et de la fenêtre se fait par l’appel de la fonction « IniGL » avec comme paramètre la position de la fenêtre et son titre.
L’appel a cette fonction a pour effet de créer une fenêtre dans laquelle la scène sera dessinée.
Cet appel définit également les paramètres par défaut de la librairie OpenGL , ceux ci sont :
La couleur de fond noire.
Un affichage en double buffers.
Lissage des formes des couleurs.
Les paramètres de la perspective et de projection de la scène dans la fenêtre.
Une lumière en position (2,2,2) de propriété standard (RGBA):
Ambiante : {0.7, 0.5, 0.5, 1.0}.
Diffuse : {0.8, 0.8, 0.8, 1.0}.
Spéculaire : {0.9, 0.9, 0.9, 1.0}.
De plus cet appel définit les paramètres par défaut de la librairie « GL_PLUS » : des lignes de largeur variable en fonction de sa position par rapport à la caméra.
La deuxième phase quant à elle permet de choisir le type des matériaux : des matériaux tenant compte ou non de la luminosité en appelant respectivement les fonctions « Ini_material_light » ou Ini_material ».
Une fois ces deux phases effectuées, le programmeur peut effectuer des modifications sur ces paramètres par défaut en utilisant soit des primitives OpenGL, soit des fonctions de configurations de « GL_PLUS ».
Exemple d’implémentation en C :
Cet exemple montre comment créer une fenêtre OpenGL de titre « visualisation » dont la position du coin supérieur gauche est (0,10) et le coin inférieur droit est (150,300). Cet exemple initialise également les matériaux tenant compte de la lumière.
x1= 0;
y1= 10;
x2= 150;
y2= 300;
inigl(« visualisation »,&x1,&y1,&x2,&y2) ;
ini_matérial_light() ;
.....
L’animation d’images composées de molécules :
L’animation des molécules se fait par l’appel de la fonction « Drawmolec ».
L’appel à cette fonction doit se faire après l’initialisation de l’environnement OpenGL : si le programmeur appelle directement la fonction d’affichage des molécules, rien ne se passe.
Les données passées en paramètres à la fonction se font par adresses : le format de ces données est expliqué plus en détail dans les paragraphes qui précèdent.
Quatre paramètres sont donnés à la fonction .
L’adresse d’un tableau contenant tous les atomes.
L’adresse d’un tableau contenant la configuration des molécules.
L’adresse d’un entier donnant le nombre de molécules total de la scène.
L’adresse d’un entier donnant le type de représentation souhaitée.
L’animation se fait par appels successifs à la fonction « Drawmolec » en donnant les molécules composant les images à afficher.
Cette animation se fait en deux phases, une phase de configuration de la vue et l’animation proprement dite.
La configuration de la vue s’effectue lors du premier appel à la fonction d’affichage.
Lors du premier appel à la fonction d’affichage, le contrôle de l’application est donné à l’utilisateur. Celui-ci peut interagir avec la vue en positionnant la caméra afin d’obtenir l’angle de vue désiré. Il peut zoomer, déplacer la caméra ou le point de référence dans toutes les directions et faire tourner la caméra autour du point de référence dans toutes les directions. Pour effectuer ces modifications, l’utilisateur est aidé par un système d’axe placé sur le point de référence et par l’affichage dans la console de toutes les touches de configuration et de leur correspondant clavier. L’utilisateur rend le contrôle lorsqu’il presse la touche « STOP CONFIG ». La configuration de la scène laisse alors place à l’animation proprement dite.
La deuxième phase est l’animation proprement dite : chaque nouvel appel de cette fonction d’affichage donne lieu à une nouvelle image. Cette animation garde la configuration de la vue .
Si le programmeur ne veut pas de la configuration interactive, Il peut faire abstraction de cette configuration de la vue en appelant non plus la fonction d’affichage « DrawMolec » mais la fonction « DrawMolec2 » qui permet l’animation de la scène avec les paramètres de transformations par défaut de la caméra.
Exemple d’implémentation : voir annexe molécule.
Reconfiguration :
Le programmeur peut permettre de reconfigurer la scène. Si la fonction d’affichage « Drawmolec » est remplacée par la fonction « ConfigView », le processus de reconfiguration de la vue est exécuté à nouveau.
Les modifications apportées à la vue restent d’application pour le reste de l’animation (jusqu’à la nouvelle configuration de la vue ).
Le programmeur peut également reconfigurer les types de matériaux : s’il décide de passer à une scène tenant compte de la lumière, il peut appeler la fonction de définition des matériaux «lumineux » ou inversément passer à des matériaux ne tenant plus compte de la lumière. Il peut également définir en cours d’animation ses propres matériaux.
De plus, le programmeur peut décider de choisir des représentations de lignes différentes : passer de lignes de largeur fixe à des lignes de largeur dépendant de la distance à la caméra, et inversément.
Enfin, le programmeur peut insérer toutes les configurations propres à OpenGL qu’il désire : brouillard, textures, agrandissement de la fenêtre,...
Définition de formes personnelles :
Si le programmeur veut représenter les atomes par des formes personnelles, il peut créer des listes OpenGL composant ces formes. Pour pouvoir utiliser ces formes, le programmeur doit donner en paramètre le type de représentation «USER » : ce type de représentation a pour effet de considérer le champ «index » des atomes comme numéro de la forme utilisée pour les représenter.
Le programmeur doit donc donner comme champ «index » de chaque atome le numéro d’index de la liste OpenGL définissant la forme de celui-ci.
Ce champ étant généralement utilisé pour la couleur de l’objet, le programmeur doit définir la couleur dans la liste OpenGL définissant la forme. Si l’utilisateur omet de définir la couleur de la forme, la librairie utilisera la couleur précédemment utilisée, c’est à dire : la couleur de l‘atome précédent.
Cette fonctionnalité est très puissante car, par formes personnelles, on entend listes OpenGL. Ces listes permettent non seulement de définir des formes et des couleurs mais elles permettent également toutes sortes de configurations et options d’affichage permises par OpenGL. Ces listes peuvent par exemple servir à définir une seconde source lumineuse.
En prenant un atome non plus comme un objet mais comme un élément de dessin, il est possible d’animer ce que l’on veut : par exemple, le premier atome peut être la lumière, le deuxième un personnage, le troisième une maison, le quatrième peut être les transformations appliquées au cinquième et ainsi de suite. De sorte que la librairie peut afficher n'importe quelle animation.
Pour l'utilisateur.
La librairie « GL_PLUS » comportant une fonction de configuration interactive de la vue, il est nécessaire d’informer celui-ci de l’utilisation de cette configuration.
Cette configuration est assez simple d’utilisation mais doit quand même être expliquée.
Interface utilisateur:
La configuration interactive de la vue a un fonctionnement assez simple : l’utilisateur peut modifier en pressant les touches la position de la caméra et du point de repère (point fixé par la caméra).
La correspondance des touches est affichée dans la console : chaque ligne correspond à une transformation.
Voici le schéma d’une ligne :
COMMANDE : ‘Touche associée’
Voici la liste des commandes disponibles et leur effet:
UP : effectue une rotation de la caméra vers le haut.
DOWN : effectue une rotation de la caméra vers le bas.
LEFT : effectue une rotation de la caméra vers la gauche.
RIGHT : effectue une rotation de la caméra vers la droite.
ZOOM_OUT : éloigne la caméra du point de référence.
ZOOM_IN : rapproche la caméra du point de référence.
X_MOINS : déplace le point de référence dans la direction des X négatifs.
X_PLUS : déplace le point de référence dans la direction des X positifs.
Y_MOINS : déplace le point de référence dans la direction des Y négatifs.
Y_PLUS : déplace le point de référence dans la direction des Y positifs.
Z_MOINS : déplace le point de référence dans la direction des Z négatifs.
Z_PLUS : déplace le point de référence dans la direction des Z positifs.
STOP_CONFIG : arrête la configuration et permet la suite du programme.
L’application a pour but la visualisation de molécules afin d’étudier les matériaux au niveau atomique en temps réel. Elle doit permettre la création interactive des images d’un film à partir de fichiers points.
L’application doit gérer la vue dans une multitude d’atomes qui, vue de loin, paraîtrait incompréhensible : l’utilisateur doit pouvoir choisir interactivement où se trouve la caméra qui filme la scène et le point que celle-ci fixe. La caméra doit pouvoir être attachée à un atome et le rester dans le reste de l’animation, le point fixé par celle-ci doit également pouvoir être attaché à un atome pour une période donnée de l’animation.
De plus, l’application doit permettre à l’utilisateur de se positionner dans les images du film et de pouvoir effectuer des modifications sur celles-ci et les suivantes si nécessaire.
Le programme doit permettre de choisir interactivement la représentation des molécules : les formes qui définissent les atomes, leur taille et l’épaisseur des liens entre les atomes et ce pour toute l’animation.
Enfin l’application doit fournir, dans des fichiers images, une représentation plus fine de la scène dans un but de présentation. Ces images doivent pouvoir être transformées en film par une autre application.
Présentation graphique :
L’application doit être implémentée dans un environnement graphique : elle doit se présenter dans deux fenêtres, une fenêtre de visualisation de la scène et une contenant toutes les commandes.
La fenêtre de commandes doit contenir toutes les commandes. Elle doit présenter les commandes par groupe de commandes qui agissent sur le même domaine : un domaine pour la présentation des formes, un pour le positionnement de la caméra, un pour la navigation dans les images et un plus général pour toutes les commandes de lecture dans les fichiers, écriture dans les fichiers et sortie du logiciel.
La fenêtre de visualisation doit être séparée de la fenêtre de commandes : elle doit fournir un aperçu de ce que donnera les fichiers images. Elle doit être redimensionnnable et déplaçable indépendamment de la fenêtre de commandes.
Configuration de la caméra :
L’utilisateur doit pouvoir choisir, par sélection avec la souris, un atome ; l’atome auquel la caméra sera attachée durant le reste de l’animation : l’application doit permettre d’attacher la caméra à un atome pour le reste de la série d’images et pouvoir éventuellement la rattacher plus loin dans la série sur un autre atome.
Le changement de position de la caméra doit pouvoir se faire de façon instantanée en une image ou le changement doit pouvoir s’étaler sur plusieurs images en vue d’éviter les coupures de la séquence d’animation en plan discontinu.
La caméra attachée à un atome doit rester attachée à celui-ci durant tout le film ou le reste du film si elle a été attachée au milieu du film. Si ce n’est que l’utilisateur peut demander de libérer la caméra ; celle-ci doit, alors, rester sur la même position durant tout le reste de l’animation, sans se soucier de la position des atomes et molécules.
Une caméra attachée ou non à un atome doit pouvoir à n’importe quel moment de l’animation être attachée à n’importe quel atome.
Toutes ces spécifications sur la position de la caméra sont valables pour le point fixé par celle-ci : le point de référence doit également pouvoir être attaché et libéré à n’importe quel moment de la série d’images et le rester jusqu’à la fin de l’animation, sauf modification des images suivantes.
Il est évident qu’une modification peut ne pas avoir l’effet attendu. Afin d’éviter ces effets indésirables, toute modification de la position de la caméra ou du point de repère doit pouvoir être annulée.
Choix de la représentation :
L’utilisateur doit pouvoir choisir manuellement la représentation des molécules que ce soit pour des raisons de performances de l’ordinateur ou que ce soit pour des raisons esthétiques.
L’application doit permettre la définition de la taille des formes, que ce soit des formes qui représentent les atomes ou que ce soit les liens qui les unissent en molécules.
L’interface doit permettre, de façon simple, le choix entre différentes formes de représentation des atomes : cube, icosaèdre, dodécagone, sphère ou aucune pour augmenter la fluidité de l’animation.
Navigation dans les images du film :
L’application doit permettre à l’utilisateur de se positionner sur n’importe quelle image du film d’animation et pouvoir modifier celle-ci. Lorsque l’utilisateur se positionne sur une image il doit pouvoir visualiser l’image avec la configuration de caméra de cette image.
L’utilisateur doit pouvoir visualiser l’animation. Cette fonctionnalité doit lancer l’animation à partir de la première image jusqu’à la dernière et revenir sur l’image où l’utilisateur se trouvait avant le lancement de l’animation.
L’utilisateur doit également avoir la possibilité de lancer l’animation à partir de la position courante du film et ce jusqu’à la fin et revenir sur cette position de départ.
L’application doit permettre de stopper l’animation en cours. Cette fonctionnalité doit pouvoir positionner la position courante du film sur n’importe quelle position. L’utilisateur doit donc pouvoir arrêter l’animation et se positionner sur une image.
Les fichiers d’entrée et de sortie :
L’application doit pouvoir gérer deux types de fichiers : un type de fichier en entrée et un en sortie.
Les fichiers d’entrée :
Les fichiers d’entrée contiennent les points relatifs à chaque atome.
Les lignes des fichiers d’entrée sont de deux formats différents : soit la position X, Y et Z de l’atome, soit une ligne vide (ne comportant que le retour chariot) qui représente la fin d’une série d’atomes appartenant à la même molécule et le commencement éventuel de la suivante.
Exemple :
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth2246
Position X | Position Y | Position Z | Couleur optionnelle | |
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth22463.25 | 2.57 | 2.63 | 1 | Molécule numéro N | <#0>idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth2246
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth22464.325 | 3.587 | 9.54 | 7 | |
2.17 | 8.002 | 16.89754 | 6 | |
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth2246 | ||||
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth22467.2 | 6.59 | 15.33658 | 6 | Molécule numéro N+1 | <#0>idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth2246
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth22462.65 | 1.98765 | 9.54 | 3 | |
idth1idth3idth1447idth3idth1447idth3idth1502idth3idth1615idth3idth2246... | ... | ... | ... |
Les fichiers peuvent ou non contenir le quatrième élément dans la ligne. Si le quatrième élément représentant la couleur est absent, l’application doit pouvoir en affecter une par défaut aux atomes.
L’application doit pouvoir, à partir de ces fichiers, construire les atomes et les molécules : il doit pouvoir reconstituer celles-ci en fonction de la configuration du premier fichier.
Le programme doit pouvoir enfin vérifier si le format du fichier est correct.
Les fichiers de sortie :
L’application doit pouvoir fournir des fichiers images dans un format de fichier standard : les images stockées dans ces fichiers doivent contenir une représentation plus esthétique, plus précise que la fenêtre de visualisation.
Les fichiers de sortie doivent être dans un format courant qu’il est possible de récupérer avec la plupart des applications de conversions d’images.
Enfin, ces fichiers d’images doivent pouvoir être assemblés pour former un film : ces fichiers doivent être triés par leur nom pour qu’une application de conversion de fichiers images en film puissent reconnaître l’ordre chronologique des images.
Les matériaux :
L’application doit fournir des matériaux de couleurs de base pour les atomes et leurs liens entre eux : elle doit fournir des matériaux de couleur rouge, vert, bleu, gris, cyan, magenta jaune et gris.
Si les fichiers d’entrée comportent des codes de couleurs, l’application doit pouvoir affecter les matériaux de couleurs correspondant aux atomes.
Si les fichiers d’entrée ne comportent pas de codes de couleurs, le programme doit pouvoir en affecter par défaut.
Gestion des erreurs :
L’application doit tre sécurisée au point de vue des erreurs courantes : telles que disque remplis, protection en écritures,...
L'application n'étant pas destinée à tourner sur plusieurs plates-formes, les contraintes de portabilité s'en sont réduites considérablement. Cette diminution des contraintes a permis de choisir un système d'exploitation et un langage particulier.
Les programmes tels que « 3D Studio© » ou autres sont des programmes de modélisation et de rendu d’images de synthèse. Toutefois, ils ne permettent pas une animation temps réel de film : par exemple « 3D Studio Max © » ne permet d’afficher en temps réel qu’approximativement une trentaine de sphères ou cent cinquante cubes (avec un rendu de « Gouraud »). Ces logiciels sont mieux adaptés à l’animation différée qu’à l’animation temps réel.
Ces types de programmes ne permettent pas d’obtenir une visualisation des molécules à partir des fichiers points : ces fichiers ont en effet leur propre format et ne sont pas compatibles avec les formats reconnus par ce type de logiciel. Il faudrait pour cela créer un convertisseur de fichiers.
Enfin, la complexité de l’interface de ces applications (due à leur aspect général) en font des outils peu adéquats dans le cas qui nous intéresse.
La création d’une application spécifique permet de lire ces fichiers points directement, de réduire l’interface au besoin et permet surtout d’animer en temps réel beaucoup plus de formes.
Les contraintes de portabilités ont été réduites par rapport à "GL_PLUS", mais ne sont pas pour autant absentes.
Le choix s'est tourné vers Microsoft Windows NT un système d'exploitation existant sur différentes machines.
Ce système d'exploitation permet d'utiliser les applications sur différentes machines, même d'architecture différente, sans recompilation du code.
Microsoft Windows NT 4.0 est fourni en standard avec la version 3.1 des librairies d'OpenGL.
Pour toutes ces raisons, Microsoft Windows NT 4.0 s'est avéré le système le plus avantageux pour l'implémentation de l'application "MOLEVIEW".
Suite au choix du système d'exploitation, le choix du langage s'est focalisé sur un langage adapté à celui-ci. Le choix s'est porté sur Microsoft Visual C++ 4.0 , un langage du même constructeur que le système d'exploitation bien adapté à ce type d'application. Microsoft Visual C++ permet par ses classes prédéfinies, les MFC, une utilisation aisée des API Windows. De plus, ces MFC gèrent une grande partie des erreurs courantes telles que disque plein,.... Ce qui permet au programmeur un gain de temps considérable.
Ce studio de développement permet une création visuelle des objets graphiques comme les boutons, les fenêtres, les boîtes de dialogue,... Ce qui permet un gain non négligeable de temps lors de la création de l'interface. En plus de la création, il permet une gestion simple de ces objets et du code relatif à leurs événements.
Enfin, ce langage est fourni en standard avec le kit de développement OpenGL comportant une aide détaillée sur l'utilisation d'OpenGL et de sa portabilité.
Le format des fichiers de sauvegarde n'a pas beaucoup d'importance. Mis à part que le format doit être assez répandu pour trouver des applications permettant de les visualiser.
Le choix s'est donc porté sur le format de fichier d'images le plus simple : le format "PPM". Le temps gagné par ce choix autorise de se concentrer sur d'autres aspects tels que l'optimisation, l'interface,...
Le but de l'application est de créer des films d'animations en images de synthèse, le service possède un convertisseur de fichiers "PPM" vers des fichiers "MPEG" (film)[Cat95], Le choix du format de fichiers "PPM" évite la création de fichiers de films avec toutes les difficultés que cela comporte : timing, couleurs, compression,...
Le but de cette implémentation est de fournir un éditeur de film. Cet éditeur lit des données « point » dans des fichiers, permet de gérer le positionnement de la caméra tout au long des images, de modifier celui-ci, de visualiser le résultat de ce positionnement et enfin de créer les images qui serviront à la création du film par un autre programme qui compacte les images en un film.
Cette application travaille sur plusieurs mécanismes d’animations : l’animation des atomes fonctionne sur base de scripts, ceux-ci ont été créés par un mécanisme d’animation contrôlé par la dynamique moléculaire. Par contre, la caméra utilise une combinaison de trois types de mécanismes : un mécanisme de liens hiérarchiques, par trajectoires et par clef d’interpolation.
La caméra est une caméra « intelligente qui se positionne en un point et en fixe un autre.
Les classes créées.
Contrairement à l’implémentation de la librairie «GL_PLUS» précédemment expliquée, l’application « MoleView » a été réalisée en Visual C++ 4.0 utilisant la programmation orientée objet. Les objets y sont nommés «classes».
La description des classes qui va suivre permet la compréhension du fonctionnement du programme. Dans un premier point, vous trouverez une brève description des classes, leur fonction au sein du programme ainsi que la justification de leur création.
Dans le second point, vous trouverez des explications complémentaires sur les classes composant la classe «FILM» : cette partie donne des informations plus précises sur sa structure et les raisons de celle-ci.
Pour plus d’informations sur ces classes, référez-vous à la documentation de Visual C++ 4.0 ( [Lon95] et [MVC96] ) et aux listings de l’application « MoleView ».
Brèves descriptions des classes.
La classe «CMoleViewApp»:
La classe «CMoleViewApp» est une classe dérivée de la classe standard «CWinApp» : Cette classe est un objet «application » obligatoire.
La classe «CMoleViewApp» ne sert qu’à vérifier si la résolution de l’écran permet l’utilisation du programme (plus de 256 couleurs) et lance l’interface principale «CMoleViewDlg» si tel est le cas.
La classe «CMoleViewDlg»:
La classe «CMoleViewDlg » est une classe dérivée de la classe standard «CDialog » qui constitue l’interface principale du programme : elle comporte tous les contrôles du programme.
Cette classe maîtresse lance et gère toutes les autres : elle est composée de tous les contrôles, elle gère les paramètres courants de l’application et le lancement de toutes les procédures d’interactions avec l’utilisateur.
Cette interface principale contrôle le déroulement de l’application, gère la navigation dans le film, l’initialisation des autres classes, l’édition du film, la configuration de la représentation et toutes les interactions entre l’utilisateur et le film.
Pour plus d’informations sur cette classe, référez-vous à la description de l’interface principale.
La classe «ATOME»:
L’objet « ATOME » comme son nom l’indique est une classe destinée à contenir un atome. Cette classe n’est dérivée d’aucune classe standard. Elle est constituée de la position et de la couleur de l’atome qu’elle représente.
Elle ne contient pas de fonctions de dessin de cet atome pour des raisons de performances. L’affichage des atomes est regroupés dans une seule fonction, ce qui permet d’économiser le temps gaspillé dans les appels répétés de fonctions.
La classe «AUXWIN»:
Cette classe est dérivée d’une «CDialog » : c’est la fenêtre de visualisation. Elle regroupe toutes les fonctions OpenGL utilisées dans l’application.
Le fait que cette classe soit dérivée d’une classe «CDialog» permet de se libérer de la gestion de la fenêtre. La seule fonction de gestion de fenêtre qui a dû être réécrite est celle d’affichage.
La classe «AUXWIN » gère tout ce qui est visualisation .
Elle contient toutes les fonctions d’initialisation de l’environnement OpenGL : définition de la perspective, double buffering, mode RGBA,...
Elle contient également toutes les données nécessaires à l’affichage de la scène : taille de la fenêtre de visualisation, couleurs, lumières,...
Enfin, elle contient les fonctions d’animation temps réel, de rendu des images finales, de positionnement de la caméra, de sélection des atomes,...
Le fait que cette fonction contienne toutes les fonctions OpenGL permet de changer de langage graphique sans trop de modifications : en effet seule la réécriture de cette classe est nécessaire.
La classe «CFG»:
La classe «CFG» est une classe qui est destinée à contenir toutes les informations nécessaires au positionnement de la caméra dans une image.
Elle permet de savoir, entre autre, à quel atome la caméra ou le point de référence est attaché. Si la caméra (ou le point de référence) n’est pas attaché, elle permet de connaître sa position.
Cette classe est utilisée dans la classe «IMAGE » et la classe «UNDO».
La classe «COpenFile»:
Cette classe est une boîte de dialogue qui permet la sélection des fichiers « points » pour l’animation : elle permet de naviguer dans les répertoires et les disques durs, de sélectionner des fichiers « points » ainsi que leur type (contenant des informations sur la couleur des atomes ou non).
Cette boîte de dialogue, lorsque la sélection a été effectuée, contient une variable membre (un tableau) contenant tous les fichiers et le chemin d’accès à ceux-ci.
La classe «CfileDlg» ne permet pas de sélectionner plus de 256 noms de fichiers, C’est pourquoi la création de cette classe s’est avérée nécessaire.
La classe «CSaveDlg»:
C’est une boîte de dialogue qui permet de choisir le répertoire vers lequel les fichiers «PPM» seront sauvés.
Cette boîte de dialogue permet également de définir la taille des images de sortie, ce que ne permet pas la classe standard «CfileDlg».
La classe «FILE_SKEL»:
La classe «FILE_SKEL» est une classe destinée à recevoir le format des images : les atomes par molécule, leur nombre, la liste des fichiers, s’ils contiennent les couleurs ou non,...
Elle contient également une fonction qui permet l’initialisation en fonction d’un nom de fichier : ouverture et analyse du format.
Cet objet contient une fonction qui permet de s’initialiser à partir d’un autre objet «FILE_SKEL».
Enfin, Elle contient une fonction qui lance la classe «COpenFile» qui permet de demander le nom des fichiers «points » à l’utilisateur.
Cette classe est une classe qui permet d’initialiser un «FILM» et de garder les informations minimales pour son initialisation : cette fonctionnalité est intéressante lorsque l’utilisateur change de fichiers de données. Si ces nouveaux fichiers sont incorrects, l’application peur restaurer l’animation précédente.
La classe «FILM»:
La classe « FILM » contient toutes les informations et fonctions appliquées au film. Elle est constituée d’images et du format de ces images.
Elle contient également une fonction d’initialisation de la position de la caméra par défaut.
Enfin, elle possède une fonction qui permet d’initialiser le «FILM» à partir d’une classe «FILE_SKEL».
La classe «IMAGE»:
La classe «IMAGE» est une classe qui contient tous les atomes d’une image ainsi que la configuration de la caméra pour cette image.
Elle possède deux fonctions membres :
«FillFromFile» qui permet de remplir une image à partir d’un fichier de points et «GetMinMax» qui permet de donner les minimum et maximum des positions dans chaque direction.
Cette dernière est utilisée pour la configuration par défaut de la position de la caméra.
La classe «UNDO»:
La classe «UNDO» est destinée à conserver la configuration du film en vue d’une annulation de la dernière modification.
Elle contient la configuration de la caméra de chaque image et le numéro de l’image courante.
Cette classe est utilisée par l’interface principale qui peut y stocker la configuration d’un film et la restaurer si l’utilisateur en fait la demande.
La Classe «WaitDlg»:
Cette classe est une classe qui n’a qu’un but esthétique : c’est une classe qui permet à l’utilisateur de visualiser l’état d’avancement d’une tâche qui prend un certain temps.
Cette boite de dialogue possède une barre de progression afin de visualisé cet avancement. Elle possède également une icône animée qui permet de voir que l’application n’est pas arrêtée et tourne toujours : cette icône est animée à chaque appel à une de ses fonctions membres.
Enfin cette interface permet à l’utilisateur, si il clique sur un bouton, de signaler un « USER_ABORD » à la procédure appelante.
La classe «FILM» et les classes qui la composent.
Cette partie est destinée à expliquer le comment et le pourquoi de la structure de la classe «FILM». En effet, la structure de cette classe peut paraître étrange : pourquoi la classe ne comporte-t-elle pas de fonctions d’affichage des images, des atomes ? Pourquoi n’y a-t-il pas d’objet «molécule » ?...
Les explications qui vont suivre répondent à ces questions.
Nous allons voir plus en détail sa structure et les raisons pour lesquelles cette structure s’est avérée la plus adéquate.
Voici la structure de la classe «FILM» :
FILM
INT[] (nombre d’atomes)
INT (nombre de molecules)
IMAGE[]
CFG Positionnement de la caméra
ATOME[]
Notations :
Un indentation indique que la classe est une classe membre.
Les « [] » indiquent que c’est un tableau d’objet.
Les noms en majuscules indiquent le type de la classe, la suite ce que représente la classe.
Cette représentation ne tient pas compte des fonctions membres dans le but de ne pas encombrer la représentation.
Voici de façon plus formelle la définition des classes :
L’idée générale de la structure du «FILM» est qu’un film est composé d’un ensemble d’images. Une image est composée d’un ensemble d’atomes et d’un positionnement de caméra.
Voici la définition de ces concepts en classes.
La classe «CFG» :
La classe «CFG» modélise la caméra, plus précisément, le positionnement de la caméra et le positionnement du point qu’elle fixe.
Voici sa définition :
class CFG
{
double Ref_x,Ref_y,Ref_z; position du point de référence si celui-ci n’est pas attaché.
double Eye_x,Eye_y,Eye_z; position de la caméra si celle-ci n’est pas attachée.
int Ref_fix ;si le point de référence est attaché (numéro de l’atome) ou non (-1).
int Eye_fix; si la caméra est attachée (numéro de l’atome) ou non (-1).
};
La classe «ATOME» :
La classe «ATOME» contient toutes les informations nécessaires sur un atome : sa position (x,y,z) et le numéro de sa couleur.
Voici sa définition :
class ATOME
{
float x,y,z;
int index;
};
La classe «IMAGE» :
La classe «IMAGE» est une classe qui regroupe tous les atomes (tableau d’atomes) d’une même image ainsi que la configuration de la caméra et de son point de repère.
Voici sa définition :
class IMAGE
{
CFG Repère;
CArray <ATOME,ATOME> atome;
};
Cette classe comporte deux fonctions : une pour remplir l’image à partir d’un fichier de points et l’autre qui renvoie les positions maximales et minimales dans chacune des directions.
La classe «FILM» :
La classe «FILM» modélise le film, Elle comporte toutes les images ainsi que la configuration de celles-ci. Le format d’une image est le nombre de molécules qui la compose et le nombre d’atomes pour chacune de celles-ci.
Voici sa définition :
class FILM
{
int nbr_mole;
CArray <int,int> nbr_atome;
CArray <IMAGE,IMAGE> image;
};
Cette classe comporte deux fonctions :
La première (IniFromSkel) permet d’initialiser le film à partir d’un squelette contenant le format et le nom des fichiers qui la compose.
La deuxième fonction (SetDefaultRepere) permet de positionner la caméra par défaut.
Un film est composé d’un ensemble d’images. Une image est composée d’un ensemble d’atomes et d’un positionnement de caméra.
Mais le film comporte les informations invariantes sur les images : le format de l’image. Ce format est composé du nombre de molécules et pour chacune de ces molécules le nombre d’atomes qui la composent.
Pour les mêmes raisons, le positionnement de la caméra et du point de repère de celle-ci est stocké dans l’image. En effet, ce stockage des informations invariantes permet d’économiser de la place mémoire : ces informations ne sont plus stockées qu’une seule fois.
Pourquoi les classes «ATOME », «IMAGE » et «FILM » ne comportent-elles pas de fonction d’affichage ?
Suivant les principes de la programmation orientée objet, chacune de ces classes devrait comporter sa propre fonction d’affichage. Mais le besoin de rapidité de l’animation temps réel est en contradiction avec cette structuration. En effet, pour chaque atome l’application stricte des principes de l’orienté objet impliquerait un appel de fonction. Il faut savoir qu’un appel de fonction coûte du temps CPU, qui peut paraître dérisoire pour un atome mais devient vite sensible lorsque l’image comporte quelques centaines d’atomes.
Si chaque atome pénalise l’animation d’un appel de fonction, la rapidité et donc la fluidité de celle-ci en serait diminuée.
Une seconde raison de l’absence de fonction d’affichage dans chaque objet est que toutes les fonctions OpenGL ont été regroupées en un seul objet : la classe «AUXWIN». Ce regroupement des fonctions OpenGL permet de changer assez aisément de langage graphique. Si une librairie graphique optimisée et plus performante dans le domaine de l’application apparaissait, la modification de l’application serait assez simple : elle consisterait en une réécriture de la classe «AUXWIN».
Pourquoi la classe «CFG » ne comporte-elle pas de fonction de positionnement ?
Pour la même raison que précédemment, le positionnement de la caméra se fait à l’aide de primitives OpenGL . Celles-ci sont regroupées en une seule classe ce qui permet de changer, sans trop de modifications, de langage graphique.
Pourquoi n’y a-t-il pas de classe « molécule » ?
La présence d’une classe molécule aurait pu éviter de conserver dans la classe «FILM» le format de l’image, mais le positionnement de la caméra et du point de repère se fait sur un atome.
La sélection avec la librairie OpenGL se fait en mettant sur une pile le numéro de chaque objet dessiné. Dans le cas présent chaque atome possède un numéro (son numéro d’index dans l’image).
La sélection avec la librairie OpenGL se fait en mettant sur une pile le numéro de chaque objet dessiné. Dans le cas présent, chaque atome possède un numéro (son numéro d’index dans le tableau de l’image), ce qui simplifie énormément le processus de sélection. En effet dans le cas où un objet molécule serait défini, l’algorithme de sélection devrait placer, pour chaque atome, le numéro de la molécule ainsi que son numéro à l’intérieur de la molécule, ce qui peut engendrer un dépassement de pile. Une autre solution serait de garder la même numérotation d’atomes pour l’algorithme et de rechercher dans les molécules l’atome qui lui correspond : ce processus s’avère peu performant.
Une seconde raison à cette absence est le besoin de performance : si les atomes étaient regroupés en molécules, l’algorithme d’affichage devrait pour chacune de celle-ci effectuer une déréférenciation supplémentaire qui s’avère coûteuse lorsque le nombre de molécules excède la centaine.
Pourquoi la classe «FILE_SKEL » existe-t-elle ?
Deux raisons ont entraîné la création de cette classe :
La première raison est que cet objet gère tout ce qui est interface utilisateur pour la sélection d’une série de fichiers et que cet objet contient tous les noms des fichiers points. Ce qui permet de ne pas encombrer l’objet film de cet interface utilisateur. En effet, celle-ci n’a aucune raison logique de figurer dans un objet «FILM».
Mais la raison la plus importante est que, lorsque l’utilisateur sélectionne une deuxième série de fichiers points, l’utilisation d’un deuxième «FILE_SKEL» est utile si cette deuxième série s’avère inutilisable car cette classe permet la vérification du format des fichiers. Si cette classe, ou une autre équivalente, n’existait pas, l’application serait incapable de restaurer l’animation précédente à moins de créer un deuxième objet film, ce qui pourrait saturer la mémoire.
Description de l'interface principale.
Description générale :
Une utilisation aisée de l’application, impose que l’interface utilisateur soit simple, compréhensible et fonctionnelle. Voici le résultat de la prise en compte de ces facteurs :
La simplification de l’interface principale s’est surtout traduite par une automatisation des tâches qui découlent d’un événement. Ainsi les fonctions telles que la restauration de l’ancienne animation si la nouvelle est inutilisable est automatique; si l’utilisateur effectue une modification qui influence la visualisation, celle-ci est mise à jour; si les itérations pour le changement de position de la caméra dépasse la fin du film, celles-ci sont modifiées automatiquement,...
La simplicité passe également par une restriction du champ d’action de l’utilisateur : si, par exemple, une action n’a aucun effet, celle-ci doit être inutilisable. Ainsi si l’utilisateur ne sélectionne aucune forme, l’interface doit sélectionner les lignes,... Cette restriction du champ d’action de l’utilisateur a pour effet de diminuer la complexité de l’interface en diminuant le nombre d’interactions possibles.
Si deux actions différentes ont la même utilité, il n’est pas nécessaire de compliquer l’interface en affichant deux boutons : par exemple, « attacher la caméra » est la même chose que « attacher le point de référence », ces actions se font par sélection d’un atome. Il suffit donc d’un seul bouton « attacher » qui attache soit la caméra soit le point de référence en fonction de ce qui est choisi dans l’interface (caméra ou point de référence). Ce raisonnement peut également être appliqué à la libération et à la sélection du nombre d’itérations pour réaliser la transition de position de la caméra et du point de référence.
L’utilisation de longues explications sur le fonctionnement d’un bouton nuit à la compréhension de l’interface. De plus, l’espace disponible sur un bouton n’est pas toujours suffisant pour expliquer la fonctionnalité qui se cache derrière ce bouton. Un icône peut souvent remplacer une longue explication : par exemple, « lancer l’animation à partir du début » peut être remplacé par un icône. De plus le côté intuitif d’un icône peut aider l’utilisateur dans la compréhension de l’interface.
Voici la liste des icônes utilisés dans l’interface principale et leur signification :
Quitter le programme.
Sélection des fichiers points pour l’animation.
Sélection de la caméra.
Sélection du point de repère.
Attacher le point de référence ou la caméra.
Libérer le point de référence ou la caméra.
Annuler la dernière modification.
Enregistrer l’animation dans les fichiers.
Lancer l’animation.
Lancer l’animation depuis la première image.
L’aspect fonctionnel de l’interface est surtout axé sur sa présentation. L’interface est découpée en groupes d’actions similaires ou qui agissent sur le même concept.
Voici la description des groupes :
Groupe des fonctions de contrôle : ce groupe contient les fonctionnalités sortie de l’application et ouverture d’une nouvelle série de fichiers points. C’est l’équivalent du menu « fichier » dans les applications standards sous Windows.
Groupe des fonctionnalités se rapportant aux molécules : ce groupe contient les fonctionnalités de sélection de la forme, des lignes et des tailles de ces deux dernières.
Groupe des fonctionnalités se rapportant à la vue: il contient les fonctionnalités de sélection de la caméra et du point de référence, d’attachement et de libération de ces deux dernières, le nombres d’itérations pour effectuer les mouvements et l’annulation de la dernière modification.
Groupe qui contient toutes les fonctionnalités sur les images de l’animation : ce groupe contient les boutons pour le lancement de l’animation, pour la création des fichiers images et une barre de défilement pour la navigation à travers les images.
Les fonctions standards de gestion de fenêtres qui ont été réécrites :
Les fonctions qui vont suivre sont les fonctions standards des classes « MFC » utilisées lors de la programmation de l’application.
Dans tous les cas, la fonction réécrite appelle la fonction par défaut et ensuite effectue les opérations supplémentaires engendrées par l’application. Cette partie ne fait état que de ces opérations supplémentaires.
OnInitDialog :
Cette fonction est appelée lors de l’initialisation d’une boite de dialogue, elle a été réécrite pour permettre l’initialisation de la fenêtre de visualisation, de son environnement OpenGL, des données, de l’interface et de la fonctionnalité UNDO.
OnActivate:
La fonction « OnActivate » est appelée lorsqu’un événement qui change l’activation de
la fenêtre se produit. L’interface principale et la fenêtre de visualisation étant fortement liées, cette fonction active les deux fenêtres simultanément.
OnPaint() :
Cette fonction est appelée chaque fois que l’interface doit être redessinée : chevauchement de fenêtres, activations, ... Du fait que la fenêtre et l’interface principale sont fortement liées, lorsque l’une a besoin d’être dessinée, l’autre également.
Cette fonction redessine l’image courante de l’explication dans la fenêtre de visualisation.
Les fonctions associées aux boutons :
Le terme « bouton » est pris au sens large, il désigne un bouton, une barre de défilement, un bouton de sélection, ou tout autre élément d’interface.
L’appel de ces fonctions s’effectue à chaque interaction de l’utilisateur avec les composants de l’interface.
Ces fonctions appellent la fonction standard du « bouton » et effectuent les opérations supplémentaires dues à l’application.
OnNone(), OnCube(), OnIco(), OnDodec(), OnSphere() et OnLine() :
Toutes ces fonctions sont associées aux boutons de sélection du groupe comportant toutes les actions sur les molécules. Elles permettent de sélectionner le type d’affichage : cube, icosaèdre, lien,...
Toutes ces fonctions sont regroupées en un seul point car leur fonctionnement est similaire .
Elle définit la forme, met à jour l’interface, recalcule les tailles et affiche l’image courante avec les nouveaux paramètres d’affichage.
OnVScroll() :
Cette fonction est appelée lorsque l’utilisateur interagit avec une barre de défilement vertical. Dans notre interface, les barres de défilement vertical sont essentiellement utilisées pour modifier des valeurs de paramètres encadrés par deux valeurs : les tailles et la longueur de la transition pour les mouvements de caméra.
Pour les tailles, la fonction teste la validité de la valeur, met à jour les tailles et réaffiche l’image courante avec les nouveaux paramètres.
Pour la longueur de la transition de la caméra, la fonction teste la validité de la valeur et met à jour une variable contenant cette longueur.
OnStepAttach() :
Cette fonction est appelée chaque fois que l’utilisateur sélectionne ou désélectionne le mode de transition itératif de la caméra : elle teste la validité de la longueur de la transition, met à jour l’interface et un flag utilisé pour le mouvement de caméra.
OnAttach() et OnFree():
Ces fonctions sont appelées chaque fois que l’utilisateur veut attacher la caméra ou le point de référence à un atome ou le libérer d’un atome.
Leur fonctionnement est similaire .
Elle détermine si c’est sur le positionnement du point de référence qu’il faut agir.
Elle sauvegarde la configuration pour la fonctionnalité UNDO et appelle la fonction qui permet l’action désirée.
OnUndo() :
Cette fonction est appelée chaque fois que l’utilisateur demande une annulation de la dernière modification : cette fonction appelle la fonction de restauration.
OnFile() :
La fonction « OnFile » donne à l’utilisateur la possibilité de sélectionner une série de fichiers points pour l’animation.
Cette fonction ouvre l’interface de sélection des fichiers points.
Si des fichiers ont été sélectionnés, elle initialise l’animation et l’interface.
Si aucun fichier n’a été sélectionné ou si ces derniers sont inutilisables, la fonction restaure l’ancienne animation.
Ensuite, elle réaffiche l’image courante.
L’algorithme de lecture des fichiers points est expliqué plus longuement dans le point « description des principaux algorithmes ».
OnHScroll() :
Cette fonction gère la barre de positionnement dans le film, ce « Slider » permet de naviguer à travers les images. Elle est appelée chaque fois que l’utilisateur interagit sur cette barre de défilement horizontal.
Cette fonction prend la position de la barre de défilement et affiche l’image correspondante.
OnPlay() et OnPLAYAll():
Ces deux fonctions ont la même fonctionnalité : le démarrage de l’animation.
Elles déterminent le point de départ de l’animation et son point d’arrivée, image courante jusque dernière ou première et dernière image.
Ensuite, elles lancent l’animation avec ces paramètres.
Et enfin, si l’utilisateur n’a pas interrompu l’animation, elles restaurent la position courante du film et réaffichent l’image correspondante.
OnMake() :
Cette fonction est appelée chaque fois que l’utilisateur demande la création des images précises sur disque.
Cette fonction lance l’interface de sauvegarde, récolte les informations de celle-ci, initialise l’environnement OpenGL pour la récupération du rendu, lance la création du film avec les paramètres récoltés et restaure l’environnement initial.
Les fonctions internes à l’interface :
Ces fonction sont internes à l’interface, l’utilisateur n’y a pas directement accès.
InitGLWindow() :
La fonction « IniGLWindow » permet l’initialisation de la fenêtre de visualisation.
Elle crée la fenêtre, initialise sa taille par défaut, ses paramètres de perspectives, la taille des objets par défaut, place la caméra et lie cette fenêtre à l’interface principale.
AssignControl() :
Cette fonction assigne les contrôles : elle affecte à chacun d’eux l’icône qui lui correspond.
En plus de cet aspect esthétique, elle initialise les pointeurs qui permettent leur gestion.
SetDefaultControl() :
Cette fonction permet de configurer l’interface principale. Elle fixe l’interface par défaut : les formes, le type de sélection, les tailles des formes, et le positionnement dans le film.
InitData() :
Cette fonction permet d’initialiser le film .
Elle effectue, à peu de chose prêt, les actions de la fonction interface « OnFile » mais quitte l’application si les fichiers sont inutilisables.(en donnant à l’utilisateur des informations sur les raisons de l’invalidité des fichiers).
IniSlider() :
Cette fonction permet l’initialisation de la barre de défilement horizontal servant à la navigation dans le film.
Elle fixe les bornes du « Slider » en fonction du nombre d’images du film, elle initialise ses sauts d’un dixième du nombre d’images vers la gauche et la droite.
Enfin, cette fonction positionne la barre de défilement sur la position correspondante à l’image courante.
IniUndo() :
Cette fonction permet l’initialisation de la classe « UNDO » en fonction de l’animation.
Elle fixe la taille de l’objet pour contenir toutes les configurations de l’animation courante et sauvegarde la configuration du film.
LineSize() et FormeSize();
Ces fonctions sont destinées a mettre en concordance les tailles et l’interface principale.
Leur fonctionnement est similaire : elles transforment les valeurs contenues dans l’interface en unité de taille pour le dessin. C’est à dire qu’elles convertissent les valeurs entre 0 et 100 en taille d’atomes ou de largeur de lignes.
SetSTEP() :
Cette fonction permet la vérification du nombre d’itérations pour les mouvements de caméra.
Elle ajuste la longueur de la transition pour que celle-ci ne dépasse pas la taille du film et permet de rectifier cette longueur pour que l’application de la transition, à partir de la position courante, ne dépasse pas la fin du film.
SetImg() :
Cette fonction permet de changer l’image courante.
Elle change le numéro de l’image courante, repositionne la barre de navigation sur cette image et modifie la zone de texte indiquant l’image courante.
StoreUndo() et RestoreUndo() :
Ces deux fonctions sont complémentaires, elles permettent de sauvegarder et de restaurer la configuration de la vue d’un film.
Elles activent et désactivent le bouton permettant le UNDO respectivement si elles sauvegardent ou restaurent la configuration.
AttachRef() et AttachCam();
Ces deux fonctions ont le même rôle mais appliqué à des concepts différents : elles attachent la caméra ou le point de référence sur un atome. Leur fonctionnement est similaire mais appliqué à l’une ou à l’autre.
Ces fonctions appellent la fonction de sélection de la fenêtre de visualisation et récupèrent, si c’est le cas, l’atome qui à été sélectionné.
Ensuite elles mettent à jour la configuration de la caméra (ou du point de référence) des images qui suivent : attachée ou non et sa position
Pour ce faire, elles effectuent ou non les mouvements de caméra par itération.
L’algorithme de sélection d’un atome est expliqué plus longuement dans le point « description des principaux algorithmes ».
PlaceView();
Cette fonction permet d’initialiser la vue pour la représentation de l’image.
Elle applique le même raisonnement pour la caméra et pour le point de référence .
Si l’élément est attaché à un atome, alors elle le positionne sur la position de cet atome.
Par contre, s’il n’est pas attaché, elle le positionne à la position stockée dans la configuration.
Cette fonction est appelée avant tout affichage.
L’algorithme d’affichage d’une image est expliqué plus longuement dans le point « description des principaux algorithmes ».
DrawImage() et PaintChild() :
La fonction d’affichage d’une image « DrawImage » permet d’afficher une image dont le numéro est passé en paramètre. La fonction « DrawChild », quant à elle, permet d’afficher dans la fenêtre de visualisation (child) l’image courante.
L’affichage d’une image se fait en trois phases .
On teste si le numéro de l’image est valide [0, nombre d’images du film].
On configure la vue (PlaceView).
Et on appelle la fonction d’affichage de la fenêtre de visualisation pour l’image à afficher.
PlayFilm() :
La fonction « PlayFim » permet de lancer l’animation.
Cette fonction reçoit deux paramètres : le numéro de l’image de départ et le numéro de l’image de fin.
Dans un premier temps, elle positionne la fenêtre de visualisation en avant-plan de l’interface.
Ensuite, avant d’afficher chaque image, elle teste si l’utilisateur n’interrompt pas l’animation : si ce n’est pas le cas elle affiche l’image en positionnant l’image courante (SetImg) et quand l’animation est terminée, elle repositionne l’image courante sur l’image de départ.
Si par contre l’utilisateur a interrompu l’animation, elle repositionne l’image courante à l’endroit de l’interruption.
MakeAniFile() :
Cette fonction est similaire à la fonction « PlayFim » à la différence près que les images sont plus précises et sont sauvées dans un fichier.
Tout comme la fonction « PlayFim » elle parcourt les images en testant si l’utilisateur n’interrompt pas le processus. Mais à la différence de « PlayFim », elle affiche la boîte de dialogue indiquant la progression, positionne la vue, affiche avec précision l’image, la copie dans la fenêtre de visualisation et sauve celle-ci dans un fichier sur disque (SavePpmNo).
SavePpmNo();
Cette dernière fonction permet de sauver un « bitmap » passé en paramètre sur disque dans un fichier « PPM » qui porte un nom qui indique son numéro d’ordre.
Cette fonction crée en premier lieu le nom du fichier.
Ensuite elle crée le fichier sur disque, sauve dans celui-ci le bitmap passé en paramètre (dans le format PPM) et ferme ce fichier.
L’algorithme de cette fonction est expliqué plus longuement dans le point « description des principaux algorithmes ».
Description des principaux algorithmes.
Les algorithmes qui vont suivre ne constituent pas la totalité des algorithmes utilisés dans l’application. Les algorithmes qui seront présentés sont ceux qui sont les plus sollicités lors de l’exécution ou ceux qui comportent des astuces qu’il serait intéressant de développer.
Lecture dans les fichiers points :
L’algorithme de lecture des fichiers points se fait en deux phases .
La première phase consiste à créer un squelette du fichier. Ce squelette va contenir le format du fichier point : il va contenir le nombre de molécules que comporte un fichier ainsi que le nombre d’atomes qui constituent chaque molécule.
La deuxième phase remplit les images atome par atome : pour une image, elle va lire un fichier atome par atome et vérifier si ce fichier correspond bien au squelette créé dans la première phase.
Voici tout d’abord l’algorithme général qui permet d’ouvrir des fichier points .
Cet algorithme se trouve dans la fonction membre « OpenFile » de la classe « FILE_SKEL ».
RETRY = VRAI.
Tant que (RETRY = VRAI) faire
Ouverture de l’interface qui permet la sélection des fichiers.
Si l’utilisateur a annulé la sélection alors
RETRY = FAUX
Autrement
Si (le nombre de fichiers sélectionnés >0) alors
PATH = chemin d’accès des fichiers.
/* première phase*/
Construire le squelette des fichiers à partir du premier
Si (pas d’erreur lors de la création du squelette) alors
RETRY=FALSE;
/* deuxième phase*/
Remplir les images avec les atomes.
Fin Si.
Fin Si.
Fin Si
Fin tant que.
Renvoyer le nombre de fichiers.
Voici les algorithmes des deux phases :
Première phase : construire le squelette des fichiers à partir du premier.
Avant d’expliquer la première phase, rappelons-nous le format des fichiers points.
Chaque ligne comporte les positions (x,y,z) et la couleur (optionnelle) d’un atome suivie d’un retour chariot (<ENTER>) : chaque ligne composée de cette manière correspond à un atome.
Une ligne ne comportant qu’un retour chariot indique que l’on passe à la ligne suivante.
Mais une deuxième ligne vide n’indique pas une nouvelle molécule.
Suite à ces spécifications, l’algorithme de création du format des données peut facilement détecter le nombre de molécules et le nombre d’atomes pour chacune de celles-ci.
Une nouvelle molécule (( <ENTER><ENTER><autre caractère>. (respectivement précédent2, précédent 2 et CHAR dans l’algorithme).
Un nouvel atome(( <ENTER><autre caractère>. (respectivement précédent 2 et CHAR dans l’algorithme).
Le tableau dont parle l’algorithme constitue le format des données : la taille du tableau constitue le nombre de molécules et la valeur correspondant à chacune d’elle donne le nombre d’atomes qui la composent.
Cet algorithme se trouve dans la fonction membre « GetSkel » de la classe « FILE_SKEL ».
Créer un tableau vide de nombre d’atome (0 molécule).
Précédent1=Précédent2 = <ENTER>
Ouverture du premier fichier
Si (erreur d’ouverture) alors
renvoyer une erreur.
Autrement
Tant que (pas la fin du fichier) faire
CHAR= caractère suivant du fichier.
Si (Précédent1=Précédent2 = <ENTER> et CHAR ¹ <ENTER>) alors
Ajouter un élément valant 0 au tableau.
Fin Si
Si (Précédent1 = <ENTER> et CHAR ¹ <ENTER>) alors
Incrémenter la dernière valeur du tableau.
Fin Si
Précédent2=Précédent1.
Précédent1 = CHAR ;
Fin tant que
Fin si
Fermer le fichier.
Si (le nombre d’éléments ou la somme de tous les éléments du tableau est 0)
Renvoyer une erreur.
Fin Si.
Retour.
Deuxième phase : remplir les images avec les atomes.
Le remplissage des images avec les atomes des fichiers se fait en répétant l’algorithme qui va suivre pour toutes les images.
Le concept principe de cet algorithme est assez simple: remplir l’image en lisant un par un les atomes du fichier. Ensuite on regarde si le nombre d’atomes lus est égal à la somme des éléments du tableau utilisés dans la première phase (TOTAL): si ce n’est pas le cas, une erreur est générée.
Pour chaque atome, on teste également le nombre de composantes lues.
La constante LOAD_COLOR définit si le fichier contient ou non la couleur de l’atome.
Cet algorithme se trouve dans la fonction membre « FillFromFilel » de la classe « IMAGE ».
Si (LOAD_COLOR =VRAI) alors
Maxread=4.
Sinon
Maxread=3.
Fin Si.
RET=VRAI.
Ouvrir le fichier.
Si (erreur d’ouverture) alors
Renvoyer une erreur.
Sinon
Count=0 ;
Tant que (count<TOTAL et RET=VRAI et pas la fin du fichier)
Lire X ,Y Z s’ils sont lus read=3 sinon read=0.
Si (LOAD_COLOR) alors
Lire INDEX. si il est lu read= read+1 sinon read=0.
Autrement
INDEX= Count modulo 7
Fin Si
Si (read ¹ Maxread) alors
Renvoyer une erreur.
Ret=FAUX.
Autrement
Ajouter un atome à l’image (dont les valeurs sont X,Y,Z et INDEX)
Count=Count+1.
Fin si.
Fin tant que.
Fermer le fichier.
Si (Count <> TOTAL) alors
Renvoyer une erreur.
Fin Si
Fin Si
Affichage d'une image :
L’algorithme d’affichage d’une image pour l’animation temps réel est identique à celui de la librairie « GL_PLUS ». Il est donc inutile de l’expliquer à nouveau.
Toutefois, nous pouvons signaler qu’il se trouve dans la fonction « Render » de la classe « AUXWIN ».
Par contre, l’algorithme d’affichage d’une image plus « précise » est nouveau : cet algorithme ne dessine plus les liens comme des lignes : ceux-ci sont remplacés par un cylindre joignant les centres des atomes qu’il joint. Ce cylindre est divisé en deux parties, chaque partie est de même couleur que l’atome auquel elle est attachée.
Une autre différence est que les formes représentant les atomes sont fixées : c’est une sphère définie avec beaucoup plus de points que dans l’algorithme précédent. Cette nouvelle sphère contient vingt latitudes et vingt longitudes (contre 6 et 5 précédemment).
Il faut encore signaler que cet algorithme ne fonctionne pas en mode « double buffering » mais affiche directement dans un bitmap en mémoire : cette fonctionnalité permet de copier plus facilement le rendu de la scène dans un fichier PPM.
Cet algorithme se trouve dans les fonctions membres «DrawNice » et « JointAtome» de la classe « AUXWIN ».
Algorithme principal :
L’algorithme principal est décomposé en deux passes : une première qui affiche tous les atomes et la seconde qui affiche tous les liens entres ceux-ci.
Notations :
Cet algorithme est appliqué a une image donnée en paramètre : a[i] correspond au iième atome de l’image passée en paramètre.
Le format de l’image est également passé en paramètre : Nbr_atome[i] correspond au nombre d’atomes que contient la iième molécule, tout comme Nbr_molécule représente le nombre de molécules de l’image.
Cet algorithme étant assez similaire de l’algorithme de la librairie « GL_PLUS », le lecteur peut se référer à celui-ci pour plus d’informations.
Effacement de la scène.
Sauvegarde de la matrice de transformation.
Définition de la perspective.
Positionnement de la caméra.
C=0.
Pour i allant de 0 à Nbr_molec faire
Pour j allant de 0 à Nbr_atome[i] faire
Sélection de la couleur de a[C].
Sauvegarde de la matrice de transformation.
Translation vers a[C]
Afficher une sphère à la position courante.
Restaurer la matrice de transformation précédente.
C=C+1.
Fin Pour.
Fin Pour.
C=0.
Pour i allant de 0 à Nbr_molec faire
NA= Nbr_atome[i].
Pour j allant de 0 à NA faire
Si (j < NA-1) alors
/* si ce n’est pas le dernier atome de la molécule*/
Joindre les atomes a[C] et a[C+1].
/*point suivant */
Fin Si.
C=C+1.
Fin Pour.
Fin Pour.
Restaurer la matrice de transformation précédente.
Algorithme : joindre l’atome A à l’atome B.
Comme expliqué plus haut, l’algorithme d’affichage d’une image plus « précise » est nouveau. Cet algorithme ne dessine plus les liens comme des lignes : ceux-ci sont remplacés par un cylindre joignant les centres des atomes qu’il joint. Ce cylindre est divisé en deux parties, chaque partie est de même couleur que l’atome auquel elle est attachée.
L’idée de base de cet algorithme est d’effectuer un changement de repère afin d’orienter l’axe des Z sur la droite joignant les deux centres des atomes. Ensuite de dessiner un cylindre dont l’axe de révolution est confondu avec ce nouvel axe des Z et dont la hauteur est la moitié de la distance entre les deux atomes. Ensuite effectuer une translation de la même hauteur suivant l’axe des Z et de redessiner ce cylindre en changeant la couleur de celui-ci.
Pour effectuer ce premier changement de repère, nous utiliserons les formules pour le passage de coordonnées cartésiennes en coordonnées sphériques .
L’algorithme n’utilise pas exactement ces formules mais s’en inspire fortement : il a été trouvé dans le News Group comp.graphic.api.opengl mais son auteur n’était pas communiquer : tous les tests visuels indiquent qu’il donne le résultat attendu.
Il est le résultat d’une redéfinition des axes pour obtenir des rotations autour des axes X et Y, du passage de repère levogire à dextrogire et d’une tranformation du système d’équation en calcul immédiat par tests sur les données.
Afin d’éviter le système d’équations pour le calcul de phi et téta, tous les cas ont été envisagés.
dx= (B.x - At.x).
dy= (B.y - A.y).
dz=-(B.z - A.z).
Tmp=( dx*dx + dz*dz ).
R= SQRT(Tmp + dy*dy).
Longueur=r/2 .
Tmp=SQRT(Tmp).
Si (Tmp ¹ 0) alors
Angy=ARCSIN( -dx / Tmp).
Si (dz <0) alors Angy=-Angy.
Autrement
Angy=0.0.
Fin Si.
Si (R ¹ 0) alors
Angx=ARCSIN( dy / r).
Si (dz <0) alors Angx=-Angx.
Autrement
Angx=0.0.
Fin Si.
Sauvegarde de la matrice de transformation.
Translation vers B.
Rotation de Angy autour de l’axe des Y.
Rotation de Angx autour de l’axe des X.
Sélection de la couleur de l’atome B.
Affichage d’un cylindre de hauteur = à Longueur.
Translation de Longueur suivant l’axe des Z.
Sélection de la couleur de l’atome A.
Affichage d’un cylindre de hauteur = à Longueur.
Restauration de la dernière matrice de transformation.
La sélection d’un atome :
L’algorithme de sélection d’un atome est divisé en deux parties. Une première partie qui gère l’interfaçage de la sélection et une deuxième qui donne l’objet qui est le plus près de la caméra à une position donnée (x,y).Cet algorithme se trouve dans les fonctions membres «Select » « Render » et « DoSelect» de la classe « AUXWIN ».
L’interfaçage de la sélection :
L’algorithme qui gère l’interfaçage de la sélection a un principe assez simple .
Il boucle tant que l’utilisateur clique à côté d’un atome et ne clique pas sur le bouton droit de la souris. Cet algorithme renvoie deux types de valeurs : un nombre négatif indique que l’utilisateur a annulé la sélection (bouton droit) ou un nombre positif qui est le numéro de l’atome dans l’image.
Cet algorithme se trouve dans la fonction membre «Select » de la classe « AUXWIN ».
RET=-1.
Selected=Faux.
Tant que (Selected=Faux) faire
Attendre que l’utilisateur appuie sur un bouton.
Si c’est le bouton droit alors
Selected=VRAI
Fin Si
Si c’est le bouton droit alors
x,y = position de la souris dans la fenêtre.
Regarder quel est l’atome à cette position
/* point suivant*/
Si il y a un atome alors
RET= numéro de cet atome.
Fin Si.
Fin Tant que.
Renvoyer RET.
La sélection de l’atome à la position x,y :
Cet algorithme a été fortement inspiré du fonctionnement d‘OpenGL et de ses fonctionnalités .
OpenGL permet de définir un deuxième buffer fonctionnant comme un Z-buffer. Ce deuxième buffer ne stocke plus la couleur de l’objet au premier plan mais un nom (sous forme d’un numéro) que l’on définit juste avant d’afficher l’objet.
Dès lors, le principe de l’algorithme est de restreindre l’affichage aux voisinages de la position x,y, et de regarder après l’affichage, la valeur stockée dans ce buffer. Etant entendu que le nombre qui s’y trouve est le numéro de l’atome.
Une dernière précision, l’algorithme renvoie la valeur –1 si aucun atome n’est sélectionné sinon elle renvoie son numéro.
La phrase « Sélection du nom xx » signifie que l’on signale à OpenGL que les modifications suivantes portent le nom xx : c’est cette valeur qu’OpenGL va mettre dans le buffer si les modifications de l’affichage sont plus proches de la caméra que ce qui s’y trouve.
Cet algorithme est appliqué a une image donnée en paramètre : a[i] correspond au iième atome de l’image passée en paramètre.
Le format de l’image est également passé en paramètre : Nbr_atome[i] correspond au nombre d’atomes que contient la iième molécule, tout comme Nbr_molécule représente le nombre de molécules de l’image.
Cet algorithme peur être trouvé dans les fonctions « Render » et « DoSelect» de la classe « AUXWIN ».
Calculer la position x’,y’ relative à l’affichage courant (fonction de x,y)
Initialise le buffer de noms.( -1 partout à un Z infini).
Effacement de la scène.
Sauvegarde de la matrice de transformation.
Définition de la perspective.
Restriction de la zone d’affichage au voisinage de x’,y’.
Positionnement de la camera.
C=0.
Pour i allant de 0 à Nbr_molec faire
Pour j allant de 0 à Nbr_atome[i] faire
Sélection du nom C.
Sauvegarde de la matrice de transformation.
Translation vers a[C]
Afficher une sphère à la position courante.
Restaurer la matrice de transformation précédente.
C=C+1.
Fin Pour.
Fin Pour.
Restaurer la matrice de transformation précédente.
Récupérer le numéro de l’atome dans le buffer de noms. (fonction d’OpenGL)
Renvoyer le numéro de l’atome.
Sauvegarde dans les fichiers "PPM" :
Voici un bref récapitulatif du format des fichiers « PPM » .
Le format du fichier « PPM » est très simple il se constitue d’un en-tête et des composantes de couleur RGB pour chaque point de l’image.
Voici l’en-tête utilisé dans l’algorithme de sauvegarde des fichiers « PPM » :
P6\n /* indique le format ppm */
400 400\n /* 400 est la taille suivant X et Y de l’image*/
256\n /* le nombre de couleurs pour chaque composante de couleur RGB */
... Ensuite viennent les unes à la suite des autres les composantes RGB de chaque point.
L’algorithme de sauvegarde des fichiers « PPM » est très simple : il crée le fichier ppm et son en-tête, et copie point par point l’image créée en mémoire par l’algorithme « d’affichage précis ».
Cet algorithme peut être trouvé dans la fonction « SavePpmNo » de la classe « CMoleViewDlg ».
Ouvrir le fichier.
Si (pas d’erreur d’ouverture ) alors
Ecrire "P6\n".
Ecrire « size size\n ».
Ecrire "255\n".
Pour y allant de size-1 à 0 faire
Pour x allant de 0 à size –1 faire
Pixel=Couleur RGB du point x,y.
Ecrire RGB.
Si (erreur d’écriture) alors
Renvoyer une erreur
Fin Si
Fin Pour
Fin Pour
Autrement
Renvoyer erreur
Fin Si
L’utilisation de l’application « MoleViev » nécessite un ordinateur type 486DX2 au minimum et le système d’exploitation Windows NT 4.0 ou ultérieur. Cet ordinateur doit disposer au minimum d’une carte graphique 1 Mb de 16 Mb de mémoire vive et 1 Mb d’espace disque. La résolution d’écran doit permettre un affichage de 65535 couleurs (16 BIT).
Le logiciel « MoleView » peut tourner sur un ordinateur muni du système d’exploitation Windows95 muni des librairies OpenGL.
Les performances de l’animation étant fortement liées aux performances de la machine, il est conseillé d’utiliser un ordinateur de type Pentium 133 Mhrz, 32 Mb de mémoire vive et un carte graphique accélératrice 3D.
Le manuel utilisateur qui suit ne contient que les informations nécessaires à une utilisation du logiciel « MoleView » .
Pour plus d’informations sur l’application, référez-vous au manuel technique.
L’ouverture de fichiers points :
Lorsque l’utilisateur clique sur le bouton
ou lors du lancement de l’application « MoleView », l’interface d’ouverture des fichiers apparaît : voici sa description et son fonctionnement.
La sous-fenêtre de sélection des fichiers (1) permet à l’utilisateur de sélectionner les fichiers points qui serviront à créer l’animation :
Si l’utilisateur veut changer de répertoire ([nom du répertoire]) ou de disque ([- unité disque-]) , il peut « double-cliquer » sur celui-ci. Le nouveau chemin d’accès est alors affiché dans la fenêtre d’indication du répertoire courant (3).
Lorsqu’il se situe dans le répertoire des fichiers points, l’utilisateur peut sélectionner les fichiers.
Si les fichiers points contiennent des informations sur la couleur des atomes, l’utilisateur doit cocher la case de sélection (4) et uniquement dans ce cas : en effet si l’utilisateur coche cette case alors que les fichiers ne contiennent pas d’informations sur la couleur des atomes les résultats sont imprévisibles.
Pour annuler la sélection des fichiers, l’utilisateur peut cliquer sur le bouton (6) : cette action a pour effet de restaurer l’animation précédente ou de quitter le programme si cette action annule la première sélection.
Pour valider sa sélection, l’utilisateur peut cliquer sur le bouton (5). Si les fichiers sont corrects, l’animation sera remplacée par les nouveaux fichiers points. Par contre si les fichiers s’avèrent inutilisables, l’application restaurera l’ancienne animation.
Voici un exemple de fichiers points :
Changement des formes et tailles :
Toutes les fonctions de configuration des formes et tailles des molécules se trouvent dans le groupe de commandes de l’interface principale suivant :
Les cases à cocher «NONE», «CUBE», «ICOSAEDRON», «DODECAGONE» et «SPHERE» permette de choisir la forme destinée à représenter un atome.
La case à cocher «LINE» quant à elle permet d’afficher ou non les liens entre les atomes.
La sélection de «NONE» sélectionne automatiquement l’affichage des liens entre les atomes.
Les flèches
et
permettent de changer la taille des formes (en haut) et la taille des liens (en bas).
A chaque modification de la représentation des molécules, l’affichage est automatiquement remis à jour.
Voici quelques exemples :
Représentation en utilisant le style de forme « NONE ».
Représentation en utilisant le style de forme « ICOSAEDRE » et les lignes sélectionnées.
Représentation en utilisant le style de forme « SPHERE» et les lignes sélectionnées.
Positionnement de la vue :
Toutes les fonctions de configuration de la vue de la scène se trouvent dans le groupe de commandes de l’interface principale suivant :
Les boutons
et
permettent de choisir l’élément de la vue à positionner respectivement le point de vue ou la caméra.
Le bouton
permet d’attacher l’élément de la vue sélectionné à un atome (l’utilisateur devra alors cliquer sur l’atome).
Le bouton
permet de détacher l’élément de la vue sélectionné de l’atome auquel il est attaché.
Ces deux dernières opérations modifient la vue du reste de l’animation. Ces opérations peuvent être effectuées autant de fois que voulu.
Le bouton
permet d’annuler la dernière modification appliquée au film.
Si l’utilisateur désire que le changement de vue s’effectue sur plusieurs images, il doit cocher la case «STEP» et indiquer avec les flèches
et
le nombre d’images utilisées pour le changement. Si par contre l’utilisateur veut que le changement de vue s’effectue sans transition il ne peut cocher cette case.
Lancer l’animation :
Pour lancer l’animation l’utilisateur peut cliquer soit sur le bouton
, soit sur le bouton
de l’interface principale.
Le bouton
lance l’animation depuis le première image jusqu’à la dernière et repositionne la position de l’animation sur l’image initiale.
Le bouton
lance l’animation depuis l’image courante jusqu’à la dernière et repositionne la position de l’animation sur l’image initiale.
L’animation du film peut être stoppée en cliquant sur l’interface principale.
La barre de défilement située en dessous de ces deux boutons permet à l’utilisateur de se positionner sur n’importe qu’elle image du film.
Sauvegarde des fichiers :
Pour sauvegarder les images successives de l’animation dans des fichiers « PPM », l’utilisateur peut cliquer sur le bouton
de l’interface principale.
Cette action a pour effet d’afficher la boîte de dialogue de sauvegarde suivante :
La sous-fenêtre de navigation (1) permet à l’utilisateur de se positionner dans le répertoire destiné à la sauvegarde des fichiers « PPM », le répertoire courant est affiché dans la sous-fenêtre (2).
Cette interface permet également de modifier la taille des fichiers de sortie : l’utilisateur peut, en modifiant la zone d’édition (3) entrer la taille désirée pour les images de sortie.
Pour annuler la sauvegarde, l’utilisateur doit cliquer sur le bouton (4) : cet action a pour effet de revenir à l’interface principale.
Le bouton (5) lance le rendu de chaque image et sa sauvegarde dans des fichiers « PPM ».
Voici quelques exemples de fichiers « PPM » :
