Accueil

 
.

Script : Déplacement selon un axe quelconque

 

Vous pouvez télécharger le script ici

But du script :

Il permet de déplacer un groupe de points selon une direction donnée par l'utilisateur à l'aide de 2 points d'un mesh.

Comment se servir du script :

1. Lancez le script à l'aide du combo Alt+P dans la fenêtre de texte

2. Sélectionnez les deux points de votre mesh qui forment la direction du déplacement (ces deux points peuvent être quelconques dans le mesh).
3. Sortez du mode Edition mais conservez l'objet qui contient ces deux points sélectionné.

4. Appuyez sur le premier bouton en haut : "Capter Direction"


---> vous verrez alors les coordonnées du vecteur unitaire dirigeant le déplacement apparaître en dessous. (*)

 

5. Sélectionnez maintenant le groupe de points à bouger (éventuellement dans un autre objet de type mesh).
6. Sortez du mode Edition mais conservez l'objet qui contient ces points sélectionné.

7. Appuyez sur le second bouton au milieu: "Capter Points a bouger"


---> vous verrez alors des empty se créer dans la vue 3D à la position des points à bouger et orientés par la direction du mouvement.

 

8. Toujours en mode Objet (pas en Edit mode!) utilisez le dernier bouton en bas de type slider.(**)


---> vous verrez vos points se déplacer du nombre d'unité Blender à partir de la position initiale dans la direction choisie.


Vous pouvez répéter les opérations précédentes à partir de 2 ou de 5 autant de fois que désiré sans quitter le script.
Pour quitter le script : Q ou Esc.

Voilà c'est aussi "simple" que ça, Happy modeling ;)

(**)Ce bouton à glissière permet de balayer une très large zone de déplacement :
Il varie au début entre -5 et 5. Mais si on le lache entre (+/-)4 et (+/-)5, il vous permet maintenant de varier entre -100 et +100. De même si ensuite vous lachez entre (+/-)90 et (+/-)100 il variera de -500 à 500. Le processus est réversible.

(*)Si vous avez plus de deux points sélectionnés, la console devra vous afficher un avertissement mais c'est tout ce qui apparaîtra. La direction choisie risque alors d'être un peu fantaisiste. Si vous n'avez qu'un seul point sélectionné la direction sera celle entre le centre du monde et ce point.

Bugs connus :

...Si vous quittez le script directement sans effectuer aucun déplacement, il apparaîtra un popup d'erreur. Il n'est pas important, et n'altètre en rien vos données.
...Si le nombre de points capté par le script est important comparé au nombre, lors de la sortie du script il se peut que tous les empty ne soient pas supprimé. Cela n'influe en rien le reste de votre fichier et n'a aucune importance lors de la relance du script.
...

Comprendre le script :

Voici le script commenté pas à pas sans la partie GUI:

# import de tous les modules utiles (peut-être que j'en ai importé trop mais bon...)
import Blender
from Blender import *

from Blender import NMesh
from Blender.Draw import *
from Blender.BGL import *
from Blender import Mathutils
from math import *

#On commence par initialiser ce qui representera la direction (3 coordonnées du vecteur unitaire directeur de la droite de déplacement.
vx=0
vy=0
vz=0

# Fonction permettant d'obtenir le nom du mesh (data de l'objet) sélectionné
def lobj():

global nom
objet=Blender.Object.GetSelected()[0]
nom=objet.data.name
#print (nom)


#Fonction Principales

#Déplacement des points : requiers le nom du mesh et le "facteur" de déplacement
def depl(obj,k):

global vx, vy, vz, vo                #vo est une liste composé des postions initiales des points sélectionnés

mish=NMesh.GetRaw(obj)    #On sélectionne la liste de verticale de l'objet
i=0                                  #Mise à zéro du paramètre qui servira à trouver le bon idex dans la liste des positions initiale
for v in mish.verts:                 #Boucle qui fait varier "v" dans les points de tout le mesh

if v.sel==1:                # On ne fait la suite que si le point v est selectionné

v.co[0] = vo[i] + k*vx
v.co[1] = vo[i+1] + k*vy
v.co[2] = vo[i+2] + k*vz
#On a déplacé le point v de coordonnées v.co ("liste" à trois données)
# à partir de sa position initiale stocké dans vo aux rangs i à i+2
i+=3 
#On passe au point séléctionné suivant dans la liste des positions initiale.
#On notera ici l'importance de la similitude entre la création de la liste initiale et le déplacement.

