Accueil > > > PRÉSENTATION DU MODULE VPYTHON DÉDIÉ À L'ANIMATION 3D
PRÉSENTATION DU MODULE VPYTHON DÉDIÉ À L'ANIMATION 3D
Information sur la source
Description
Présentation ludique du module vpython avec une interface graphique basée sur l'utilisation du module tkinter. Ce programme permet d'inserer des formes géométriques dans un espace 3D à partir de leurs coordonnées et des vecteurs définissants leur position. On peut également charger/sauvegarder la scène (fichier vPyScene.py). Les modules indispensables sont Tkinter, vpython , et math (le module math facilite le calcul lors de la création d'animation par exemple). Il est possible d'exporter la scène crée au format POV en utilisant le module povexport . Pour convertir l'image au format bmp, je propose le logiciel libre POV-Ray . Dans ce cas, vous pouvez lever les commentaires ('#') des lignes 6 et 218 en précisant la chemin vers votre répertoire d'instalation de POV-Ray ce qui permet de lancer automatiquement la conversion de la scène. Concernant le programme, j'ai essayé de le rendre simple et lisible afin de présenter simplement une facette du module vpython. En effet, vpython présente de nombreuses autres caractéristiques. Sans être exaustif, on peut citer : * des formes non présentées (types courbes, etc...) * la possibilité de gérer les sources de lumière * la possibilité de fusionner des objects * la possibilité de gérer les évènement clavier et souris * la possibilité d'insérer des boutons de controle * la possibilité bien entendue d'animer les objects
Source
- #! D:\Python25\python.exe
- from Tkinter import *
- from visual import *
- from math import *
- import povexport
- #import os
-
- class PyIGU3D:
- def __init__(self, parent):
- """Initialisation de l'IGU"""
- self.parent=parent
- self.parent.title('Controles de la vision 3D')
- self.menuBar()
- self.container=Frame(self.parent)
- self.interface=Text(self.container)
- self.interface.insert('end','Bonjour et bienvenu\nPour tout renseignement tonny.rosca@gmail.com\n...')
- self.interface.pack(side='left',expand=YES,fill=BOTH)
- self.yscrollbar=Scrollbar(self.container)
- self.yscrollbar.pack(side='right',fill=Y)
- self.container.pack(fill=BOTH)
- self.yscrollbar.config(command=self.interface.yview)
-
- def menuBar(self):
- """Initialisation de la barre de menu"""
- menu=Menu()
- fichier=Menu()
- fichier.add_command(label='Nouveau',command=self.newScene)
- fichier.add_command(label='Charger la scene',command=self.loadScene)
- fichier.add_command(label='Sauvegarder la scene',command=self.saveScene)
- fichier.add_command(label='Exporter la scene',command=self.exportScene)
- fichier.add_command(label='Quitter',command=self.parent.destroy)
- menu.add_cascade(label='Fichier',menu=fichier)
- affichage=Menu()
- affichage.add_command(label='Lister les objects',command=self.listObjects)
- affichage.add_command(label='Parametres par default',command=self.allDefault)
- menu.add_cascade(label='Affichage',menu=affichage)
- inserer=Menu()
- inserer.add_command(label='Cube',command=self.addCube)
- inserer.add_command(label='Cone',command=self.addCone)
- inserer.add_command(label='Cylindre',command=self.addCylinder)
- inserer.add_command(label='Boulle',command=self.addBall)
- menu.add_cascade(label='Inserer',menu=inserer)
- zoom=Menu()
- zoom.add_command(label='Zoom +',command=self.zoomIn)
- zoom.add_command(label='Zoom -',command=self.zoomOut)
- zoom.add_command(label='Zoom auto',command=self.zoomAuto)
- menu.add_cascade(label='Zoom',menu=zoom)
- vue=Menu()
- vue.add_command(label="Decalage vers la droite",command=self.rightMove)
- vue.add_command(label="Decalage vers la gauche",command=self.leftMove)
- vue.add_command(label="Decalage vers le haut",command=self.upMove)
- vue.add_command(label="Decalage vers le bas",command=self.downMove)
- vue.add_command(label="Decalage vers le fond",command=self.topMove)
- vue.add_command(label="Decalage vers l'ecran",command=self.backMove)
- vue.add_command(label="Recentrer la vue",command=self.centerAuto)
- vue.add_command(label="Imposer les coordonnees",command=self.coordCenter)
- menu.add_cascade(label='Vue',menu=vue)
- couleur=Menu()
- couleur.add_command(label='Changer la couleur du fond',command=self.paramColor)
- menu.add_cascade(label='Couleur',menu=couleur)
- camera=Menu()
- camera.add_command(label='Decaler vers le haut',command=self.cameraUp)
- camera.add_command(label='Decaler vers le bas',command=self.cameraDown)
- camera.add_command(label='Decaler vers la droite',command=self.cameraRight)
- camera.add_command(label='Decaler vers la gauche',command=self.cameraLeft)
- camera.add_command(label='Vue par default',command=self.cameraDefault)
- camera.add_separator()
- camera.add_command(label="Augmenter l'angle",command=self.angleMore)
- camera.add_command(label="Diminuer l'angle",command=self.angleLess)
- camera.add_command(label="Angle par default",command=self.angleDefault)
- menu.add_cascade(label='Camera',menu=camera)
- animation=Menu()
- animation.add_command(label="Parametres de l'animation",command=self.paramAnim)
- menu.add_cascade(label='Animation',menu=animation)
- aide=Menu()
- aide.add_command(label='A propos...',command=self.aboutVersion)
- aide.add_command(label='Aide',command=self.aboutAuthor)
- menu.add_cascade(label='?',menu=aide)
- self.parent.config(menu=menu)
-
- def paramColor(self):
- """Fenetre d'ajustement de la couleur de fond"""
- self.windowColor=Toplevel()
- self.windowColor.title('Parametres')
- self.containerP1=Frame(self.windowColor)
- self.containerP1.pack(fill=X)
- self.redBackground=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
- self.redBackground.pack(fill=X)
- self.greenBackground=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
- self.greenBackground.pack(fill=X)
- self.blueBackground=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
- self.blueBackground.pack(fill=X)
- self.buttonP1=Button(self.containerP1,text='Valider',command=self.colorBackground)
- self.buttonP1.pack(fill=X)
- self.buttonP2=Button(self.containerP1,text='Annuler',command=self.windowColor.destroy)
- self.buttonP2.pack(fill=X)
-
- def zoomIn(self):
- """Zoom In"""
- self.scene.range=(self.scene.range[0]/1.5,self.scene.range[1]/1.5,self.scene.range[2]/1.5)
-
- def zoomOut(self):
- """Zoom Out"""
- self.scene.range=(1.5*self.scene.range[0],1.5*self.scene.range[1],1.5*self.scene.range[2])
-
- def zoomAuto(self):
- """Zoom automatique"""
- self.scene.autoscale=1
-
- def centerAuto(self):
- """Centrer la vue"""
- self.scene.autocenter=1
-
- def rightMove(self):
- """Decaler vers la droite"""
- self.scene.center=(self.scene.center[0]+10,self.scene.center[1],self.scene.center[2])
-
- def leftMove(self):
- """Decaler vers la gauche"""
- self.scene.autocenter=0
- self.scene.center=(self.scene.center[0]-10,self.scene.center[1],self.scene.center[2])
-
- def upMove(self):
- """Decaler vers le haut"""
- self.scene.autocenter=0
- self.scene.center=(self.scene.center[0],self.scene.center[1]-10,self.scene.center[2])
-
- def downMove(self):
- """Decaler vers le bas"""
- self.scene.autocenter=0
- self.scene.center=(self.scene.center[0],self.scene.center[1]+10,self.scene.center[2])
-
- def topMove(self):
- """Decaler vers le devant"""
- self.scene.autocenter=0
- self.scene.center=(self.scene.center[0],self.scene.center[1],self.scene.center[2]+10)
-
- def backMove(self):
- """Decaler vers le derriere"""
- self.scene.autocenter=0
- self.scene.center=(self.scene.center[0],self.scene.center[1],self.scene.center[2]-10)
-
- def coordCenter(self):
- """Imposer les coordonnees du centre de la camera"""
- self.windowCoordCenter=Toplevel()
- self.windowCoordCenter.title('Parametres')
- self.containerP1=Frame(self.windowCoordCenter)
- self.containerP1.pack(fill=X)
- self.x0perso=Scale(self.containerP1,from_=-500,to=500,resolution=1,label='Origine de x',orient='horizontal')
- self.x0perso.pack(fill=X)
- self.y0perso=Scale(self.containerP1,from_=-500,to=500,resolution=1,label='Origine de y',orient='horizontal')
- self.y0perso.pack(fill=X)
- self.z0perso=Scale(self.containerP1,from_=-500,to=500,resolution=1,label='Origine de z',orient='horizontal')
- self.z0perso.pack(fill=X)
- self.buttonP1=Button(self.containerP1,text='Valider',command=self.validCoordCenter)
- self.buttonP1.pack(fill=X)
- self.buttonP2=Button(self.containerP1,text='Annuler',command=self.windowCoordCenter.destroy)
- self.buttonP2.pack(fill=X)
-
- def validCoordCenter(self):
- """Valide le choix des coordonnees et recentre la vue"""
- self.scene.center=(self.x0perso.get(),self.y0perso.get(),self.z0perso.get())
- self.windowCoordCenter.destroy()
-
- def colorBackground(self):
- """Zoom In"""
- self.scene.background=(self.redBackground.get(),self.greenBackground.get(),self.blueBackground.get())
- self.windowColor.destroy()
-
- def cameraUp(self):
- """Deplacement de la camera vers le haut"""
- self.scene.forward=(self.scene.forward[0],self.scene.forward[1]+0.5,self.scene.forward[2])
-
- def cameraDown(self):
- """Deplacement de la camera vers le bas"""
- self.scene.forward=(self.scene.forward[0],self.scene.forward[1]-0.5,self.scene.forward[2])
-
- def cameraRight(self):
- """Deplacement de la camera vers la droite"""
- self.scene.forward=(self.scene.forward[0]-0.5,self.scene.forward[1],self.scene.forward[2])
-
- def cameraLeft(self):
- """Deplacement de la camera vers la gauche"""
- self.scene.forward=(self.scene.forward[0]+0.5,self.scene.forward[1],self.scene.forward[2])
-
- def cameraDefault(self):
- """Retour de la camera dans la position par default"""
- self.scene.forward=(0,0,-1)
-
- def angleMore(self):
- """Augmente l'angle de focale de la camera"""
- try:
- self.scene.fov=self.scene.fov*1.2
- except:
- self.interface.insert('end','Angle maximal atteint : 180 degres')
- self.yscrollbar.config(command=self.interface.yview)
-
- def angleLess(self):
- """Diminue l'angle de focale de la camera"""
- self.scene.fov=self.scene.fov/1.2
-
- def angleDefault(self):
- """Retablie l'angle de focale de la camera par default"""
- self.scene.fov=pi/3
-
- def allDefault(self):
- """Retablir les parametres par default"""
- self.scene.fov=pi/3
- self.scene.forward=(0,0,-1)
- self.scene.autocenter=1
- self.scene.autoscale=1
-
- def exportScene(self):
- """Exportation de la scene au format pov"""
- try:
- povexport.export(display=self.scene, filename='monVpython.POV')
- self.interface.insert('end',"Fichier exporte avec succes\n...")
- #os.popen("D:\\POV\\bin\\pvengine.exe monVpython.Pov")
- except:
- self.interface.insert('end',"Erreur lors de l'exportation du fichier\n...")
- self.yscrollbar.config(command=self.interface.yview)
-
- def loadScene(self):
- """Chargement d'une scene enregistree"""
- from vPyScene import forLoadScene
- self.scene=forLoadScene()
-
- def saveScene(self):
- """Sauvegarde de la scene sous"""
- try:
- outputFile=open("vPyScene.py",'w')
- #Sauvegarde de la scene
- outputFile.write("from visual import *\ndef forLoadScene():\n")
- outputFile.write("\tscene=display(title='Ma presentation de vpython',exit=0,background="+str(scene.background)+")\n")
- outputFile.write("\tscene.forward=("+str(self.scene.forward[0])+","+str(self.scene.forward[1])+","+str(self.scene.forward[2])+")\n")
- outputFile.write("\tscene.range=("+str(self.scene.range[0])+","+str(self.scene.range[1])+","+str(self.scene.range[2])+")\n")
- outputFile.write("\tscene.center=("+str(self.scene.center[0])+","+str(self.scene.center[1])+","+str(self.scene.center[2])+")\n")
- outputFile.write("\tscene.fov="+str(self.scene.fov)+"\n")
- index=0
- for obj in self.scene.objects:
- index+=1
- if obj.__class__==box:
- outputFile.write("\tobj"+str(index)+"=box(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),size=("+str(obj.size[0])+","+str(obj.size[1])+","+str(obj.size[2])+"),color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"))\n")
- elif obj.__class__==sphere:
- outputFile.write("\tobj"+str(index)+"=sphere(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),radius="+str(obj.radius)+",color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"))\n")
- elif obj.__class__==cone:
- outputFile.write("\tobj"+str(index)+"=cone(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),radius="+str(obj.radius)+",color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"),axis=("+str(obj.axis[0])+","+str(obj.axis[1])+","+str(obj.axis[2])+"))\n")
- elif obj.__class__==cylinder:
- outputFile.write("\tobj"+str(index)+"=cylinder(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),radius="+str(obj.radius)+",color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"),axis=("+str(obj.axis[0])+","+str(obj.axis[1])+","+str(obj.axis[2])+"))\n")
- outputFile.write("\treturn scene")
- outputFile.close
- self.interface.insert('end','Sauvegarde effectuee avec succes.\n...')
- except:
- self.interface.insert('end','Erreur lors de la sauvegarde du fichier.\n...')
- self.yscrollbar.config(command=self.interface.yview)
-
- def listObjects(self):
- for obj in self.scene.objects:
- if obj.__class__==box:
- self.interface.insert('end',"Object : Un cube.\n...\tDimensions :\n...\t\tX : "+str(obj.size[0])+"\n...\t\tY : "+str(obj.size[1])+"\n...\t\tZ : "+str(obj.size[2])+"\n...")
- elif obj.__class__==sphere:
- self.interface.insert('end',"Object : Une spere.\n...\tRayon : "+str(obj.radius)+"\n...\t")
- elif obj.__class__==cylinder:
- self.interface.insert('end',"Object : Un cylindre.\n...\tRayon : "+str(obj.radius)+"\n...\tDimensions :\n...\t\tX : "+str(obj.axis[0])+"\n...\t\tY : "+str(obj.axis[1])+"\n...\t\tZ : "+str(obj.axis[2])+"\n...")
- elif obj.__class__==cone:
- self.interface.insert('end',"Object : Un cone.\n...\tRayon : "+str(obj.radius)+"\n...\tDimensions :\n...\t\tX : "+str(obj.axis[0])+"\n...\t\tY : "+str(obj.axis[1])+"\n...\t\tZ : "+str(obj.axis[2])+"\n...")
- self.interface.insert('end',"\tPosition de l'object :\n...\t\tX : "+str(obj.pos[0])+"\n...\t\tY : "+str(obj.pos[1])+"\n...\t\tZ : "+str(obj.pos[2])+"\n...")
- self.interface.insert('end',"\tCouleur de l'object :\n...\t\tRouge : "+str(obj.color[0])+"\n...\t\tVert : "+str(obj.color[1])+"\n...\t\tBleue : "+str(obj.color[2])+"\n...")
- self.yscrollbar.config(command=self.interface.yview)
-
- def aboutAuthor(self):
- """Joindre l'auteur"""
- self.interface.insert('end','1. Creer une scene (Fichier--Nouveau)\n...2. Inserer des objects (Inserer)\n...Pour tout renseignement tonny.rosca@gmail.com\n...')
- self.yscrollbar.config(command=self.interface.yview)
-
- def aboutVersion(self):
- """Version"""
- self.interface.insert('end','Tutorial vPython V2.0\n...')
- self.yscrollbar.config(command=self.interface.yview)
-
- def validScene(self):
- """Creation d'un nouvelle scene"""
- self.interface.insert('end',"Nouvelle scene cree ("+str(self.xWin.get())+"*"+str(self.yWin.get())+").\n...")
- self.scene=display(title='Ma presentation de vpython',x=0,y=0,width=self.xWin.get(), height=self.yWin.get(),center=(0,0,0), background=(0,0,0),exit=0)
- self.windowScene.destroy()
- self.yscrollbar.config(command=self.interface.yview)
-
- def newScene(self):
- """Ouverture d'une fenetre presentant les parametres de la nouvelle scene"""
- self.windowScene=Toplevel()
- self.windowScene.title('Parametres de la scene')
- self.containerS1=Frame(self.windowScene)
- self.xWin=Scale(self.containerS1,from_=10,to=1024,resolution=1,label='Largeur de la fenetre',orient='horizontal')
- self.xWin.pack(fill=X)
- self.xWin.set(300)
- self.yWin=Scale(self.containerS1,from_=10,to=780,resolution=1,label='Hauteur de la fenetre',orient='horizontal')
- self.yWin.pack(fill=X)
- self.yWin.set(200)
- self.containerS2=Frame(self.windowScene)
- self.buttonS1=Button(self.containerS2,text='Valider',command=self.validScene)
- self.buttonS1.pack(fill=X)
- self.buttonS2=Button(self.containerS2,text='Annuler',command=self.windowScene.destroy)
- self.buttonS2.pack(fill=X)
- self.containerS1.pack(fill=X)
- self.containerS2.pack(fill=X)
-
- def addCube(self):
- """Ouverture d'une fenetre presentant les parametres du cube"""
- try:
- self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
- except:
- self.newScene()
- self.windowCube=Toplevel()
- self.windowCube.title('Inserer un cube')
- self.containerP1=Frame(self.windowCube)
- self.redCube=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
- self.redCube.pack(fill=X)
- self.greenCube=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
- self.greenCube.pack(fill=X)
- self.greenCube.set(1)
- self.blueCube=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
- self.blueCube.pack(fill=X)
- self.containerP2=Frame(self.windowCube)
- self.x0Cube=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
- self.x0Cube.pack(fill=X)
- self.y0Cube=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
- self.y0Cube.pack(fill=X)
- self.z0Cube=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
- self.z0Cube.pack(fill=X)
- self.containerP3=Frame(self.windowCube)
- self.xxCube=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Taille x',orient='horizontal')
- self.xxCube.pack(fill=X)
- self.xxCube.set(30)
- self.yyCube=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Taille y',orient='horizontal')
- self.yyCube.pack(fill=X)
- self.yyCube.set(30)
- self.zzCube=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Taille z',orient='horizontal')
- self.zzCube.pack(fill=X)
- self.zzCube.set(30)
- self.containerP4=Frame(self.windowCube)
- self.buttonP1=Button(self.containerP4,text='Valider',command=self.validCube)
- self.buttonP1.pack(fill=X)
- self.buttonP2=Button(self.containerP4,text='Annuler',command=self.windowCube.destroy)
- self.buttonP2.pack(fill=X)
- self.containerP1.pack(side='left',fill=X)
- self.containerP2.pack(side='left',fill=X)
- self.containerP3.pack(side='left',fill=X)
- self.containerP4.pack(side='bottom',fill=X)
- self.yscrollbar.config(command=self.interface.yview)
-
- def validCube(self):
- """Creation du cube"""
- self.interface.insert('end',"Creation du cube.\n...")
- self.cube=box(pos=(self.x0Cube.get(),self.y0Cube.get(),self.z0Cube.get()), size=(self.xxCube.get(),self.yyCube.get(),self.zzCube.get()),color=(self.redCube.get(),self.greenCube.get(),self.blueCube.get()))
- self.windowCube.destroy()
- self.yscrollbar.config(command=self.interface.yview)
-
- def addBall(self):
- """Ouverture d'une fenetre presentant les parametres du cube"""
- try:
- self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
- except:
- self.newScene()
- self.windowBall=Toplevel()
- self.windowBall.title('Inserer un cube')
- self.containerP1=Frame(self.windowBall)
- self.redBall=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
- self.redBall.pack(fill=X)
- self.redBall.set(1)
- self.greenBall=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
- self.greenBall.pack(fill=X)
- self.blueBall=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
- self.blueBall.pack(fill=X)
- self.containerP2=Frame(self.windowBall)
- self.x0Ball=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
- self.x0Ball.pack(fill=X)
- self.y0Ball=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
- self.y0Ball.pack(fill=X)
- self.z0Ball=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
- self.z0Ball.pack(fill=X)
- self.containerP3=Frame(self.windowBall)
- self.rayBall=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Rayon',orient='horizontal')
- self.rayBall.pack(fill=X)
- self.rayBall.set(30)
- self.containerP4=Frame(self.windowBall)
- self.buttonP1=Button(self.containerP4,text='Valider',command=self.validBall)
- self.buttonP1.pack(fill=X)
- self.buttonP2=Button(self.containerP4,text='Annuler',command=self.windowBall.destroy)
- self.buttonP2.pack(fill=X)
- self.containerP1.pack(side='left',fill=X)
- self.containerP2.pack(side='left',fill=X)
- self.containerP3.pack(side='left',fill=X)
- self.containerP4.pack(side='bottom',fill=X)
- self.yscrollbar.config(command=self.interface.yview)
-
- def validBall(self):
- """Creation du cube"""
- self.interface.insert('end',"Creation de la boulle.\n...")
- self.ball=sphere(pos=(self.x0Ball.get(),self.y0Ball.get(),self.z0Ball.get()), radius=self.rayBall.get(),color=(self.redBall.get(),self.greenBall.get(),self.blueBall.get()))
- self.windowBall.destroy()
- self.yscrollbar.config(command=self.interface.yview)
-
- def addCylinder(self):
- """Ouverture d'une fenetre presentant les parametres du cylindre"""
- try:
- self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
- except:
- self.newScene()
- self.windowCylinder=Toplevel()
- self.windowCylinder.title('Inserer un cylindre')
- self.containerCy1=Frame(self.windowCylinder)
- self.redCylinder=Scale(self.containerCy1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
- self.redCylinder.pack(fill=X)
- self.greenCylinder=Scale(self.containerCy1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
- self.greenCylinder.pack(fill=X)
- self.blueCylinder=Scale(self.containerCy1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
- self.blueCylinder.pack(fill=X)
- self.blueCylinder.set(1)
- self.containerCy2=Frame(self.windowCylinder)
- self.x0Cylinder=Scale(self.containerCy2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
- self.x0Cylinder.pack(fill=X)
- self.y0Cylinder=Scale(self.containerCy2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
- self.y0Cylinder.pack(fill=X)
- self.z0Cylinder=Scale(self.containerCy2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
- self.z0Cylinder.pack(fill=X)
- self.containerCy3=Frame(self.windowCylinder)
- self.xxCylinder=Scale(self.containerCy3,from_=-500,to=500,resolution=1,label='Taille x',orient='horizontal')
- self.xxCylinder.pack(fill=X)
- self.xxCylinder.set(30)
- self.yyCylinder=Scale(self.containerCy3,from_=-500,to=500,resolution=1,label='Taille y',orient='horizontal')
- self.yyCylinder.pack(fill=X)
- self.yyCylinder.set(30)
- self.zzCylinder=Scale(self.containerCy3,from_=-500,to=500,resolution=1,label='Taille z',orient='horizontal')
- self.zzCylinder.pack(fill=X)
- self.zzCylinder.set(30)
- self.containerCy4=Frame(self.windowCylinder)
- self.rayCylinder=Scale(self.containerCy3,from_=0,to=500,resolution=1,label='Rayon',orient='horizontal')
- self.rayCylinder.pack(fill=X)
- self.rayCylinder.set(30)
- self.containerCy5=Frame(self.windowCylinder)
- self.buttonCy1=Button(self.containerCy5,text='Valider',command=self.validCylinder)
- self.buttonCy1.pack(fill=X)
- self.buttonCy2=Button(self.containerCy5,text='Annuler',command=self.windowCylinder.destroy)
- self.buttonCy2.pack(fill=X)
- self.containerCy1.pack(side='left',fill=X)
- self.containerCy2.pack(side='left',fill=X)
- self.containerCy3.pack(side='left',fill=X)
- self.containerCy4.pack(side='left',fill=X)
- self.containerCy5.pack(side='bottom',fill=X)
- self.yscrollbar.config(command=self.interface.yview)
-
- def validCylinder(self):
- """Creation du cylindre"""
- self.interface.insert('end',"Creation du cylindre\n...")
- self.cylindre=cylinder(pos=(self.x0Cylinder.get(),self.y0Cylinder.get(),self.z0Cylinder.get()),axis=(self.xxCylinder.get(),self.yyCylinder.get(),self.zzCylinder.get()),radius=self.rayCylinder.get(),color=(self.redCylinder.get(),self.greenCylinder.get(),self.blueCylinder.get()))
- self.windowCylinder.destroy()
- self.yscrollbar.config(command=self.interface.yview)
-
- def addCone(self):
- """Ouverture d'une fenetre presentant les parametres du cone"""
- try:
- self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
- except:
- self.newScene()
- self.windowCone=Toplevel()
- self.windowCone.title('Inserer un cone')
- self.containerCo1=Frame(self.windowCone)
- self.redCone=Scale(self.containerCo1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
- self.redCone.pack(fill=X)
- self.redCone.set(1)
- self.greenCone=Scale(self.containerCo1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
- self.greenCone.pack(fill=X)
- self.greenCone.set(1)
- self.blueCone=Scale(self.containerCo1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
- self.blueCone.pack(fill=X)
- self.containerCo2=Frame(self.windowCone)
- self.x0Cone=Scale(self.containerCo2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
- self.x0Cone.pack(fill=X)
- self.y0Cone=Scale(self.containerCo2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
- self.y0Cone.pack(fill=X)
- self.z0Cone=Scale(self.containerCo2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
- self.z0Cone.pack(fill=X)
- self.containerCo3=Frame(self.windowCone)
- self.xxCone=Scale(self.containerCo3,from_=-500,to=500,resolution=1,label='Taille x',orient='horizontal')
- self.xxCone.pack(fill=X)
- self.xxCone.set(30)
- self.yyCone=Scale(self.containerCo3,from_=-500,to=500,resolution=1,label='Taille y',orient='horizontal')
- self.yyCone.pack(fill=X)
- self.yyCone.set(30)
- self.zzCone=Scale(self.containerCo3,from_=-500,to=500,resolution=1,label='Taille z',orient='horizontal')
- self.zzCone.pack(fill=X)
- self.zzCone.set(30)
- self.containerCo4=Frame(self.windowCone)
- self.rayCone=Scale(self.containerCo3,from_=0,to=500,resolution=1,label='Rayon',orient='horizontal')
- self.rayCone.pack(fill=X)
- self.rayCone.set(30)
- self.containerCo5=Frame(self.windowCone)
- self.buttonCo1=Button(self.containerCo5,text='Valider',command=self.validCone)
- self.buttonCo1.pack(fill=X)
- self.buttonCo2=Button(self.containerCo5,text='Annuler',command=self.windowCone.destroy)
- self.buttonCo2.pack(fill=X)
- self.containerCo1.pack(side='left',fill=X)
- self.containerCo2.pack(side='left',fill=X)
- self.containerCo3.pack(side='left',fill=X)
- self.containerCo4.pack(side='left',fill=X)
- self.containerCo5.pack(side='bottom',fill=X)
- self.yscrollbar.config(command=self.interface.yview)
-
- def validCone(self):
- """Creation du cone"""
- self.interface.insert('end',"Creation du cone\n...")
- self.leCone=cone(pos=(self.x0Cone.get(),self.y0Cone.get(),self.z0Cone.get()),axis=(self.xxCone.get(),self.yyCone.get(),self.zzCone.get()),radius=self.rayCone.get(),color=(self.redCone.get(),self.greenCone.get(),self.blueCone.get()))
- self.windowCone.destroy()
- self.yscrollbar.config(command=self.interface.yview)
-
- def paramAnim(self):
- """Lancement d'une animation de type rotation de la camera autours du point central selon x"""
- self.windowAnim=Toplevel()
- self.windowAnim.title=("Parametres de l'animation")
- self.containerAn1=Frame(self.windowAnim)
- self.x0Anim=Scale(self.containerAn1,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
- self.x0Anim.pack(fill=X)
- self.y0Anim=Scale(self.containerAn1,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
- self.y0Anim.pack(fill=X)
- self.z0Anim=Scale(self.containerAn1,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
- self.z0Anim.pack(fill=X)
- self.z0Anim.set(-1)
- self.containerAn2=Frame(self.windowAnim)
- self.xTemp=Entry(self.containerAn2)
- self.xTemp.pack(fill=X)
- self.xTemp.insert('0','xt=-1+sin(2*pi*t/30)')
- self.yTemp=Entry(self.containerAn2)
- self.yTemp.pack(fill=X)
- self.yTemp.insert('0','yt=-0.5')
- self.zTemp=Entry(self.containerAn2)
- self.zTemp.pack(fill=X)
- self.zTemp.insert('0','zt=cos(2*pi*t/30)-1')
- self.zoomTemp=Entry(self.containerAn2)
- self.zoomTemp.pack(fill=X)
- self.zoomTemp.insert('0','zoomt='+str(self.scene.range[0])+'+40*t**2-100*t')
- self.totalTime=Scale(self.containerAn2,from_=0.1,to=60,resolution=0.1,label='Temps total',orient='horizontal')
- self.totalTime.pack(fill=X)
- self.totalTime.set(1)
- self.containerAn3=Frame(self.windowAnim)
- self.buttonAn1=Button(self.containerAn3,text='Valider',command=self.validAnim)
- self.buttonAn1.pack(fill=X)
- self.buttonAn1=Button(self.containerAn3,text='Exporter',command=self.exportAnim)
- self.buttonAn1.pack(fill=X)
- self.buttonAn2=Button(self.containerAn3,text='Annuler',command=self.windowAnim.destroy)
- self.buttonAn2.pack(fill=X)
- self.containerAn1.pack(side='left',fill=X)
- self.containerAn2.pack(side='left',fill=X)
- self.containerAn3.pack(side='bottom',fill=X)
-
- def validAnim(self):
- """Lance l'animation en fonction des equations donnes par l'utilisateur"""
- t=0
- dt=0.01
- finished=False
- self.scene.forward=(self.x0Anim.get(),self.y0Anim.get(),self.z0Anim.get())
- while not finished:
- rate(100)
- exec(self.xTemp.get())
- exec(self.yTemp.get())
- exec(self.zTemp.get())
- exec(self.zoomTemp.get())
- self.scene.range=(zoomt,zoomt,zoomt)
- self.scene.forward=(xt,yt,zt)
- t+=dt
- if t>=self.totalTime.get():
- finished=True
- #self.windowAnim.destroy()
-
- def exportAnim(self):
- """Exporter l'animation"""
- t=0
- dt=0.01
- finished=False
- cpt=0
- self.scene.forward=(self.x0Anim.get(),self.y0Anim.get(),self.z0Anim.get())
- while not finished:
- rate(100)
- exec(self.xTemp.get())
- exec(self.yTemp.get())
- exec(self.zTemp.get())
- exec(self.zoomTemp.get())
- self.scene.range=(zoomt,zoomt,zoomt)
- self.scene.forward=(xt,yt,zt)
- t+=dt
- try:
- povexport.export(display=self.scene, filename='monVpython'+str(cpt)+'.POV')
- self.interface.insert('end',"Fichier exporte avec succes\n...")
- #os.popen('D:\\POV\\bin\\pvengine.exe monVpython'+str(cpt)+'.POV')
- except:
- self.interface.insert('end',"Erreur lors de l'exportation du fichier\n...")
- self.yscrollbar.config(command=self.interface.yview)
- cpt+=1
- if t>=self.totalTime.get():
- finished=True
-
-
-
- root=Tk()
- myapp=PyIGU3D(root)
- root.mainloop()
#! D:\Python25\python.exe
from Tkinter import *
from visual import *
from math import *
import povexport
#import os
class PyIGU3D:
def __init__(self, parent):
"""Initialisation de l'IGU"""
self.parent=parent
self.parent.title('Controles de la vision 3D')
self.menuBar()
self.container=Frame(self.parent)
self.interface=Text(self.container)
self.interface.insert('end','Bonjour et bienvenu\nPour tout renseignement tonny.rosca@gmail.com\n...')
self.interface.pack(side='left',expand=YES,fill=BOTH)
self.yscrollbar=Scrollbar(self.container)
self.yscrollbar.pack(side='right',fill=Y)
self.container.pack(fill=BOTH)
self.yscrollbar.config(command=self.interface.yview)
def menuBar(self):
"""Initialisation de la barre de menu"""
menu=Menu()
fichier=Menu()
fichier.add_command(label='Nouveau',command=self.newScene)
fichier.add_command(label='Charger la scene',command=self.loadScene)
fichier.add_command(label='Sauvegarder la scene',command=self.saveScene)
fichier.add_command(label='Exporter la scene',command=self.exportScene)
fichier.add_command(label='Quitter',command=self.parent.destroy)
menu.add_cascade(label='Fichier',menu=fichier)
affichage=Menu()
affichage.add_command(label='Lister les objects',command=self.listObjects)
affichage.add_command(label='Parametres par default',command=self.allDefault)
menu.add_cascade(label='Affichage',menu=affichage)
inserer=Menu()
inserer.add_command(label='Cube',command=self.addCube)
inserer.add_command(label='Cone',command=self.addCone)
inserer.add_command(label='Cylindre',command=self.addCylinder)
inserer.add_command(label='Boulle',command=self.addBall)
menu.add_cascade(label='Inserer',menu=inserer)
zoom=Menu()
zoom.add_command(label='Zoom +',command=self.zoomIn)
zoom.add_command(label='Zoom -',command=self.zoomOut)
zoom.add_command(label='Zoom auto',command=self.zoomAuto)
menu.add_cascade(label='Zoom',menu=zoom)
vue=Menu()
vue.add_command(label="Decalage vers la droite",command=self.rightMove)
vue.add_command(label="Decalage vers la gauche",command=self.leftMove)
vue.add_command(label="Decalage vers le haut",command=self.upMove)
vue.add_command(label="Decalage vers le bas",command=self.downMove)
vue.add_command(label="Decalage vers le fond",command=self.topMove)
vue.add_command(label="Decalage vers l'ecran",command=self.backMove)
vue.add_command(label="Recentrer la vue",command=self.centerAuto)
vue.add_command(label="Imposer les coordonnees",command=self.coordCenter)
menu.add_cascade(label='Vue',menu=vue)
couleur=Menu()
couleur.add_command(label='Changer la couleur du fond',command=self.paramColor)
menu.add_cascade(label='Couleur',menu=couleur)
camera=Menu()
camera.add_command(label='Decaler vers le haut',command=self.cameraUp)
camera.add_command(label='Decaler vers le bas',command=self.cameraDown)
camera.add_command(label='Decaler vers la droite',command=self.cameraRight)
camera.add_command(label='Decaler vers la gauche',command=self.cameraLeft)
camera.add_command(label='Vue par default',command=self.cameraDefault)
camera.add_separator()
camera.add_command(label="Augmenter l'angle",command=self.angleMore)
camera.add_command(label="Diminuer l'angle",command=self.angleLess)
camera.add_command(label="Angle par default",command=self.angleDefault)
menu.add_cascade(label='Camera',menu=camera)
animation=Menu()
animation.add_command(label="Parametres de l'animation",command=self.paramAnim)
menu.add_cascade(label='Animation',menu=animation)
aide=Menu()
aide.add_command(label='A propos...',command=self.aboutVersion)
aide.add_command(label='Aide',command=self.aboutAuthor)
menu.add_cascade(label='?',menu=aide)
self.parent.config(menu=menu)
def paramColor(self):
"""Fenetre d'ajustement de la couleur de fond"""
self.windowColor=Toplevel()
self.windowColor.title('Parametres')
self.containerP1=Frame(self.windowColor)
self.containerP1.pack(fill=X)
self.redBackground=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
self.redBackground.pack(fill=X)
self.greenBackground=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
self.greenBackground.pack(fill=X)
self.blueBackground=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
self.blueBackground.pack(fill=X)
self.buttonP1=Button(self.containerP1,text='Valider',command=self.colorBackground)
self.buttonP1.pack(fill=X)
self.buttonP2=Button(self.containerP1,text='Annuler',command=self.windowColor.destroy)
self.buttonP2.pack(fill=X)
def zoomIn(self):
"""Zoom In"""
self.scene.range=(self.scene.range[0]/1.5,self.scene.range[1]/1.5,self.scene.range[2]/1.5)
def zoomOut(self):
"""Zoom Out"""
self.scene.range=(1.5*self.scene.range[0],1.5*self.scene.range[1],1.5*self.scene.range[2])
def zoomAuto(self):
"""Zoom automatique"""
self.scene.autoscale=1
def centerAuto(self):
"""Centrer la vue"""
self.scene.autocenter=1
def rightMove(self):
"""Decaler vers la droite"""
self.scene.center=(self.scene.center[0]+10,self.scene.center[1],self.scene.center[2])
def leftMove(self):
"""Decaler vers la gauche"""
self.scene.autocenter=0
self.scene.center=(self.scene.center[0]-10,self.scene.center[1],self.scene.center[2])
def upMove(self):
"""Decaler vers le haut"""
self.scene.autocenter=0
self.scene.center=(self.scene.center[0],self.scene.center[1]-10,self.scene.center[2])
def downMove(self):
"""Decaler vers le bas"""
self.scene.autocenter=0
self.scene.center=(self.scene.center[0],self.scene.center[1]+10,self.scene.center[2])
def topMove(self):
"""Decaler vers le devant"""
self.scene.autocenter=0
self.scene.center=(self.scene.center[0],self.scene.center[1],self.scene.center[2]+10)
def backMove(self):
"""Decaler vers le derriere"""
self.scene.autocenter=0
self.scene.center=(self.scene.center[0],self.scene.center[1],self.scene.center[2]-10)
def coordCenter(self):
"""Imposer les coordonnees du centre de la camera"""
self.windowCoordCenter=Toplevel()
self.windowCoordCenter.title('Parametres')
self.containerP1=Frame(self.windowCoordCenter)
self.containerP1.pack(fill=X)
self.x0perso=Scale(self.containerP1,from_=-500,to=500,resolution=1,label='Origine de x',orient='horizontal')
self.x0perso.pack(fill=X)
self.y0perso=Scale(self.containerP1,from_=-500,to=500,resolution=1,label='Origine de y',orient='horizontal')
self.y0perso.pack(fill=X)
self.z0perso=Scale(self.containerP1,from_=-500,to=500,resolution=1,label='Origine de z',orient='horizontal')
self.z0perso.pack(fill=X)
self.buttonP1=Button(self.containerP1,text='Valider',command=self.validCoordCenter)
self.buttonP1.pack(fill=X)
self.buttonP2=Button(self.containerP1,text='Annuler',command=self.windowCoordCenter.destroy)
self.buttonP2.pack(fill=X)
def validCoordCenter(self):
"""Valide le choix des coordonnees et recentre la vue"""
self.scene.center=(self.x0perso.get(),self.y0perso.get(),self.z0perso.get())
self.windowCoordCenter.destroy()
def colorBackground(self):
"""Zoom In"""
self.scene.background=(self.redBackground.get(),self.greenBackground.get(),self.blueBackground.get())
self.windowColor.destroy()
def cameraUp(self):
"""Deplacement de la camera vers le haut"""
self.scene.forward=(self.scene.forward[0],self.scene.forward[1]+0.5,self.scene.forward[2])
def cameraDown(self):
"""Deplacement de la camera vers le bas"""
self.scene.forward=(self.scene.forward[0],self.scene.forward[1]-0.5,self.scene.forward[2])
def cameraRight(self):
"""Deplacement de la camera vers la droite"""
self.scene.forward=(self.scene.forward[0]-0.5,self.scene.forward[1],self.scene.forward[2])
def cameraLeft(self):
"""Deplacement de la camera vers la gauche"""
self.scene.forward=(self.scene.forward[0]+0.5,self.scene.forward[1],self.scene.forward[2])
def cameraDefault(self):
"""Retour de la camera dans la position par default"""
self.scene.forward=(0,0,-1)
def angleMore(self):
"""Augmente l'angle de focale de la camera"""
try:
self.scene.fov=self.scene.fov*1.2
except:
self.interface.insert('end','Angle maximal atteint : 180 degres')
self.yscrollbar.config(command=self.interface.yview)
def angleLess(self):
"""Diminue l'angle de focale de la camera"""
self.scene.fov=self.scene.fov/1.2
def angleDefault(self):
"""Retablie l'angle de focale de la camera par default"""
self.scene.fov=pi/3
def allDefault(self):
"""Retablir les parametres par default"""
self.scene.fov=pi/3
self.scene.forward=(0,0,-1)
self.scene.autocenter=1
self.scene.autoscale=1
def exportScene(self):
"""Exportation de la scene au format pov"""
try:
povexport.export(display=self.scene, filename='monVpython.POV')
self.interface.insert('end',"Fichier exporte avec succes\n...")
#os.popen("D:\\POV\\bin\\pvengine.exe monVpython.Pov")
except:
self.interface.insert('end',"Erreur lors de l'exportation du fichier\n...")
self.yscrollbar.config(command=self.interface.yview)
def loadScene(self):
"""Chargement d'une scene enregistree"""
from vPyScene import forLoadScene
self.scene=forLoadScene()
def saveScene(self):
"""Sauvegarde de la scene sous"""
try:
outputFile=open("vPyScene.py",'w')
#Sauvegarde de la scene
outputFile.write("from visual import *\ndef forLoadScene():\n")
outputFile.write("\tscene=display(title='Ma presentation de vpython',exit=0,background="+str(scene.background)+")\n")
outputFile.write("\tscene.forward=("+str(self.scene.forward[0])+","+str(self.scene.forward[1])+","+str(self.scene.forward[2])+")\n")
outputFile.write("\tscene.range=("+str(self.scene.range[0])+","+str(self.scene.range[1])+","+str(self.scene.range[2])+")\n")
outputFile.write("\tscene.center=("+str(self.scene.center[0])+","+str(self.scene.center[1])+","+str(self.scene.center[2])+")\n")
outputFile.write("\tscene.fov="+str(self.scene.fov)+"\n")
index=0
for obj in self.scene.objects:
index+=1
if obj.__class__==box:
outputFile.write("\tobj"+str(index)+"=box(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),size=("+str(obj.size[0])+","+str(obj.size[1])+","+str(obj.size[2])+"),color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"))\n")
elif obj.__class__==sphere:
outputFile.write("\tobj"+str(index)+"=sphere(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),radius="+str(obj.radius)+",color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"))\n")
elif obj.__class__==cone:
outputFile.write("\tobj"+str(index)+"=cone(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),radius="+str(obj.radius)+",color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"),axis=("+str(obj.axis[0])+","+str(obj.axis[1])+","+str(obj.axis[2])+"))\n")
elif obj.__class__==cylinder:
outputFile.write("\tobj"+str(index)+"=cylinder(pos=("+str(obj.pos[0])+","+str(obj.pos[1])+","+str(obj.pos[2])+"),radius="+str(obj.radius)+",color=("+str(obj.color[0])+","+str(obj.color[1])+","+str(obj.color[2])+"),axis=("+str(obj.axis[0])+","+str(obj.axis[1])+","+str(obj.axis[2])+"))\n")
outputFile.write("\treturn scene")
outputFile.close
self.interface.insert('end','Sauvegarde effectuee avec succes.\n...')
except:
self.interface.insert('end','Erreur lors de la sauvegarde du fichier.\n...')
self.yscrollbar.config(command=self.interface.yview)
def listObjects(self):
for obj in self.scene.objects:
if obj.__class__==box:
self.interface.insert('end',"Object : Un cube.\n...\tDimensions :\n...\t\tX : "+str(obj.size[0])+"\n...\t\tY : "+str(obj.size[1])+"\n...\t\tZ : "+str(obj.size[2])+"\n...")
elif obj.__class__==sphere:
self.interface.insert('end',"Object : Une spere.\n...\tRayon : "+str(obj.radius)+"\n...\t")
elif obj.__class__==cylinder:
self.interface.insert('end',"Object : Un cylindre.\n...\tRayon : "+str(obj.radius)+"\n...\tDimensions :\n...\t\tX : "+str(obj.axis[0])+"\n...\t\tY : "+str(obj.axis[1])+"\n...\t\tZ : "+str(obj.axis[2])+"\n...")
elif obj.__class__==cone:
self.interface.insert('end',"Object : Un cone.\n...\tRayon : "+str(obj.radius)+"\n...\tDimensions :\n...\t\tX : "+str(obj.axis[0])+"\n...\t\tY : "+str(obj.axis[1])+"\n...\t\tZ : "+str(obj.axis[2])+"\n...")
self.interface.insert('end',"\tPosition de l'object :\n...\t\tX : "+str(obj.pos[0])+"\n...\t\tY : "+str(obj.pos[1])+"\n...\t\tZ : "+str(obj.pos[2])+"\n...")
self.interface.insert('end',"\tCouleur de l'object :\n...\t\tRouge : "+str(obj.color[0])+"\n...\t\tVert : "+str(obj.color[1])+"\n...\t\tBleue : "+str(obj.color[2])+"\n...")
self.yscrollbar.config(command=self.interface.yview)
def aboutAuthor(self):
"""Joindre l'auteur"""
self.interface.insert('end','1. Creer une scene (Fichier--Nouveau)\n...2. Inserer des objects (Inserer)\n...Pour tout renseignement tonny.rosca@gmail.com\n...')
self.yscrollbar.config(command=self.interface.yview)
def aboutVersion(self):
"""Version"""
self.interface.insert('end','Tutorial vPython V2.0\n...')
self.yscrollbar.config(command=self.interface.yview)
def validScene(self):
"""Creation d'un nouvelle scene"""
self.interface.insert('end',"Nouvelle scene cree ("+str(self.xWin.get())+"*"+str(self.yWin.get())+").\n...")
self.scene=display(title='Ma presentation de vpython',x=0,y=0,width=self.xWin.get(), height=self.yWin.get(),center=(0,0,0), background=(0,0,0),exit=0)
self.windowScene.destroy()
self.yscrollbar.config(command=self.interface.yview)
def newScene(self):
"""Ouverture d'une fenetre presentant les parametres de la nouvelle scene"""
self.windowScene=Toplevel()
self.windowScene.title('Parametres de la scene')
self.containerS1=Frame(self.windowScene)
self.xWin=Scale(self.containerS1,from_=10,to=1024,resolution=1,label='Largeur de la fenetre',orient='horizontal')
self.xWin.pack(fill=X)
self.xWin.set(300)
self.yWin=Scale(self.containerS1,from_=10,to=780,resolution=1,label='Hauteur de la fenetre',orient='horizontal')
self.yWin.pack(fill=X)
self.yWin.set(200)
self.containerS2=Frame(self.windowScene)
self.buttonS1=Button(self.containerS2,text='Valider',command=self.validScene)
self.buttonS1.pack(fill=X)
self.buttonS2=Button(self.containerS2,text='Annuler',command=self.windowScene.destroy)
self.buttonS2.pack(fill=X)
self.containerS1.pack(fill=X)
self.containerS2.pack(fill=X)
def addCube(self):
"""Ouverture d'une fenetre presentant les parametres du cube"""
try:
self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
except:
self.newScene()
self.windowCube=Toplevel()
self.windowCube.title('Inserer un cube')
self.containerP1=Frame(self.windowCube)
self.redCube=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
self.redCube.pack(fill=X)
self.greenCube=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
self.greenCube.pack(fill=X)
self.greenCube.set(1)
self.blueCube=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
self.blueCube.pack(fill=X)
self.containerP2=Frame(self.windowCube)
self.x0Cube=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
self.x0Cube.pack(fill=X)
self.y0Cube=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
self.y0Cube.pack(fill=X)
self.z0Cube=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
self.z0Cube.pack(fill=X)
self.containerP3=Frame(self.windowCube)
self.xxCube=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Taille x',orient='horizontal')
self.xxCube.pack(fill=X)
self.xxCube.set(30)
self.yyCube=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Taille y',orient='horizontal')
self.yyCube.pack(fill=X)
self.yyCube.set(30)
self.zzCube=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Taille z',orient='horizontal')
self.zzCube.pack(fill=X)
self.zzCube.set(30)
self.containerP4=Frame(self.windowCube)
self.buttonP1=Button(self.containerP4,text='Valider',command=self.validCube)
self.buttonP1.pack(fill=X)
self.buttonP2=Button(self.containerP4,text='Annuler',command=self.windowCube.destroy)
self.buttonP2.pack(fill=X)
self.containerP1.pack(side='left',fill=X)
self.containerP2.pack(side='left',fill=X)
self.containerP3.pack(side='left',fill=X)
self.containerP4.pack(side='bottom',fill=X)
self.yscrollbar.config(command=self.interface.yview)
def validCube(self):
"""Creation du cube"""
self.interface.insert('end',"Creation du cube.\n...")
self.cube=box(pos=(self.x0Cube.get(),self.y0Cube.get(),self.z0Cube.get()), size=(self.xxCube.get(),self.yyCube.get(),self.zzCube.get()),color=(self.redCube.get(),self.greenCube.get(),self.blueCube.get()))
self.windowCube.destroy()
self.yscrollbar.config(command=self.interface.yview)
def addBall(self):
"""Ouverture d'une fenetre presentant les parametres du cube"""
try:
self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
except:
self.newScene()
self.windowBall=Toplevel()
self.windowBall.title('Inserer un cube')
self.containerP1=Frame(self.windowBall)
self.redBall=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
self.redBall.pack(fill=X)
self.redBall.set(1)
self.greenBall=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
self.greenBall.pack(fill=X)
self.blueBall=Scale(self.containerP1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
self.blueBall.pack(fill=X)
self.containerP2=Frame(self.windowBall)
self.x0Ball=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
self.x0Ball.pack(fill=X)
self.y0Ball=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
self.y0Ball.pack(fill=X)
self.z0Ball=Scale(self.containerP2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
self.z0Ball.pack(fill=X)
self.containerP3=Frame(self.windowBall)
self.rayBall=Scale(self.containerP3,from_=0,to=500,resolution=1,label='Rayon',orient='horizontal')
self.rayBall.pack(fill=X)
self.rayBall.set(30)
self.containerP4=Frame(self.windowBall)
self.buttonP1=Button(self.containerP4,text='Valider',command=self.validBall)
self.buttonP1.pack(fill=X)
self.buttonP2=Button(self.containerP4,text='Annuler',command=self.windowBall.destroy)
self.buttonP2.pack(fill=X)
self.containerP1.pack(side='left',fill=X)
self.containerP2.pack(side='left',fill=X)
self.containerP3.pack(side='left',fill=X)
self.containerP4.pack(side='bottom',fill=X)
self.yscrollbar.config(command=self.interface.yview)
def validBall(self):
"""Creation du cube"""
self.interface.insert('end',"Creation de la boulle.\n...")
self.ball=sphere(pos=(self.x0Ball.get(),self.y0Ball.get(),self.z0Ball.get()), radius=self.rayBall.get(),color=(self.redBall.get(),self.greenBall.get(),self.blueBall.get()))
self.windowBall.destroy()
self.yscrollbar.config(command=self.interface.yview)
def addCylinder(self):
"""Ouverture d'une fenetre presentant les parametres du cylindre"""
try:
self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
except:
self.newScene()
self.windowCylinder=Toplevel()
self.windowCylinder.title('Inserer un cylindre')
self.containerCy1=Frame(self.windowCylinder)
self.redCylinder=Scale(self.containerCy1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
self.redCylinder.pack(fill=X)
self.greenCylinder=Scale(self.containerCy1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
self.greenCylinder.pack(fill=X)
self.blueCylinder=Scale(self.containerCy1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
self.blueCylinder.pack(fill=X)
self.blueCylinder.set(1)
self.containerCy2=Frame(self.windowCylinder)
self.x0Cylinder=Scale(self.containerCy2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
self.x0Cylinder.pack(fill=X)
self.y0Cylinder=Scale(self.containerCy2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
self.y0Cylinder.pack(fill=X)
self.z0Cylinder=Scale(self.containerCy2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
self.z0Cylinder.pack(fill=X)
self.containerCy3=Frame(self.windowCylinder)
self.xxCylinder=Scale(self.containerCy3,from_=-500,to=500,resolution=1,label='Taille x',orient='horizontal')
self.xxCylinder.pack(fill=X)
self.xxCylinder.set(30)
self.yyCylinder=Scale(self.containerCy3,from_=-500,to=500,resolution=1,label='Taille y',orient='horizontal')
self.yyCylinder.pack(fill=X)
self.yyCylinder.set(30)
self.zzCylinder=Scale(self.containerCy3,from_=-500,to=500,resolution=1,label='Taille z',orient='horizontal')
self.zzCylinder.pack(fill=X)
self.zzCylinder.set(30)
self.containerCy4=Frame(self.windowCylinder)
self.rayCylinder=Scale(self.containerCy3,from_=0,to=500,resolution=1,label='Rayon',orient='horizontal')
self.rayCylinder.pack(fill=X)
self.rayCylinder.set(30)
self.containerCy5=Frame(self.windowCylinder)
self.buttonCy1=Button(self.containerCy5,text='Valider',command=self.validCylinder)
self.buttonCy1.pack(fill=X)
self.buttonCy2=Button(self.containerCy5,text='Annuler',command=self.windowCylinder.destroy)
self.buttonCy2.pack(fill=X)
self.containerCy1.pack(side='left',fill=X)
self.containerCy2.pack(side='left',fill=X)
self.containerCy3.pack(side='left',fill=X)
self.containerCy4.pack(side='left',fill=X)
self.containerCy5.pack(side='bottom',fill=X)
self.yscrollbar.config(command=self.interface.yview)
def validCylinder(self):
"""Creation du cylindre"""
self.interface.insert('end',"Creation du cylindre\n...")
self.cylindre=cylinder(pos=(self.x0Cylinder.get(),self.y0Cylinder.get(),self.z0Cylinder.get()),axis=(self.xxCylinder.get(),self.yyCylinder.get(),self.zzCylinder.get()),radius=self.rayCylinder.get(),color=(self.redCylinder.get(),self.greenCylinder.get(),self.blueCylinder.get()))
self.windowCylinder.destroy()
self.yscrollbar.config(command=self.interface.yview)
def addCone(self):
"""Ouverture d'une fenetre presentant les parametres du cone"""
try:
self.interface.insert('end',"Codage de la scene : "+str(self.scene)+").\n...")
except:
self.newScene()
self.windowCone=Toplevel()
self.windowCone.title('Inserer un cone')
self.containerCo1=Frame(self.windowCone)
self.redCone=Scale(self.containerCo1,from_=0,to=1,resolution=0.01,label='Rouge',orient='horizontal')
self.redCone.pack(fill=X)
self.redCone.set(1)
self.greenCone=Scale(self.containerCo1,from_=0,to=1,resolution=0.01,label='Vert',orient='horizontal')
self.greenCone.pack(fill=X)
self.greenCone.set(1)
self.blueCone=Scale(self.containerCo1,from_=0,to=1,resolution=0.01,label='Bleu',orient='horizontal')
self.blueCone.pack(fill=X)
self.containerCo2=Frame(self.windowCone)
self.x0Cone=Scale(self.containerCo2,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
self.x0Cone.pack(fill=X)
self.y0Cone=Scale(self.containerCo2,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
self.y0Cone.pack(fill=X)
self.z0Cone=Scale(self.containerCo2,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
self.z0Cone.pack(fill=X)
self.containerCo3=Frame(self.windowCone)
self.xxCone=Scale(self.containerCo3,from_=-500,to=500,resolution=1,label='Taille x',orient='horizontal')
self.xxCone.pack(fill=X)
self.xxCone.set(30)
self.yyCone=Scale(self.containerCo3,from_=-500,to=500,resolution=1,label='Taille y',orient='horizontal')
self.yyCone.pack(fill=X)
self.yyCone.set(30)
self.zzCone=Scale(self.containerCo3,from_=-500,to=500,resolution=1,label='Taille z',orient='horizontal')
self.zzCone.pack(fill=X)
self.zzCone.set(30)
self.containerCo4=Frame(self.windowCone)
self.rayCone=Scale(self.containerCo3,from_=0,to=500,resolution=1,label='Rayon',orient='horizontal')
self.rayCone.pack(fill=X)
self.rayCone.set(30)
self.containerCo5=Frame(self.windowCone)
self.buttonCo1=Button(self.containerCo5,text='Valider',command=self.validCone)
self.buttonCo1.pack(fill=X)
self.buttonCo2=Button(self.containerCo5,text='Annuler',command=self.windowCone.destroy)
self.buttonCo2.pack(fill=X)
self.containerCo1.pack(side='left',fill=X)
self.containerCo2.pack(side='left',fill=X)
self.containerCo3.pack(side='left',fill=X)
self.containerCo4.pack(side='left',fill=X)
self.containerCo5.pack(side='bottom',fill=X)
self.yscrollbar.config(command=self.interface.yview)
def validCone(self):
"""Creation du cone"""
self.interface.insert('end',"Creation du cone\n...")
self.leCone=cone(pos=(self.x0Cone.get(),self.y0Cone.get(),self.z0Cone.get()),axis=(self.xxCone.get(),self.yyCone.get(),self.zzCone.get()),radius=self.rayCone.get(),color=(self.redCone.get(),self.greenCone.get(),self.blueCone.get()))
self.windowCone.destroy()
self.yscrollbar.config(command=self.interface.yview)
def paramAnim(self):
"""Lancement d'une animation de type rotation de la camera autours du point central selon x"""
self.windowAnim=Toplevel()
self.windowAnim.title=("Parametres de l'animation")
self.containerAn1=Frame(self.windowAnim)
self.x0Anim=Scale(self.containerAn1,from_=-500,to=500,resolution=1,label='Origine x',orient='horizontal')
self.x0Anim.pack(fill=X)
self.y0Anim=Scale(self.containerAn1,from_=-500,to=500,resolution=1,label='Origine y',orient='horizontal')
self.y0Anim.pack(fill=X)
self.z0Anim=Scale(self.containerAn1,from_=-500,to=500,resolution=1,label='Origine z',orient='horizontal')
self.z0Anim.pack(fill=X)
self.z0Anim.set(-1)
self.containerAn2=Frame(self.windowAnim)
self.xTemp=Entry(self.containerAn2)
self.xTemp.pack(fill=X)
self.xTemp.insert('0','xt=-1+sin(2*pi*t/30)')
self.yTemp=Entry(self.containerAn2)
self.yTemp.pack(fill=X)
self.yTemp.insert('0','yt=-0.5')
self.zTemp=Entry(self.containerAn2)
self.zTemp.pack(fill=X)
self.zTemp.insert('0','zt=cos(2*pi*t/30)-1')
self.zoomTemp=Entry(self.containerAn2)
self.zoomTemp.pack(fill=X)
self.zoomTemp.insert('0','zoomt='+str(self.scene.range[0])+'+40*t**2-100*t')
self.totalTime=Scale(self.containerAn2,from_=0.1,to=60,resolution=0.1,label='Temps total',orient='horizontal')
self.totalTime.pack(fill=X)
self.totalTime.set(1)
self.containerAn3=Frame(self.windowAnim)
self.buttonAn1=Button(self.containerAn3,text='Valider',command=self.validAnim)
self.buttonAn1.pack(fill=X)
self.buttonAn1=Button(self.containerAn3,text='Exporter',command=self.exportAnim)
self.buttonAn1.pack(fill=X)
self.buttonAn2=Button(self.containerAn3,text='Annuler',command=self.windowAnim.destroy)
self.buttonAn2.pack(fill=X)
self.containerAn1.pack(side='left',fill=X)
self.containerAn2.pack(side='left',fill=X)
self.containerAn3.pack(side='bottom',fill=X)
def validAnim(self):
"""Lance l'animation en fonction des equations donnes par l'utilisateur"""
t=0
dt=0.01
finished=False
self.scene.forward=(self.x0Anim.get(),self.y0Anim.get(),self.z0Anim.get())
while not finished:
rate(100)
exec(self.xTemp.get())
exec(self.yTemp.get())
exec(self.zTemp.get())
exec(self.zoomTemp.get())
self.scene.range=(zoomt,zoomt,zoomt)
self.scene.forward=(xt,yt,zt)
t+=dt
if t>=self.totalTime.get():
finished=True
#self.windowAnim.destroy()
def exportAnim(self):
"""Exporter l'animation"""
t=0
dt=0.01
finished=False
cpt=0
self.scene.forward=(self.x0Anim.get(),self.y0Anim.get(),self.z0Anim.get())
while not finished:
rate(100)
exec(self.xTemp.get())
exec(self.yTemp.get())
exec(self.zTemp.get())
exec(self.zoomTemp.get())
self.scene.range=(zoomt,zoomt,zoomt)
self.scene.forward=(xt,yt,zt)
t+=dt
try:
povexport.export(display=self.scene, filename='monVpython'+str(cpt)+'.POV')
self.interface.insert('end',"Fichier exporte avec succes\n...")
#os.popen('D:\\POV\\bin\\pvengine.exe monVpython'+str(cpt)+'.POV')
except:
self.interface.insert('end',"Erreur lors de l'exportation du fichier\n...")
self.yscrollbar.config(command=self.interface.yview)
cpt+=1
if t>=self.totalTime.get():
finished=True
root=Tk()
myapp=PyIGU3D(root)
root.mainloop()
Conclusion
Si quelqu'un veut ajouter des fonctionnalités et faire avancer le code pour mieux exploiter le module, ce serait un plaisir. Pour les possibles mises à jour, ou pour le plaisir, aller faire un tour sur mon site : http://gdaveau.free.fr
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
scrollbar dans scrollbox avec TKinter [ par MHI ]
Est-ce que quelqu'un sait comment ajouter les scrollbar à une scrollbox :J'ai essayé ceci :lstFile = Tkinter.Listbox(frmMain)lstFile.place(x = 20, y =
checkButton avec TKinter [ par MHI ]
comment faire pour tester si un checkButton est coché ?
Probleme avec TKinter [ par titasse ]
Bonjour, je debute en python. J'ai un probleme lorsque je veux importer TKinter avec la commande from TKinter import * j'ai le message suivant : Imp
au sujet de Tkinter et le module turtle [ par nico1900 ]
from turtle import *forward(120)left(90) color('red') forward(80)bon en fait je voulais tester le module turtle avec l e code ci-d
Un Canvas comme dans Tkinter, mais pour wxPython [ par samurize ]
Slt tout le monde. Voila tout est dans le titre (ou a peu pres ) : Je suis à la recherche d'un module pouvant s'integrer da
Taille de widgets sous Tkinter [ par Uims ]
Bonjour, Quelqu"un saurait comment definir la taille d'un widgets sous tkinter??? Exemple: fen 1 = Tk(taille=600) J'espere que je me fait comprend
Ouverture d'un fichier windows (avec Tkinter) [ par Uims ]
Bonjour, Je travaille sous python et Tkinter et j'aurai voulu savoir comment dire a python de demarrer (comme on clique sur un fichier) une applicati
Tkinter et Python [ par Telimektar1er ]
Voila j'ai commencé e python il y a une semaine et jusqu à aujourd'hui aucun problème. Mais voilà, je viens de commencer la cr
help, faire un mastermind en python et en tkinter avant le 24 !!! [ par Crick132 ]
je suis étudiante en 2ème année, je dois réaliser un mastermind en python avec 8 couleurs et 5 combinaisons possibles.si quelqu'un
Importer une image dans Tkinter... [ par skools ]
Bonjour à tous, Et pardon à ceux à qui j'ai envoyé des messages perso, je n'arrivais pas à poster un suget dans le forum... Voilà, après des heures d
|
Derniers Blogs
CSS CONTENT STATE SELECTORS (PERSONNAL DRAFT)CSS CONTENT STATE SELECTORS (PERSONNAL DRAFT) par FREMYCOMPANY
Bonjour à tous, Je viens de publier une proposition comprenant 5 pseudo-classes pour le CSS Working Group ayant trait à l'état de chargement d'un élément (ex: IMG,VIDEO,AUDIO,OBJECT pour l'HTML.). Si le c½ur vous en dit, vous pouvez retrouver cette p...
Cliquez pour lire la suite de l'article par FREMYCOMPANY MBA : POURQUOI FAIRE ET COMMENT LE CHOISIR ?MBA : POURQUOI FAIRE ET COMMENT LE CHOISIR ? par ROMELARD Fabrice
Formation initiale Durant la formation, le découpage classique est le suivant (je donnerai les équivalences Suisse lorsque je les connaîtrais) : Ecole primaire jusqu'au Collège : Formation générale permettant d'obtenir les méthodes...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice Y'A DES ERREURS QUI PEUVENT RENDRE LE DéVELOPPEUR VIOLENTY'A DES ERREURS QUI PEUVENT RENDRE LE DéVELOPPEUR VIOLENT par Aleks
Quand on a ce genre d'erreur sans log :
Et bas on a juste envie de choper le gas de Microsoft qu'a développé ça et lui foutre des baffes de Coboye ! ...
Cliquez pour lire la suite de l'article par Aleks [HYPER-V 3] PRéSENTATION DES COMMANDLETS POWERSHELL[HYPER-V 3] PRéSENTATION DES COMMANDLETS POWERSHELL par Pierrick CATRO-BROUILLET
Avec la sortie prochaine de la Beta Consumer Preview de Windows 8, j'avais envie de revenir sur une des fonctionnalités que j'attends le plus et que, en bon geek que je suis, j'utilise déjà : Hyper-V 3 ainsi son module PowerShell.
Il y a déjà pléthor...
Cliquez pour lire la suite de l'article par Pierrick CATRO-BROUILLET IIS7 - COMPRESSION GZIPIIS7 - COMPRESSION GZIP par cyril
La compression GZIP permet d'améliorer les performances de navigation en compressant ce qu'envoie le serveur à un client. Pour comprendre comment cela fonctionne, regardons ce qu'il se passe au niveau HTTP lorsqu'un client tente d'accéder à une ress...
Cliquez pour lire la suite de l'article par cyril
Forum
PYVISA PROBLèMEPYVISA PROBLèME par sandrine44
Cliquez pour lire la suite par sandrine44
Logiciels
Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning Academy System (17.1.3.0)ACADEMY SYSTEM (17.1.3.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|