Sommaire
Créer une courbe dans CATIA V5 à partir d’un fichier de coordonnées XY
Une question qui revient souvent
Une question qui revient souvent dans le monde des utilisateurs de profils d’aile (ou airfoils in English):
- Concepteurs d’avions grandeur
- aéromodélistes
- concepteur d’éolienne
- créateurs de planche de surf
- …
Le début
Cela commence par le choix du profil. Quelques logiciels et sites internet comme AirfoilTools.com nous permettent de télécharger les coordonnées cartésiennes des points définissants l’extrados et l’intrados des profils.
En aérodynamique, un profil est défini comme suit:
- L’origine du profil est donné comme étant le point de tangence entre le bord d’attaque du profil et une verticale.
- La longueur du profil est normalisée sur une abscisse sans dimension (le profil s’étend donc de 0 à 1 du bord d’attaque vers le bord de fuite).
- Les ordonnées sont données pour l’extrados puis pour l’intrados de façon proportionnelle à l’abscisse (également sans dimension dans la table)
- Le profil est orienté selon la corde de profil (la distance la plus longue entre le bord d’attaque et le bord de fuite) qui devient donc l’axe des abscisses
Cela donne un fichier structuré de la façon suivante:
Les coordonnées XY des deux courbes sont données l’une après l’autre en partant du bord de fuite pour décrire l’Extrados jusqu’au bord d’attaque puis l’Intrados vers le bord de fuite.
NACA 4418 1.0000 0.0019 Point final du Bord de fuite de l’EXTRADOS 0.9500 0.0189 | 0.9000 0.0346 | … | … | (Abscisses décroissantes) 0.0250 0.0500 | 0.0125 0.0376 | 0.0000 0.0000 Point origine du profil (Bord d’attaque) 0.0125 -0.0211 | 0.0250 -0.0299 | … | … | 0.7000 -0.0245 | 0.8000 -0.0167 | (Abscisses croissantes) 0.9000 -0.0093 | 0.9500 -0.0055 | 1.0000 -0.0019 Point final du Bord de fuite de l’INTRADOS
C’est le format proposé par défaut sur Airfoil tools (Lednicer format)
Important:
Vos fichiers de points doivent absolument avoir cette structure (format Selig qui est différent de Lednicer) pour que le programme puisse fonctionner, vous pouvez ajouter des lignes de commentaire en en-tête mais veillez à ce que la dernière ligne soit bien les dernières coordonnées du profil (pas de retour chariot après la dernière ligne).
Pas si facile
Catia comme ses concurrents n’offre pas nativement de fonction permettant de créer une courbe à partir d’un fichier de coordonnées nodales… Dommage, il faut donc passer par une macro pour faire cela.
Comment s’y prendre:
- Soit réaliser un CatScript ou une VBScript
- Soit comme ici mixer un peu de Python et de VBScript
Dans cette excellente et très instructive présentation de son logiciel Decade , Thomas Paviot nous explique comment l’utilisation de la passerelle win32com nous permet d’atteindre CatiaV5 depuis l’extérieur (ici Python) et de le piloter à l’aide d’instructions du type CatVba.
L’utilisation dans le détail:
Python doit être installé sur votre machine Windows ainsi que win32com.
Rien de plus facile mais il faut installer d’abord Python (choisir votre version 2.x ou 3.x) puis installer la version de win32com correspondant en second lieu).
Vous devez avoir créé un répertoire de travail dans lequel doit être déposé les programmes Python que vous pouvez télécharger en bas de page.
Sous ce répertoire doit se trouver le répertoire dans lequel vous déposerez vos fichiers texte définissant vos profils (ici NACA dans lequel on trouve Naca4418.txt récupéré sur Airfoiltools).
Catia doit être lancé (il n’y a pas de Catpart à charger en prérequis)
Lançons ensuite le programme principal 01_Createur_profil.py (Vous trouverez un lien en bas de page pour récupérer les programmes python).
Ce programme appelle les sous-programmes permettant de :
- Lire le fichier texte du profil et créer les listes de coordonnées XY que le fichier en contient soit extrados et intrados ( _Recup_profil.py et _lect_profil.py )
- Créer une Catpart avec les set géométriques nécessaires ( _NewPart_profil.py )
- Créer les courbes de Bézier passant par les points de définition de chaque courbe ( _Courbe_TxtCv5.py )
A la fin du traitement, on obtient une Catpart présentant:
- un profil de 100 mm constitué de 2 courbes de Bézier désignée Spline_Extrados et Spline_Intrados.
- Les points sont dans des sets géométriques que l’on peut cacher.
- La Catpart est nommée Profil_[Nom du profil.txt] et est sauvegardée dans le répertoire de travail
- Les deux courbes sont publiées pour une utilisation future.
A partir de cette base, on peut simplement dupliquer les courbes et les placer plus loin comme ici avec une opération scale et tirer deux peaux entres les courbes d’extrados et d’intrados. Il est tout aussi facile de rajouter une rotation du profil externe pour vriller l’aile (ou la pale).
Bref, le plus dur est fait, à vous de jouer pour le reste avec amusement et créativité.
Avant de finir, je vous conseille de créer votre aile, pale d’hélice, safran, etc… dans une autre catpart en lien avec la/les “part profil” comme cela si vous voulez changer un ou plusieurs profils cela se fera simplement en re-pointant vers une autre part profil et la magie s’opèrera facilement le temps d’un Update).
En images animées cela donne ceci:
Les programmes Python
Le programme principal à la loupe:
Je n’ai pas voulu surcharger le programme Python avec une IHM ou une quelconque interactivité.
Vous pouvez bien sûr l’améliorer si bon vous semble.
Ici pour vos besoins du jour, il faudra juste éditer ce programme avec votre éditeur Python préféré (IDLE par exemple) et modifier deux variables:
- La variable Chemin_txt_profil = « NACA » donne le nom du répertoire dans lequel se trouve les profils en fichier text. Si vous utilisez autrechose que du NACA, créez un autre répertoire et changez la valeur de la variable.
- La variable Nom_profil = « NACA4418 » donne le nom du fichier txt à utiliser dans le répertoire de profils ici une classique NACA4418.
et ensuite F5 pour lancer l’exécution… Enjoy !
# -*- coding: ISO-8859-1 -*-
####################################################################
# #
# Programme permettant de tracer un profil d'aile dans Catia V5 #
# à partir d'un fichier texte de coordonnées XY donné #
# #
# PSX59 #
# Apprendre-la-CAO.com #
####################################################################
import sys, os
from _NewPart_profil import Cree_NewPart_profil
from _Recup_profil import Recup_profil
# Recupère le répertoire de travail
try:
dir_path = os.path.dirname(os.path.abspath(__file__))
except NameError: # We are the main py2exe script, not a module
import sys
dir_path = os.path.dirname(os.path.abspath(sys.argv[0]))
print 'repertoire de travail: \n',dir_path
# Définition du répertoire de stockage des profils
Chemin_txt_profil = "NACA"
# Définition du nom du profil à tracer dans CV5
Nom_profil = "NACA4418"
#######################
# Programme principal #
#######################
#Cree une nouvelle part avec les sets geom prédéfinis
Cree_NewPart_profil(dir_path,"Profil_"+Nom_profil,"Profil_"+Nom_profil)
print ("Part creee")
#Recupération du profil et creation dans catia
Recup_profil(Nom_profil,"Profil_"+Nom_profil,"Profil_"+Nom_profil,dir_path+"//"+Chemin_txt_profil)
print ("Profil "+Nom_profil+" cree et Catpart sauvegardee dans le repertoire de travail")
_NewPart_profil.py à la loupe:
# -*- coding: ISO-8859-1 -*-
def Cree_NewPart_profil(Chemin,Nom_part,Nom_set):
import win32com.client
CATIA=win32com.client.Dispatch('catia.application') #->la communication est établie
PartDoc = CATIA.Documents.Add("Part")
partDocument1 = CATIA.ActiveDocument
#recup nom de la part
Nom_ProvisoirComplet_CATPart = partDocument1.Name
Coupure_Nom_provisoir_CATPart = Nom_ProvisoirComplet_CATPart.split(".")
Nom_prov_CatPart = Coupure_Nom_provisoir_CATPart[0]
#change le nom de la part
part1 = partDocument1.Part
parameters1 = part1.Parameters
Nom_parametre = str(Nom_prov_CatPart) + "\Référence"
strParam1 = parameters1.Item(Nom_parametre)
strParam1.Value = Nom_part
#creation du set geom pour le profil
hybridBodies1 = PartDoc.Part.HybridBodies
Set_Import = hybridBodies1.Add()
print Nom_set
Set_Import.Name = Nom_set
part1.Update()
# Sauvegarde de la part
#print Chemin + "\\" + Nom_part + ".CATPart"
partDocument1.SaveAs(Chemin + "\\" + Nom_part + ".CATPart")
_Recup_profil.py à la loupe:
# -*- coding: cp1252 -*-
from _lect_profil import lect_profil
from _Courbe_TxtCv5 import Courbe_CV5
def Recup_profil(Nom_profil,Set_geom, Nom_part, Rep):
Chemin_Fich = Rep + "\\" + Nom_profil + ".txt"
print Chemin_Fich
Coord_Nds_Txt = lect_profil(Chemin_Fich) #On lit le fichier texte
print len(Coord_Nds_Txt)
Nom_courbes = ['Extrados','Intrados']
a = 0
for Liste in Coord_Nds_Txt: #pour chacune des deux courbes...
if Liste==[]:
pass
else:
Courbe_CV5(Nom_courbes[a] , Liste, Set_geom, Nom_part) #On crée les courbes dans Catia
a = a + 1
return 'profil ',Nom_profil,' charge'
_lect_profil.py à la loupe:
# -*- coding: ISO-8859-1 -*-
def lect_profil(Chemin_Fich):
#lect_profil("G:/Etudes_avions/Sites_web/Apprendre_la_CAO/Sujets/Profil_aile/NACA/NACA4418_airfoiltools.txt")
Fichier_profil = open(Chemin_Fich, 'r')
Liste_ligne = Fichier_profil.readlines()
Nb_lignes = len (Liste_ligne)
print ("nombre de lignes dans le fichier : " + str(Nb_lignes))
Liste1 = [] #extrados
Liste2 = [] #intrados
Liste_coord = [Liste1, Liste2]
X = 1
a = 0 #Numéro de ligne
while a < Nb_lignes:
print 'ligne N°',a
Elem_ligne = Liste_ligne[a].split()
print '--->', Elem_ligne
try:
premier_elem = round(float(Elem_ligne[0]),6)
second_elem = round(float(Elem_ligne[1]),6)
except:
print 'ligne inutile'
print 'ligne decoupée',Elem_ligne
a = a + 1
else:
deltaX = X - premier_elem #X est l'ancienne valeur d'abscisse et premier_elem est l'abscisse actuelle
X = premier_elem
Y = second_elem
if deltaX >= 0: #Abscisses décroissantes ?
Liste1.append([X,Y])
print 'Liste1 -->',[X,Y]
a=a+1
if X == 0.000: #lorsque l'on tombe sur le point origine on le duplique en l'ajoutant à la liste2
Liste2.append([0.00,0.00])
if deltaX < 0: #Abscisses croissantes ?
Liste2.append([X,Y])
print 'Liste2 -->',[X,Y]
a=a+1
return Liste_coord
_Courbe_TxtCv5.py à la loupe:
# -*- coding: ISO-8859-1 -*-
import win32com.client
def Courbe_CV5(a , Liste, Set_geom, Nom_part):
CATIA=win32com.client.Dispatch('catia.application') #->la communication est établie
PartDoc = CATIA.ActiveDocument
part1 = PartDoc.Part
sel = PartDoc.Selection
sel.Clear()
#ouvre le SET geom du profil
hybridBodies1 = PartDoc.Part.HybridBodies
hybridBody_import = hybridBodies1.Item(Set_geom)
hybridBodies2 = hybridBody_import.HybridBodies
#cree un set pour la courbe
hybridBody_Courbe = hybridBodies2.Add()
hybridBody_Courbe.Name = "Courbe_" + a
if Liste==[]:
pass
else:
hybridShapes1 = hybridBody_Courbe.HybridShapes
b = 1
for Coord in Liste:
X = Coord[0]*100 # modifiez ici si vous voulez modifier l'échelle du profil (ici 100 fois plus grand soit 100mm de long) Rappel: le profil à une longueur de 1 (sans unité). Si le fcteur vaut 1 alors cela fera 1mm dans catia
Y = Coord[1]*100 # idem
Point1 = part1.HybridShapeFactory.AddNewPointCoord(X, Y, 0) #cree le point de ccord XY
hybridBody_Courbe.AppendHybridShape(Point1)
sel.Add(Point1)
Point1.Name = "Point_" + str(b) # renomme le point
part1.UpdateObject(Point1)
b = b + 1
Nb_pt_dans_set = hybridShapes1.Count #compte les points
print 'Nb points = ',Nb_pt_dans_set
hybridShapeSpline1 = part1.HybridShapeFactory.AddNewSpline() #cree une spline vide
hybridShapeSpline1.SetSplineType(0)
hybridShapeSpline1.SetClosing(0)
hybridShapeSpline1.Name = "Spline_" + str(a) # Nomme la spline
# Je n'ai pas ajouté de tangence verticale au point d'origine (normale au plan XY), il y aura donc une vraie arête au bord d'attaque à imposer manuellement dans catia sur chaque spline ou ajouter une contrainte dans ce script
nb = 1
while nb < Nb_pt_dans_set +1 :
hybridShapePointOnPlane1 = hybridShapes1.Item("Point_" + str(nb)) # appel le point par son nom
reference1 = part1.CreateReferenceFromObject(hybridShapePointOnPlane1)
hybridShapeSpline1.AddPoint(reference1) #ajoute le point à la spline
nb = nb + 1
hybridBody_import.AppendHybridShape(hybridShapeSpline1) #ajoute la spline au set geom
part1.UpdateObject(hybridShapeSpline1)
#Publication des courbes
PartDoc = CATIA.ActiveDocument
product1 = PartDoc.GetItem(Nom_part)
publications1 = product1.Publications
Nom_publication = Nom_part+"_Courbe_" + a
publication1 = publications1.Add(Nom_publication)
Nom_courbe = Nom_publication+"/!Spline_" + a
reference1 = product1.CreateReferenceFromName(Nom_courbe)
publications1.SetDirect (Nom_publication, reference1)
product1.update()
#Sauvegarde du profil
PartDoc.Save()
C’est fini : )
Vous pouvez facilement et gratuitement recopier les programmes Python ci-dessus. Vous pouvez également les arranger à votre goût et vous en inspirer.
J’espère que cet article vous a aidé à concevoir et vous a fait gagner du temps.
Si vous l’avez aimé, n’hésitez pas à partager sur les réseaux sociaux et me laisser un commentaire en bas de page.
12 Responses
Merci pour le sujet c’est très instructif sur tout pour la programmation VBSCRIPT et PYTHON.
J’utilise une autre approche
1- conception sur Alias studio Tools
2-translation sur UGS NX
3- conception des nervures d’ailes par intersection Plans/Surfaces d’ailes
4- traitement des nervures en Pars
5- Translation sur INVENTOR HSM
6- Création des programmes de FAO par assemblage et nesting des nervures
7- Fabrication des nervures sur CN
J’ai réalisé la structure d’un PULSARE ainsi que la conception et la fabrication d’un CANOE CANADIEN le « CARIBOU »
le lien youtube
https://www.youtube.com/watch?v=B4kLbwuUPLc&feature=youtu.be
Bonjour Abdelhamid,
Merci pour ce commentaire et bravo pour vos réalisations.
Je vois que nous partageons les mêmes passions.
Bravo pour vos réalisations, j’ai brièvement regardé vos vidéos sur Youtube.
Votre démarche de conception est intéressante. Elle met en œuvre beaucoup de logiciels et de passerelles mais le résultat est là, c’est bien le principal.
Cela montre également qu’il existe maintenant de nombreuses solutions CAO et CFAO.
Je suis en train de mettre à disposition des articles concernant la CFAO sur Catia V5.
Bonjour,
Lorsque je lance le programme, il me met une syntaxError « Missing Parentheses in call to ‘print’ et je ne comprend pas pourquoi!
Bonjour Philippe,
Merci pour votre retour.
Je pense qu’il s’agit simplement d’un problème de version de Python. En effet, j’ai peut être oublié de le préciser mais le programme est écrit en Python 2.7 et la fonction « print » ne demande pas de parenthèses alors qu’en Python 3.4 il en faut. Vérifiez dans votre message d’erreur, mais cela doit être le cas.
Il y a quelques différences entre la version 2.x et la version 3.x au niveau de la syntaxe. Le plus simple serait peut être que vous installiez Python 2.7 à coté de la 3.4.
Il faut cependant faire attention au fait que votre PC lance bien la 2.7 (voir dans system/path) lorsque vous exécutez le *.py . Ou alors vous désinstallez la 3.x pour laisser seule la 2.7.
Bonjour,
Je voudrais faire une aile d’avion mais ce que vous expliquez en macro est incompréhensible.
Comment pourrez faire une aile sur catia svp?
Bonjour Badara,
Oui, en effet cet article montre comment obtenir un profil d’aile à partir d’un fichier de coordonnées à l’aide d’une macro.
Vous n’avez pas forcément besoin d’utiliser une macro pour dessiner les profils de l’aile.
Il suffit de tracer dans une esquisse tous les points du profil de votre choix puis de relier les points avec une courbe (spline) pour tracer l’extrados et l’intrados.
C’est un peu long mais faisable.
Une fois que vous avez les profils aux bons endroits, vous pouvez tendre une peau entre ces profils; cela vous donnera votre aile.
Bonjour PSX59 (je vais t’appeler Chef vu que tu t’y connais mieux que moi),
Merci pour ta réaction si rapide.
Y aurait-il pas une vidéo qui illustre ça sur catia, parce que j’ai vu et lue le lien mais ça ne m’aide vraiment pas.
En fait, je n’ai rien dans l’immédiat pour illustrer cela mais je pourrai faire un article là dessus si ce n’est pas trop pressant.
J’ai compris que votre objectif est de faire la surface d’une aile à partir de profils. C’est bien cela ?
Bonjour Chef,
Vous avez très bien compris, mon objectif est de pouvoir faire la surface d’aile, le fuselage d’un avion à partir de profil..
Bonsoir,
Merci pour ce tuto tres interessant.
Helas, j’utilise CATIA V5.12 et lorsque j’execute le programme 01_Createur_profil, j’obtiens seulement Part1.
Il me semble que cela bloque sur Hybridbodies, qui n’existe pas dans CATIA V5.12.
Est-il possible d’utiliser directement Courbe ?
Bonjour,
Merci pour ce retour.
En R12, je pense les « sets géométriques » (=HybridBodies) existaient déjà.
Il faut savoir où cela bloque précisément (quel sous programme et quelle ligne).
Pourriez vous m’envoyer le message d’erreur de Python ?
Bonsoir,
je vous envois une impression d’ecran par mail.