mish.update()               # On rafraichi le mesh avec les nouvelles données

#Fonction permettant de donner les positions initiales des points captés --> besoin du nom du mesh
def valid(obj):

global vo
nbr=0               # mise a zéro de ce qui servira a compter le nombre de points sélectionné.
mish=NMesh.GetRaw(obj)               # obtenir le mesh
# On commence par compter le nombre de point sélectionnés à l'aide d'une boucle qui incrémente si elle rencontre un point sélectionné
for v in mish.verts:

if v.sel==1:

nbr+=1
#On peut à présent créé une liste de la bonne dimension (le nombre de point 'nbr' multiplié par le nombre de coordonnées d'un point (3)
vo=range(0,nbr*3,1)
#Stockage des données initiales de la même façon qu'on les utilise plus haut.
i=0
for v in mish.verts:

if v.sel==1:

vo[i]=v.co[0]
vo[i+1]=v.co[1]
vo[i+2]=v.co[2]
i+=3

print (vo)

# Fonction pour obtenir la direction
def trouv(obj):

global vx, vy, vz
mish=NMesh.GetRaw(obj)               # Mises a zéros, captage des info c'est toujours les mêmes notations
nbr=0
vx=0
vy=0
vz=0
for v in mish.verts:

if v.sel==1:               # On fait toujours cette boucle pour travailler que sur les points sélectionnés

nbr+=1               # on incrémente le nombre de points
if nbr==3:

print ('WARNING YOU HAVE SELECTED MORE THAN 2 VERTS')
# Du texte en anglais (c'est plus court que le français) : c'est le cas où on à plus de trois points sélectionnés

#On créé le vecteur entre les 2 points : vecteur(BA) a pour coordonnées : (coord. de A - coord. de B)
if nbr==2:

vx+= -v.co[0]
vy+= -v.co[1]
vz+= -v.co[2]

if nbr==1:

vx=v.co[0]
vy=v.co[1]
vz=v.co[2]

#Normalisation du vecteur pour pouvoir par la suite se déplacer en unité Blender
nrm=(vx**2+vy**2+vz**2)**(-0.5)
vx*=nrm
vy*=nrm
vz*=nrm

return (vx,vy,vz) # theoriquement ça sert a rien dans la suite. Je sais pas pourquoi je l'ai mis :o) lol

#Fonction annexe : Empty visuels

#fonction pour créer les empty visuel
def empty():

global vo, vy, vz, vx
delempty()                # on commence par supprimer les anciens emptys
nro=((len(vo))/3)
nrm=(vx**2+vy**2+vz**2)**(-0.5)

for i in range(0,nro):

n=str(i)
# soit on créé un nouvel empty soit on réutilise celui existant.
try:

empte = Blender.Object.Get("Point"+n)

except:

empte = Blender.Object.New('Empty',"Point"+n)

#On postionne l'empty sur le point
empte.LocX=vo[i*3]
empte.LocY=vo[i*3+1]
empte.LocZ=vo[i*3+2]
empte.setSize(1,0.2,0.2)
#on lui applique les rotations nécessaire pour obtenir une orientation suivant la direction de déplacement
#je me suis amusé à retrouver des genre de formule d'Euler après plusieurs tests.
# Il devait y avoir plus rapide avec les matrices
try:

empte.RotZ=atan(vy/vx)

except:

empte.RotZ=90

try:

empte.RotY=(-vz/abs(vz))*atan(vz/((vx**2+vy**2)**(0.5)))

except:

empte.RotY=0

#On lie l'empty à la scène courante
scene=Blender.Scene.GetCurrent()
scene.link(empte)
Blender.Redraw()

#Suppression des emptys
#Grand merci à _Ph_ et à son site : http://hp.home.chez.tiscali.fr/re_illusion/index.htm
def delempty():

global vo
#Même principe que pour la création
nro=((len(vo))/3)
#Ici la boucle for va jusqu'à 10 fois le nombre d'empty dernièrement capté.
#L'utilisation de try et except nous permet de faire autant de boucle que voulue.
for i in range(0,nro*10):

n=str(i)
print('boucle')
try:

empte = Blender.Object.Get("Point"+n)
scene=Blender.Scene.GetCurrent()
scene.unlink(empte)

except:

break

Blender.Redraw()


#################
#Partie Affichage non détaillé ...
#################

Attention il manque une partie de ce script. Sa présence ici n'est que pour les explications.
Pour le télécharger : ici