1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2016-2022 CEA/DEN, EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 """Obtention des surfaces médianes à partir d'un objet GEOM ou SHAPER
22 On sait traiter les faces :
29 Pour un objet complexe, on crée l'objet final comme étant la partition de toutes
30 les surfaces médianes.
32 Version initiale par :
33 alexandre.prunie@blastsolutions.io
34 guillaume.schweitzer@blastsolutions.io
39 __revision__ = "V11.03"
41 #========================= Les imports - Début ===================================
53 from SketchAPI import *
54 from salome.shaper import model
55 from salome.shaper import geom
57 from GeomAlgoAPI import *
61 #========================== Les imports - Fin ====================================
64 D_FMT["stp"] = ["stp", "step"]
65 D_FMT["igs"] = ["igs", "iges"]
66 for CLE in ("brep", "xao"):
69 # statut = 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
88 # Transparence des solides traités correctement
91 # Limite basse de l'épaisseur pour pouvoir faire les intersections
94 #========================= Début de la fonction ==================================
96 def decode_cao (fmt_cao):
97 """Décode le format de la cao
100 :fmt_cao: format du fichier, step, iges, etc.
102 :fmt_cao_0: format décodé
107 fmt_cao_low = fmt_cao.lower()
109 for cle, l_aux in D_FMT.items():
110 if ( fmt_cao_low in l_aux ):
116 #========================= Fin de la fonction ===================================
118 #========================= Début de la fonction ==================================
120 def import_cao (part_doc, ficcao, nom_objet=None, verbose=False):
121 """Importation d'une cao
125 :ficcao: le fichier de la CAO
126 :nom_objet: nom à donner à l'objet lu, éventuellement
128 :objet: l'objet importé dans SHAPER
131 nom_fonction = __name__ + "/import_cao"
132 blabla = "Dans {} :\n".format(nom_fonction)
133 message_0 = "Fichier : {}\n".format(ficcao)
135 message = blabla + message_0
136 message += "nom_objet : {}".format(nom_objet)
144 laux = ficcao.split(".")
145 fmt_cao_0 = decode_cao (laux[-1])
147 if ( fmt_cao_0 not in ("stp", "brep", "igs", "xao") ):
148 message += "Le format de CAO est inconnu"
152 message += "Le fichier de CAO n'a pas été décodé correctement."
155 elif not os.path.isfile(ficcao):
156 message += "Le fichier de CAO est inconnu."
162 objet = model.addImport(part_doc, ficcao)
166 if nom_objet is not None:
167 objet.result().setName(nom_objet)
170 texte = "Objet : '{}'\n".format(objet.result().name())
171 texte += "De type : '{}'".format(objet.result().shapeType())
174 return erreur, message, objet
176 #========================= Fin de la fonction ===================================
178 #========================= Début de la fonction ==================================
180 def print_tab (nb_tab, message, argu=None, saut_av=False, saut_ap=False):
181 """Imprime avec des tabulations
184 :nb_tab: nombre de tabulations à appliquer
185 :message: message principal
186 :argu: argument du format
187 :saut_av: saut de ligne avant le texte
188 :saut_ap: saut de ligne après le texte
196 for _ in range(nb_tab):
200 if ( argu is not None ):
201 texte += "{}".format(argu)
208 #========================= Fin de la fonction ===================================
210 #========================= Début de la fonction ==================================
212 def nommage (objet, nom, couleur=None):
213 """Nomme un objet et son résultat
216 :objet: objet à traiter
217 :nom: nom à attribuer
218 :couleur: éventuellement couleur
222 objet.result().setName(nom)
224 if ( couleur is not None ):
225 objet.result().setColor(couleur[0], couleur[1], couleur[2])
227 #========================= Fin de la fonction ===================================
230 #=================================== La classe ===================================
232 class SurfaceMediane (object):
234 """Calcul des surfaces médianes de solides minces
236 L'objectif de ce programme est de créer les surfaces médianes, encore appelées fibres neutres, pour \
237 une structure qui est un solide ou un assemblage de solides (compound).
238 Pour réaliser l'opération, trois façons de faire :
240 1. On lance le script en précisant le fichier à analyser dans la zone d'auto-test.
242 2. Si on part d'un script qui manipule un fichier au format CAO, on crée une instance de la classe SurfaceMediane \
243 puis on appelle la méthode surf_fic_cao avec ce fichier en argument.
245 3. Si on part d'un script qui crée un objet SHAPER, on crée une instance de la classe SurfaceMediane \
246 puis on appelle la méthode surf_objet_shaper avec cet objet en argument.
249 Le programme crée les surfaces sous réserve que pour le solide envisagé, il a réussi à trouver deux faces \
250 de taille identique et supérieure aux tailles des autres faces du solide. \
251 Cela fonctionne pour des surfaces planes ou de forme canonique.
252 Il crée alors une surface au milieu de ces deux grandes faces. \
253 Cette face est coloriée en vert, le solide est en vert et transparent.
255 On sait traiter les faces :
262 Si la création n'a pas eu lieu, un message est émis et les solides sont mis en couleur :
263 . Rouge : le solide n'est pas assez mince.
264 . Bleu : le solide est trop mince, vis-à-vis de la précision de SHAPER.
265 . Orange : la forme de la face n'est pas reconnue.
273 . Exportation finale dans un fichier step. Par défaut, pas d'export.
274 -export_step/-no_export_step
277 surf_fic_cao --> import_cao
278 --> surf_objet_shaper (récursif) --> _nom_sous_objets
279 --> _surf_objet_shaper_0
280 --> surf_solide_shaper --> _isole_solide
281 --> _traitement_objet --> face_mediane_solide --> _faces_du_solide
283 --> _cree_face_mediane
285 _cree_face_mediane --> _cree_face_mediane_plane
286 --> _cree_face_mediane_cylindre
287 --> _cree_face_mediane_sphere
288 --> _cree_face_mediane_tore
289 --> _cree_face_mediane_cone
290 --> _cree_face_mediane_0
299 affiche_aide_globale = 0
306 nom_solide_aux = None
312 objet_principal = None
313 # Pour chaque sous-objet dans l'ordre de l'arborescence : nom
315 # Statut de chaque sous-objet connu par son nom :
316 # 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
318 # Liste des faces médianes créées et des fonctions initiales
320 # La fonction initiale
326 #=========================== Début de la méthode =================================
328 def __init__ ( self, liste_option ):
330 """Le constructeur de la classe SurfaceMediane
332 Décodage des arguments
333 On cherche ici les arguments généraux : aide, verbeux
336 for option in liste_option :
339 if isinstance(option,str):
340 saux = option.upper()
342 if saux in ( "-H", "-HELP" ):
343 self.affiche_aide_globale = 1
346 elif saux == "-VMAX" :
348 self._verbose_max = 1
349 elif saux == "-EXPORT_STEP":
350 self._export_step = True
351 elif saux == "-NO_EXPORT_STEP":
352 self._export_step = False
354 #=========================== Fin de la méthode ==================================
356 #=========================== Début de la méthode =================================
359 """A la suppression de l'instance de classe"""
360 if self._verbose_max:
361 print ("Suppression de l'instance de la classe.")
363 #=========================== Fin de la méthode ==================================
365 #=========================== Début de la méthode =================================
367 def _nom_sous_objets (self, objet, lecture, n_recur=0, rang=0):
368 """Gère les noms des sous_objets solides
371 :objet: objet à traiter
372 :lecture: vrai pour lire les noms, faux pour les attribuer
373 :n_recur: niveau de récursivité
374 :rang: rang du sous-objet
377 :rang: rang du sous-objet
380 nom_fonction = __name__ + "/_nom_sous_objets"
381 blabla = "Dans {} :\n".format(nom_fonction)
383 if self._verbose_max:
385 for _ in range(n_recur):
387 texte = "\n{}{}".format(prefixe,blabla)
388 texte += "{}n_recur = {}".format(prefixe,n_recur)
389 texte += "\n{}lecture = {}".format(prefixe,lecture)
392 # 1. Au premier passage, il faut garder la référence au résultat principal
395 objet_0 = objet.result()
396 if self._verbose_max:
397 print ("d_statut_so = {}".format(self.d_statut_so))
401 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
403 nb_sub_results = objet_0.numberOfSubs()
405 if self._verbose_max:
406 texte = "{}Examen de l'objet '{}' ".format(prefixe,objet_0.name())
407 texte += "de type '{}'".format(objet_0.shapeType())
408 texte += "\n{}objet.result().numberOfSubs() : {}".format(prefixe,nb_sub_results)
411 for n_sobj in range(nb_sub_results):
413 # 2.1. Exploration récursive de l'arborescence
415 rang = self._nom_sous_objets ( objet_0.subResult(n_sobj), lecture, n_recur+1, rang )
417 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
419 if ( objet_0.shapeType() == "SOLID" ):
420 # A la lecture, on enregistre le nom
423 self.l_noms_so.append(nom)
424 self.d_statut_so[nom] = 0
425 # A la récupération, on redonne le nom et on affecte une couleur dépendant de l'état
427 nom = self.l_noms_so[rang]
429 etat = self.d_statut_so[nom]
430 objet_0.setColor (D_COLOR_R[etat],D_COLOR_G[etat],D_COLOR_B[etat])
432 objet_0.setTransparency (TRANSPARENCE)
437 #=========================== Fin de la méthode ==================================
439 #=========================== Début de la méthode =================================
441 def _couleur_objet (self, objet, n_recur=0, coul_r=1, coul_g=0, coul_b=0):
442 """Appliquer une couleur à un objet et à ses sous_objets
445 :objet: objet à traiter
446 :n_recur: niveau de récursivité
447 :coul_r,coul_g,coul_b: code RGB de la couleur à appliquer
450 :rang: rang du sous-objet
453 nom_fonction = __name__ + "/_couleur_objet"
454 blabla = "Dans {} :".format(nom_fonction)
456 if self._verbose_max:
458 print_tab(n_recur, "objet : ", objet.name())
459 print_tab(n_recur, "RGB = ({},{},{})".format(coul_r,coul_g,coul_b))
461 # 1. Au premier passage, il faut garder la référence au résultat principal
464 objet_0 = objet.result()
468 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
470 nb_sub_results = objet_0.numberOfSubs()
472 if self._verbose_max:
473 print_tab(n_recur, "Examen de l'objet ",objet_0.name())
474 texte = "de type '{}' ".format(objet_0.shapeType())
475 texte += "et de {} sous-objets".format(nb_sub_results)
476 print_tab(n_recur, texte)
478 for n_sobj in range(nb_sub_results):
480 # 2.1. Exploration récursive de l'arborescence
482 self._couleur_objet ( objet_0.subResult(n_sobj), n_recur+1, coul_r, coul_g, coul_b )
484 # 2.2. Cet objet n'a pas de sous-objets : on le colore
485 if self._verbose_max:
486 print_tab(n_recur, "Couleur affectée à l'objet ",objet_0.name())
487 objet_0.setColor (int(coul_r),int(coul_g),int(coul_b))
489 #print ("sortie de {}".format(nom_fonction))
491 #=========================== Fin de la méthode ==================================
493 #=========================== Début de la méthode =================================
495 def _isole_solide ( self, solide, n_recur ):
496 """Isole le solide de son arboresence
499 :solide: le solide à traiter
500 :n_recur: numéro de la récurrence
503 :objet: le solide isolé
504 :recover: la fonction de récupération
507 nom_fonction = __name__ + "/_isole_solide"
508 blabla = "Dans {} :".format(nom_fonction)
509 if self._verbose_max:
510 print_tab (n_recur, blabla)
511 texte = "Pour le solide '{}' ".format(solide.name())
512 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
513 print_tab (n_recur, texte)
515 if ( solide.name() != self.objet_principal.name() ):
516 objet, recover = self._isole_solide_a ( solide, n_recur )
519 objet, recover = self._isole_solide_b ( solide, n_recur )
521 if self._verbose_max:
522 print_tab (n_recur, "objet final : ", objet.name())
523 print_tab (n_recur, "fonction_0 : {}".format(self.fonction_0))
524 print_tab (n_recur, "recover : {}".format(recover))
526 return objet, recover
528 #=========================== Fin de la méthode ==================================
530 #=========================== Début de la méthode =================================
532 def _isole_solide_a ( self, solide, n_recur ):
533 """Isole le solide de son arboresence
536 :solide: le solide à traiter
537 :n_recur: numéro de la récurrence
540 :objet: le solide isolé
541 :recover: la fonction de récupération
544 nom_fonction = __name__ + "/_isole_solide_a"
545 blabla = "Dans {} :".format(nom_fonction)
546 if self._verbose_max:
547 print_tab (n_recur, blabla)
548 texte = "Pour le solide '{}' ".format(solide.name())
549 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
550 print_tab (n_recur, texte)
552 if self._verbose_max:
553 print_tab (n_recur, ". Extraction du solide '{}'".format(self.objet_principal.name()))
555 # 1. Extraction du solide
556 remove_subshapes = model.addRemoveSubShapes(self.part_doc, model.selection("COMPOUND", self.objet_principal.name()))
557 remove_subshapes.setSubShapesToKeep([model.selection("SOLID", solide.name())])
559 self.nom_solide_aux = "{}_S".format(solide.name())
560 if self._verbose_max:
561 print_tab (n_recur, "\tAttribution à remove_subshapes.result() du nom '{}'".format(self.nom_solide_aux))
562 remove_subshapes.result().setName(self.nom_solide_aux)
564 self.fonction_0 = remove_subshapes
566 # 2. Récupération de l'objet principal
567 recover = model.addRecover(self.part_doc, remove_subshapes, [self.objet_principal])
568 if self._verbose_max:
569 print_tab (n_recur, "\tAttribution à recover du nom '{}'".format(self.objet_principal.name()))
570 recover.result().setName(self.objet_principal.name())
572 return remove_subshapes.result(), recover
574 #=========================== Fin de la méthode ==================================
576 #=========================== Début de la méthode =================================
578 def _isole_solide_b ( self, solide, n_recur ):
579 """Isole le solide de son arboresence
582 :solide: le solide à traiter
583 :n_recur: numéro de la récurrence
586 :objet: le solide isolé
587 :recover: la fonction de récupération
590 nom_fonction = __name__ + "/_isole_solide_b"
591 blabla = "Dans {} :".format(nom_fonction)
592 if self._verbose_max:
593 print_tab (n_recur, blabla)
594 texte = "Pour le solide '{}' ".format(solide.name())
595 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
596 print_tab (n_recur, texte)
598 if self._verbose_max:
599 print_tab (n_recur, ". Mise en place du solide")
601 self.nom_solide_aux = self.objet_principal.name()
602 self.fonction_0 = None
606 #=========================== Fin de la méthode ==================================
608 #=========================== Début de la méthode =================================
610 def _faces_du_solide ( self, solide, n_recur=0 ):
611 """Détermine les faces d'un solide
614 :solide: solide SHAPER à traiter
615 :n_recur: niveau de récursivité
618 :l_faces_car: pour chaque face du solide (surface,caractéristiques)
621 nom_fonction = __name__ + "/_faces_du_solide"
622 blabla = "Dans {} :".format(nom_fonction)
623 if self._verbose_max:
624 print_tab (n_recur, blabla, saut_av=True)
628 if self._verbose_max:
629 print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
630 print_tab (n_recur, ".. shapeType : ", solide.shapeType())
633 #print_tab (n_recur, "volume = ", GeomAlgoAPI_ShapeTools.volume(solide.shape()))
634 # 1. Repérage des faces
635 objResult = solide.resultSubShapePair()[0]
637 exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
639 l_faces.append(exp.current().face())
644 for iface, face in enumerate(l_faces):
645 surf = GeomAlgoAPI_ShapeTools.area(face)
646 caract = geom.shapeInfo(face)
647 if self._verbose_max:
648 print_tab (n_recur, "\tFace n°{} ; ".format(iface), "surface = {}, caractéristiques = {}".format(surf,caract))
649 l_faces_car.append((surf,caract))
653 #=========================== Fin de la méthode ==================================
655 #=========================== Début de la méthode =================================
657 def _calcul_caract_faces ( self, solide, n_recur ):
658 """Calcule les caractéristiques géométriques des faces du solide
661 :solide: solide SHAPER à traiter
662 :n_recur: niveau de récursivité
665 :tb_caract: tableau des caractéristiques géométriques des faces
668 nom_fonction = __name__ + "/_calcul_caract_faces"
669 blabla = "Dans {} :".format(nom_fonction)
670 if self._verbose_max:
671 print_tab (n_recur, blabla, saut_av=True)
672 print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
673 print_tab (n_recur, ".. shapeType : ", solide.shapeType())
675 # 1. Repérage des faces
676 objResult = solide.resultSubShapePair()[0]
678 exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
680 l_faces.append(exp.current().face())
683 # 2. Caractéristiques
684 nb_faces = len(l_faces)
685 tb_caract = np.zeros((nb_faces,3), dtype = 'object')
686 for iaux, face in enumerate(l_faces):
687 surf = GeomAlgoAPI_ShapeTools.area(face)
688 caract = geom.shapeInfo(face)
689 if self._verbose_max:
690 print_tab (n_recur, "\tFace n°{} ; ".format(iaux), "surface = {}, caractéristiques = {}".format(surf,caract))
692 tb_caract [iaux][0] = face
693 tb_caract [iaux][1] = surf
694 tb_caract [iaux][2] = caract
696 #if self._verbose_max:
697 #for iaux in range(nb_faces):
698 #print ("\t. tb_caract : {} {}".format(surf,tb_caract[iaux][2]))
702 #=========================== Fin de la méthode ==================================
704 #=========================== Début de la méthode =================================
706 def _tri_faces ( self, tb_caract, n_recur ):
707 """Trie les faces en fonction de leurs surfaces
710 :tb_caract: tableau des caractéristiques géométriques des faces
711 :n_recur: niveau de récursivité
714 :tb_caract_1[-1], tb_caract_1[-2]: les caractéristiques des 2 faces les plus grandes
720 nom_fonction = __name__ + "/_tri_faces"
721 blabla = "Dans {} :".format(nom_fonction)
723 # Tri du tableau en fonction des surfaces
724 if self._verbose_max:
725 print_tab (n_recur, blabla)
726 print_tab (n_recur, "tb_caract brut : ", tb_caract)
727 tb_caract_1 = sorted(tb_caract, key=lambda colonnes: colonnes[1])
728 if self._verbose_max:
729 print_tab (n_recur, "tb_caract trié :", tb_caract_1)
731 if self._verbose_max:
732 texte = "\tSurface de la plus grande face : {}, de caractéristiques {}\n".format(tb_caract_1[-1][1],tb_caract_1[-1][2])
733 texte += "\tSurface de la face suivante : {}, de caractéristiques {}".format(tb_caract_1[-2][1],tb_caract_1[-2][2])
734 if self._verbose_max:
735 texte += "\n\tSurface de la 3ème face suivante : {}, de caractéristiques {}".format(tb_caract_1[-3][1],tb_caract_1[-3][2])
738 # La surface suivante doit être différente, sinon ce n'est pas un solide mince
739 ecart = np.abs((tb_caract_1[-1][1]-tb_caract_1[-3][1])/tb_caract_1[-1][1])
740 if ( ecart < self._epsilon ):
741 message = "\nSolide '{}'\n".format(self.nom_solide)
742 message += ". Surface de la plus grande face : {}\n".format(tb_caract_1[-1][1])
743 message += ". Surface de la 1ère face suivante : {}\n".format(tb_caract_1[-2][1])
744 message += ". Surface de la 2ème face suivante : {}\n".format(tb_caract_1[-3][1])
745 if self._verbose_max:
746 message += ". Ecart relatif :{:4.1f}%\n".format(ecart*100.)
747 message += "L'écart est trop faible par rapport à la limite de {}%.\n".format(self._epsilon*100.)
748 message += "==> Impossible de créer la face médiane car le solide n'est pas assez mince.\n"
750 self.d_statut_so[self.nom_solide] = -1
751 self.faces_pb_nb += 1
752 self.faces_pb_msg += message
754 return erreur, message, tb_caract_1[-1], tb_caract_1[-2]
756 #=========================== Fin de la méthode ==================================
758 #=========================== Début de la méthode =================================
760 def _verif_epaisseur ( self, epaisseur ):
761 """Contrôle de la validité de l'épaisseur
764 :epaisseur: épaisseur du solide
767 nom_fonction = __name__ + "/_verif_epaisseur"
768 blabla = "Dans {} :\n".format(nom_fonction)
770 if self._verbose_max:
772 texte += ". Epaisseur du solide : {}\n".format(epaisseur)
773 texte += ". EP_MIN : {}".format(EP_MIN)
776 if ( epaisseur <= EP_MIN ):
777 message = "\nSolide '{}'\n".format(self.nom_solide)
778 message += ". Epaisseur : {}\n".format(epaisseur)
779 message += "L'épaisseur est trop faible par rapport à la limite de {}.\n".format(EP_MIN)
780 message += "==> Impossible de créer la face médiane car le solide est trop mince.\n"
782 self.d_statut_so[self.nom_solide] = 2
783 self.faces_pb_nb += 1
784 self.faces_pb_msg += message
788 #print ("erreur = {}".format(erreur))
792 #=========================== Fin de la méthode ==================================
794 #=========================== Début de la méthode =================================
796 def _cree_face_mediane ( self, solide, caract_face_1, caract_face_2, n_recur ):
797 """Crée la face médiane entre deux autres
800 :solide: solide SHAPER à traiter
801 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
802 :n_recur: niveau de récursivité
805 :face: la face médiane créée
808 nom_fonction = __name__ + "/_cree_face_mediane"
809 blabla = "Dans {} :".format(nom_fonction)
811 if self._verbose_max:
812 print_tab (n_recur, blabla)
813 print_tab (n_recur, "face_1 : " ,caract_face_1)
814 print_tab (n_recur, "face_2 : " ,caract_face_2)
819 # 1. Forme de la face
820 forme = caract_face_1[2][0]
822 # 2. Traitement selon la forme de la face
824 if forme in ( "Disk" , "Plane", "Rectangle"):
825 erreur, face = self._cree_face_mediane_plane ( solide, caract_face_1, caract_face_2, n_recur )
827 # 2.2. Face cylindrique
828 elif ( forme == "Cylinder" ):
829 erreur, face = self._cree_face_mediane_cylindre ( solide, caract_face_1, caract_face_2, n_recur )
831 # 2.3. Face sphérique
832 elif ( forme == "Sphere" ):
833 erreur, face = self._cree_face_mediane_sphere ( caract_face_1, caract_face_2, n_recur )
836 elif ( forme == "Torus" ):
837 erreur, face = self._cree_face_mediane_tore ( caract_face_1, caract_face_2, n_recur )
840 elif ( forme == "Cone" ):
841 erreur, face = self._cree_face_mediane_cone ( caract_face_1, caract_face_2, n_recur )
843 # 2.N. Face de forme inconnue
845 message = "\nSolide '{}'\n".format(self.nom_solide)
846 message += "sa face la plus grande est de forme : {}\n".format(forme)
847 message += "==> Impossible de créer la face médiane.\n"
849 self.d_statut_so[self.nom_solide] = -2
850 self.faces_pb_nb += 1
851 self.faces_pb_msg += message
853 # 3. Gestion de la face produite
856 self._cree_face_mediane_0 ( face, n_recur )
860 #=========================== Fin de la méthode ==================================
862 #=========================== Début de la méthode =================================
864 def _cree_face_mediane_0 ( self, face, n_recur ):
865 """Gestion de la face médiane créée entre deux autres
868 :face: la face médiane créée
869 :n_recur: niveau de récursivité
872 nom_fonction = __name__ + "/_cree_face_mediane_0"
873 blabla = "Dans {} :".format(nom_fonction)
875 if self._verbose_max:
876 print_tab (n_recur, blabla)
879 nom_face = self.nom_solide+"_M"
880 if self._verbose_max:
881 print_tab (n_recur,"Nom de la face créée : ", nom_face)
882 #if ( self.nom_solide_aux != self.objet_principal.name() ):
884 nommage (face, nom_face)
886 # 2. Mémorisation de la face et de la fonction initiale
887 self.l_faces_m.append((face, self.fonction_0))
889 # 3. Couleur verte pour la face
890 self._couleur_objet (face, coul_r=0, coul_g=170, coul_b=0)
892 # 4. Changement de statut pour le solide
893 self.d_statut_so[self.nom_solide] = 1
895 #=========================== Fin de la méthode ==================================
897 #=========================== Début de la méthode =================================
899 def _cree_face_mediane_plane ( self, solide, caract_face_1, caract_face_2, n_recur ):
900 """Crée la face médiane entre deux autres - cas des surfaces planes
903 :solide: l'objet solide à traiter
904 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
905 :n_recur: niveau de récursivité
908 :face: la face médiane
911 nom_fonction = __name__ + "/_cree_face_mediane_plane"
912 blabla = "Dans {} :".format(nom_fonction)
913 if self._verbose_max:
914 print_tab (n_recur, blabla)
916 # Caractéristiques des surfaces
917 coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2 = self._cree_face_mediane_plane_0 ( solide, caract_face_1, caract_face_2, n_recur )
919 # Contrôle de la validité de l'épaisseur
920 erreur = self._verif_epaisseur ( d_face_1_2 )
922 # Création de la face
924 face = self._cree_face_mediane_plane_1 ( solide, (coo_x, coo_y, coo_z),(vnor_x, vnor_y, vnor_z), taille, d_face_1_2, n_recur )
930 #=========================== Fin de la méthode ==================================
932 #=========================== Début de la méthode =================================
934 def _cree_face_mediane_plane_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
935 """Crée la face médiane entre deux autres - cas des surfaces planes
937 Décodage des caractéristiques
940 :solide: l'objet solide à traiter
941 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
942 :n_recur: niveau de récursivité
945 :coo_x, coo_y, coo_z: coordonnées du centre de la base
946 :vnor_x, vnor_y, vnor_z: coordonnées du vecteur normal
947 :taille: estimation de la taille de la future face
948 :d_face_1_2: la distance entre les deux faces
951 nom_fonction = __name__ + "/_cree_face_mediane_plane_0"
952 blabla = "Dans {} :".format(nom_fonction)
954 if self._verbose_max:
955 print_tab (n_recur, blabla)
956 print_tab (n_recur, "caract_face_1 : ", caract_face_1)
957 print_tab (n_recur, "caract_face_2 : ", caract_face_2)
959 # 1. Caractéristiques de la base
960 # Coordonnées du centre de la base
961 coo_x = caract_face_1[2][1]
962 coo_y = caract_face_1[2][2]
963 coo_z = caract_face_1[2][3]
964 # Coordonnées du vecteur normal
965 vnor_x = caract_face_1[2][4]
966 vnor_y = caract_face_1[2][5]
967 vnor_z = caract_face_1[2][6]
968 # taille : une longueur caractéristique pour être certain de tout prendre
969 l_diag = self._calcul_lg_caract ( solide, n_recur )
971 if self._verbose_max:
972 print_tab (n_recur, "Taille englobante : ",taille)
974 # 2. Distance entre les deux faces
975 face_1 = caract_face_1[0]
976 face_2 = caract_face_2[0]
977 d_face_1_2 = GeomAlgoAPI_ShapeTools.minimalDistance(face_1, face_2)
978 if self._verbose_max:
979 print_tab (n_recur, "Distance entre les deux faces = ", d_face_1_2)
981 return coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2
983 #=========================== Fin de la méthode ==================================
985 #=========================== Début de la méthode =================================
987 def _cree_face_mediane_plane_1 ( self, solide, coo_c, vnor, taille, d_face_1_2, n_recur ):
988 """Crée la face médiane entre deux autres - cas des surfaces planes
990 Création des objets temporaires et de la face médiane
993 :solide: l'objet solide à traiter
994 :coo_c: coordonnées du centre de la base
995 :vnor: coordonnées du vecteur normal
996 :taille: estimation de la taille de la future face
997 :d_face_1_2: la distance entre les deux faces
998 :n_recur: niveau de récursivité
1001 :face: la face médiane
1004 nom_fonction = __name__ + "/_cree_face_mediane_plane_1"
1005 blabla = "Dans {} :".format(nom_fonction)
1006 if self._verbose_max:
1007 print_tab (n_recur, blabla)
1008 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1009 print_tab (n_recur, "Normale : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
1010 print_tab (n_recur, "Taille : ", taille)
1011 print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1013 # 1. Objets préalables
1014 nom_par_1 = "{}_taille".format(self.nom_solide)
1015 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(taille))
1017 centre, v_norm, plan = self._cree_centre_axe_plan ( coo_c, vnor, self.nom_solide, n_recur )
1019 # 2. Création de l'esquisse
1020 sketch = self._cree_face_mediane_plane_1_a ( plan, centre, nom_par_1, taille, n_recur )
1023 face = self._cree_face_mediane_plane_1_b ( solide, sketch, v_norm, d_face_1_2, n_recur )
1025 #print ("fin de {}".format(nom_fonction))
1029 #=========================== Fin de la méthode ==================================
1031 #=========================== Début de la méthode =================================
1033 def _cree_face_mediane_plane_1_a ( self, plan, centre, nom_par_1, taille, n_recur ):
1034 """Crée la face médiane entre deux autres - cas des surfaces planes - l'esquisse
1039 :nom_par_1: nom du paramètre
1040 :taille: estimation de la taille de la future face
1041 :n_recur: niveau de récursivité
1047 nom_fonction = __name__ + "/_cree_face_mediane_plane_1_a"
1048 blabla = "Dans {} :".format(nom_fonction)
1049 if self._verbose_max:
1050 print_tab (n_recur, blabla)
1051 print_tab (n_recur, "Plan : {}".format(plan.name()))
1052 print_tab (n_recur, "Centre : {}".format(centre.name()))
1053 print_tab (n_recur, "Paramètre : {}".format(nom_par_1))
1054 print_tab (n_recur, "taille : {}".format(taille))
1056 sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
1058 ### Create SketchLine
1059 SketchLine_1 = sketch.addLine(-taille/2., taille/2., taille/2., taille/2.)
1060 sketch.setHorizontal(SketchLine_1.result())
1062 ### Create SketchLine
1063 SketchLine_2 = sketch.addLine(taille/2., taille/2., taille/2., -taille/2.)
1064 sketch.setVertical(SketchLine_2.result())
1065 sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
1067 ### Create SketchLine
1068 SketchLine_3 = sketch.addLine(taille/2., -taille/2., -taille/2., -taille/2.)
1069 sketch.setHorizontal(SketchLine_3.result())
1070 sketch.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
1071 sketch.setLength(SketchLine_3.result(), nom_par_1)
1073 ### Create SketchLine
1074 SketchLine_4 = sketch.addLine(-taille/2., -taille/2., -taille/2., taille/2.)
1075 sketch.setVertical(SketchLine_4.result())
1076 sketch.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
1077 sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
1078 sketch.setEqual(SketchLine_3.result(), SketchLine_4.result())
1080 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", centre.name()), False)
1081 SketchPoint_1 = SketchProjection_1.createdFeature()
1083 ### Create SketchLine
1084 SketchLine_5 = sketch.addLine(-taille/2., taille/2., taille/2., -taille/2.)
1085 SketchLine_5.setAuxiliary(True)
1086 sketch.setCoincident(SketchLine_1.startPoint(), SketchLine_5.startPoint())
1087 sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_5.endPoint())
1088 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_5.result())
1090 ### Create SketchLine
1091 SketchLine_6 = sketch.addLine(taille/2., taille/2., -taille/2., -taille/2.)
1092 SketchLine_6.setAuxiliary(True)
1093 sketch.setCoincident(SketchLine_2.startPoint(), SketchLine_6.startPoint())
1094 sketch.setCoincident(SketchLine_4.startPoint(), SketchLine_6.endPoint())
1095 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_6.result())
1099 nom_sketch = "{}_esquisse".format(self.nom_solide)
1100 nommage (sketch, nom_sketch)
1102 #print ("fin de {}".format(nom_fonction))
1106 #=========================== Fin de la méthode ==================================
1108 #=========================== Début de la méthode =================================
1110 def _cree_face_mediane_plane_1_b ( self, solide, sketch, v_norm, d_face_1_2, n_recur ):
1111 """Crée la face médiane entre deux autres - cas des surfaces planes
1113 Création de la face médiane
1116 :solide: l'objet solide à traiter
1118 :v_norm: vecteur normal
1119 :d_face_1_2: la distance entre les deux faces
1120 :n_recur: niveau de récursivité
1123 :face: la face médiane
1126 nom_fonction = __name__ + "/_cree_face_mediane_plane_1_b"
1127 blabla = "Dans {} :".format(nom_fonction)
1128 if self._verbose_max:
1129 print_tab (n_recur, blabla)
1130 print_tab (n_recur, "Esquisse : ", sketch.name())
1131 print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1133 ### Create LinearCopy
1134 LinearCopy_1 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", self.nom_solide_aux)], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
1135 nom = "{}_0".format(self.nom_solide_aux)
1136 nommage (LinearCopy_1, nom)
1139 Recover_1 = model.addRecover(self.part_doc, LinearCopy_1, [solide])
1140 nom = "{}_1".format(self.nom_solide_aux)
1141 nommage (Recover_1, nom)
1143 # Création d'une face ; on la translate d'une demi-épaisseur.
1144 for iaux in range(2):
1146 distance = -0.5*d_face_1_2*float(2*iaux-1)
1147 nom_solide = "{}_{}".format(self.nom_solide_aux,iaux)
1148 face = self._cree_face_mediane_plane_2 ( sketch.name(), v_norm.name(), nom_solide, distance, iaux, n_recur )
1151 face = self._cree_face_mediane_plane_11 ( face, Recover_1, n_recur )
1153 # Si l'intersection est vide, on la translate dans l'autre sens
1155 if self._verbose_max:
1156 print_tab (n_recur, "L'intersection est vide.")
1159 #print ("fin de {}".format(nom_fonction))
1163 #=========================== Fin de la méthode ==================================
1165 #=========================== Début de la méthode =================================
1167 def _cree_face_mediane_plane_11 ( self, face, Recover_1, n_recur ):
1168 """Crée la face médiane entre deux autres - cas des surfaces planes
1170 Création des objets temporaires et de la face médiane
1173 :face: la face médiane
1174 :Recover_1: la récupératiuon du solide
1175 :n_recur: niveau de récursivité
1178 :face: la face médiane
1181 nom_fonction = __name__ + "/_cree_face_mediane_plane_11"
1182 blabla = "Dans {} :".format(nom_fonction)
1183 if self._verbose_max:
1184 print_tab (n_recur, blabla)
1185 print_tab (n_recur, "face : ", face.name())
1187 # Si on traite un objet solide unique, on le récupère
1188 if ( self.nom_solide_aux == self.objet_principal.name() ):
1189 if self._verbose_max:
1190 print_tab (n_recur, "On traite un objet solide unique ==> on le récupère.")
1191 Recover_2 = model.addRecover(self.part_doc, face, [Recover_1.result()])
1192 Recover_2.result().setName("{}_S".format(self.nom_solide_aux))
1194 nb_inter = face.result().numberOfSubs()
1195 if self._verbose_max:
1196 print_tab (n_recur, "Nombre d'intersections : ", nb_inter)
1199 face = self._cree_face_mediane_plane_3 ( face )
1203 #=========================== Fin de la méthode ==================================
1205 #=========================== Début de la méthode =================================
1207 def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, distance, icpt, n_recur ):
1208 """Crée la face médiane entre deux autres - cas des surfaces planes
1210 Intersection de la face avec le solide
1213 :nom_sketch: nom de l'esquisse
1214 :nom_normal: nom du vecteur normal
1215 :nom_solide: nom du solide à intersecter
1216 :distance: la distance de translation
1217 :icpt: numéro de la tentative
1220 :face: la face médiane
1223 nom_fonction = __name__ + "/_cree_face_mediane_plane_2"
1224 blabla = "Dans {} :\n".format(nom_fonction)
1225 if self._verbose_max:
1226 print_tab (n_recur, blabla)
1227 print_tab (n_recur, "nom_sketch : ", nom_sketch)
1228 print_tab (n_recur, "nom_normal : ", nom_normal)
1229 print_tab (n_recur, "nom_solide : ", nom_solide)
1230 print_tab (n_recur, "distance : ", distance)
1232 # Création d'une face
1233 Face_1 = model.addFace(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(nom_sketch))])
1234 nom_face_1 = "{}_face_1_{}".format(self.nom_solide_aux,icpt)
1235 nommage (Face_1, nom_face_1)
1238 Translation_1 = model.addTranslation(self.part_doc, [model.selection("FACE", nom_face_1)], axis = model.selection("EDGE", nom_normal), distance = distance, keepSubResults = True)
1239 nom_trans = "{}_trans_{}".format(self.nom_solide_aux,icpt)
1240 nommage (Translation_1, nom_trans)
1241 Translation_1.result().setColor(85, 0, 255)
1243 # Intersection de cette face avec le solide initial
1244 face = model.addCommon(self.part_doc, [model.selection("SOLID", nom_solide), model.selection("FACE", nom_trans)], keepSubResults = True)
1248 #=========================== Fin de la méthode ==================================
1250 #=========================== Début de la méthode =================================
1252 def _cree_face_mediane_plane_3 ( self, face ):
1253 """Crée la face médiane entre deux autres - cas des surfaces planes
1255 Fusion des 2 intersections
1258 :face: la face médiane composée de plusieurs intersections
1261 :face_m: la face médiane
1264 nom_fonction = __name__ + "/_cree_face_mediane_plane_3"
1265 blabla = "Dans {} :\n".format(nom_fonction)
1266 if self._verbose_max:
1270 # Nommage des sous-objets
1272 for iaux in range(face.result().numberOfSubs()):
1273 nom = "{}_common_{}".format(self.nom_solide_aux,iaux)
1274 face.result().subResult(iaux).setName(nom)
1275 l_fuse.append(model.selection("FACE", '{}'.format(nom)))
1278 if self._verbose_max:
1279 print ("Fusion de {} faces.".format(len(l_fuse)))
1280 face_m = model.addFuse(self.part_doc, l_fuse, keepSubResults = True)
1284 #=========================== Fin de la méthode ==================================
1286 #=========================== Début de la méthode =================================
1288 def _cree_face_mediane_cylindre ( self, solide, caract_face_1, caract_face_2, n_recur ):
1289 """Crée la face médiane entre deux autres - cas des cylindres
1292 :solide: solide SHAPER à traiter
1293 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1294 :n_recur: niveau de récursivité
1297 :face: la face médiane
1300 nom_fonction = __name__ + "/_cree_face_mediane_cylindre"
1301 blabla = "Dans {} :".format(nom_fonction)
1304 if self._verbose_max:
1305 print_tab (n_recur, blabla)
1306 print_tab (n_recur, "face_1 : ", caract_face_1)
1307 print_tab (n_recur, "face_2 : ", caract_face_2)
1309 # Caractéristiques des cylindres
1310 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur = self._cree_face_mediane_cylindre_0 ( solide, caract_face_1, caract_face_2, n_recur )
1312 # Contrôle de la validité de l'épaisseur
1313 erreur = self._verif_epaisseur ( epaisseur )
1315 # Création de la face
1317 face = self._cree_face_mediane_cylindre_1 ( (coo_x, coo_y, coo_z), (axe_x, axe_y, axe_z), rayon, hauteur, n_recur )
1319 self._couleur_objet (solide, n_recur, coul_r=0, coul_g=0, coul_b=255)
1324 #=========================== Fin de la méthode ==================================
1326 #=========================== Début de la méthode =================================
1328 def _cree_face_mediane_cylindre_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
1329 """Crée la face médiane entre deux autres - cas des cylindres
1331 Décodage des caractéristiques
1334 :solide: l'objet solide à traiter
1335 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1336 :n_recur: niveau de récursivité
1339 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1340 :axe_x, axe_y, axe_z: coordonnées de l'axe
1341 :rayon: rayon moyen entre les deux faces
1342 :hauteur: hauteur du cylindre
1343 :epaisseur: épaisseur de l'interface entre les deux faces
1346 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_0"
1347 blabla = "Dans {} :".format(nom_fonction)
1349 if self._verbose_max:
1350 print_tab (n_recur, blabla)
1351 print_tab (n_recur, "face_1 : ", caract_face_1)
1352 print_tab (n_recur, "face_2 : ", caract_face_2)
1354 # Coordonnées du centre de la base
1355 coo_x = caract_face_1[2][1]
1356 coo_y = caract_face_1[2][2]
1357 coo_z = caract_face_1[2][3]
1358 # Coordonnées de l'axe
1359 axe_x = caract_face_1[2][4]
1360 axe_y = caract_face_1[2][5]
1361 axe_z = caract_face_1[2][6]
1363 rayon = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1364 # Hauteur : une longueur caractéristique pour être certain de tout prendre
1365 l_diag = self._calcul_lg_caract ( solide, n_recur )
1366 hauteur = 10.*l_diag
1367 if self._verbose_max:
1368 print_tab (n_recur, "Hauteur englobante : ", hauteur)
1370 epaisseur = np.abs(caract_face_2[2][7]-caract_face_1[2][7])
1372 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur
1374 #=========================== Fin de la méthode ==================================
1376 #=========================== Début de la méthode =================================
1378 def _cree_face_mediane_cylindre_1 ( self, coo_c, v_axe, rayon, hauteur, n_recur ):
1379 """Crée la face médiane entre deux autres - cas des cylindres
1381 Création des objets temporaires et de la face externe du cylindre support
1384 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1385 :axe_x, axe_y, axe_z: coordonnées de l'axe
1386 :rayon: rayon moyen entre les deux faces
1387 :hauteur: hauteur du cylindre
1388 :n_recur: niveau de récursivité
1391 :face: la face médiane
1393 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1"
1394 blabla = "Dans {} :\n".format(nom_fonction)
1396 # Les caractéristiques du cylindre à créer
1397 if self._verbose_max:
1398 print_tab (n_recur, blabla)
1399 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1400 print_tab (n_recur, "Axe : ({}, {}, {})".format(v_axe[0], v_axe[1], v_axe[2]))
1401 print_tab (n_recur, "Rayon : ", rayon)
1402 print_tab (n_recur, "Hauteur : ", hauteur)
1404 # 1. Objets préalables
1405 nom_par_1 = "{}_R".format(self.nom_solide)
1406 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon))
1407 nom_par_2 = "{}_H".format(self.nom_solide)
1408 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(hauteur))
1410 centre, _, plan = self._cree_centre_axe_plan ( coo_c, v_axe, self.nom_solide, n_recur )
1412 # 2. Création de l'esquisse
1413 sketch = self._cree_face_mediane_cylindre_1_a ( plan, centre, rayon, nom_par_1, n_recur )
1416 face = self._cree_face_mediane_cylindre_1_b ( sketch, nom_par_2, n_recur )
1420 #=========================== Fin de la méthode ==================================
1422 #=========================== Début de la méthode =================================
1424 def _cree_face_mediane_cylindre_1_a ( self, plan, centre, rayon, nom_par_1, n_recur ):
1425 """Crée la face médiane entre deux autres - cas des cylindres
1427 Création des objets temporaires et de la face externe du cylindre support
1430 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1431 :axe_x, axe_y, axe_z: coordonnées de l'axe
1432 :rayon: rayon moyen entre les deux faces
1433 :nom_par_1: nom_par_1
1434 :n_recur: niveau de récursivité
1437 :face: la face médiane
1439 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1_a"
1440 blabla = "Dans {} :\n".format(nom_fonction)
1442 # Les caractéristiques du cylindre à créer
1443 if self._verbose_max:
1444 print_tab (n_recur, blabla)
1445 print_tab (n_recur, "Plan : {}".format(plan.name()))
1446 print_tab (n_recur, "Centre : {}".format(centre.name()))
1447 print_tab (n_recur, "Rayon : ", rayon)
1449 sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
1451 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", centre.name()), False)
1452 SketchPoint_1 = SketchProjection_1.createdFeature()
1454 SketchCircle_1 = sketch.addCircle(0., 0., rayon)
1455 sketch.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
1456 sketch.setRadius(SketchCircle_1.results()[1], nom_par_1)
1459 nom_sketch = "{}_esquisse".format(self.nom_solide)
1460 nommage (sketch, nom_sketch)
1464 #=========================== Fin de la méthode ==================================
1466 #=========================== Début de la méthode =================================
1468 def _cree_face_mediane_cylindre_1_b ( self, sketch, nom_par_2, n_recur ):
1469 """Crée la face médiane entre deux autres - cas des cylindres
1471 Création des objets temporaires et de la face externe du cylindre support
1475 :n_recur: niveau de récursivité
1478 :face: la face médiane
1480 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1_b"
1481 blabla = "Dans {} :\n".format(nom_fonction)
1483 # Les caractéristiques du cylindre à créer
1484 if self._verbose_max:
1485 print_tab (n_recur, blabla)
1486 print_tab (n_recur, "Esquisse : ", sketch.name())
1487 print_tab (n_recur, "nom_par_2 : ", nom_par_2)
1489 # Création du cylindre complet
1490 cylindre = model.addExtrusion(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(sketch.name()))], model.selection(), nom_par_2, nom_par_2, "Edges")
1492 nom_cylindre = "{}_cylindre".format(self.nom_solide)
1493 nommage (cylindre, nom_cylindre, (85, 0, 255))
1495 # Intersection de la face cylindrique avec le solide initial
1496 face = self._creation_face_inter ( nom_cylindre )
1500 #=========================== Fin de la méthode ==================================
1502 #=========================== Début de la méthode =================================
1504 def _cree_face_mediane_sphere ( self, caract_face_1, caract_face_2, n_recur ):
1505 """Crée la face médiane entre deux autres - cas des sphères
1508 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1509 :n_recur: niveau de récursivité
1512 :face: la face médiane
1515 nom_fonction = __name__ + "/_cree_face_mediane_sphere"
1516 blabla = "Dans {} :".format(nom_fonction)
1519 if self._verbose_max:
1520 print_tab (n_recur, blabla)
1521 print_tab (n_recur, "face_1 : ", caract_face_1)
1522 print_tab (n_recur, "face_2 : ", caract_face_2)
1524 # Caractéristiques des sphères
1525 coo_x, coo_y, coo_z, rayon, epaisseur = self._cree_face_mediane_sphere_0 ( caract_face_1, caract_face_2, n_recur )
1527 # Contrôle de la validité de l'épaisseur
1528 erreur = self._verif_epaisseur ( epaisseur )
1530 # Création de la face
1532 face = self._cree_face_mediane_sphere_1 ( coo_x, coo_y, coo_z, rayon )
1538 #=========================== Fin de la méthode ==================================
1540 #=========================== Début de la méthode =================================
1542 def _cree_face_mediane_sphere_0 ( self, caract_face_1, caract_face_2, n_recur ):
1543 """Crée la face médiane entre deux autres - cas des sphères
1545 Décodage des caractéristiques
1548 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1549 :n_recur: niveau de récursivité
1552 :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1553 :rayon: rayon moyen entre les deux faces
1554 :epaisseur: épaisseur de l'interface entre les deux faces
1557 nom_fonction = __name__ + "/_cree_face_mediane_sphere_0"
1558 blabla = "Dans {} :".format(nom_fonction)
1561 if self._verbose_max:
1562 print_tab (n_recur, blabla)
1563 print_tab (n_recur, "face_1 : ", caract_face_1)
1564 print_tab (n_recur, "face_2 : ", caract_face_2)
1566 # Coordonnées du centre de la sphère
1567 coo_x = caract_face_1[2][1]
1568 coo_y = caract_face_1[2][2]
1569 coo_z = caract_face_1[2][3]
1571 rayon = (caract_face_2[2][4]+caract_face_1[2][4])/2.
1573 epaisseur = np.abs(caract_face_2[2][4]-caract_face_1[2][4])
1575 return coo_x, coo_y, coo_z, rayon, epaisseur
1577 #=========================== Fin de la méthode ==================================
1579 #=========================== Début de la méthode =================================
1581 def _cree_face_mediane_sphere_1 ( self, coo_x, coo_y, coo_z, rayon ):
1582 """Crée la face médiane entre deux autres - cas des sphères
1584 Création des objets temporaires et de la face externe de la sphère support
1587 :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1588 :rayon: rayon moyen entre les deux faces
1591 :face: la face externe de la sphère support
1594 nom_fonction = __name__ + "/_cree_face_mediane_sphere_1"
1595 blabla = "Dans {} :\n".format(nom_fonction)
1597 # Les caractéristiques de la sphère à créer
1598 if self._verbose_max:
1600 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1601 texte += "Rayon : {}".format(rayon)
1604 # Création du point central
1605 centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1606 nom_centre = "{}_centre".format(self.nom_solide)
1607 centre.result().setName(nom_centre)
1609 # Création d'un plan passant par ce centre et cet axe
1610 plan = model.addPlane(self.part_doc, model.selection("EDGE", "PartSet/OX"), model.selection("VERTEX", nom_centre), False)
1611 nom_plan = "{}_plan".format(self.nom_solide)
1612 plan.result().setName(nom_plan)
1614 # Création de l'esquisse
1615 nom_par_1 = "{}_R".format(self.nom_solide)
1616 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon))
1618 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1620 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
1621 SketchPoint_1 = SketchProjection_1.createdFeature()
1623 ### Create SketchArc
1624 SketchArc_1 = sketch.addArc(coo_x, coo_y, coo_x-rayon, coo_y, coo_x+rayon, coo_y, False)
1625 sketch.setRadius(SketchArc_1.results()[1], nom_par_1)
1626 sketch.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
1628 ### Create SketchLine
1629 SketchLine_1 = sketch.addLine(coo_x-rayon, coo_y, coo_x+rayon, coo_y)
1630 nom_ligne = "{}_ligne".format(self.nom_solide)
1631 SketchLine_1.setName(nom_ligne)
1632 SketchLine_1.result().setName(nom_ligne)
1633 SketchLine_1.setAuxiliary(True)
1634 sketch.setHorizontal(SketchLine_1.result())
1635 sketch.setCoincident(SketchArc_1.startPoint(), SketchLine_1.startPoint())
1636 sketch.setCoincident(SketchArc_1.endPoint(), SketchLine_1.endPoint())
1637 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result())
1640 nom_sketch = "{}_esquisse".format(self.nom_solide)
1641 sketch.setName(nom_sketch)
1642 sketch.result().setName(nom_sketch)
1644 # Création de la sphère complète
1645 sphere = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", "{}/{}".format(nom_sketch,nom_ligne)), 360, 0, "Edges")
1647 nom_sphere = "{}_sphere".format(self.nom_solide)
1648 nommage (sphere, nom_sphere, (85, 0, 255))
1650 # Intersection de la face sphérique avec le solide initial
1651 face = self._creation_face_inter ( nom_sphere )
1655 #=========================== Fin de la méthode ==================================
1657 #=========================== Début de la méthode =================================
1659 def _cree_face_mediane_tore ( self, caract_face_1, caract_face_2, n_recur ):
1660 """Crée la face médiane entre deux autres - cas des tores
1663 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1664 :n_recur: niveau de récursivité
1667 :face: la face médiane
1670 nom_fonction = __name__ + "/_cree_face_mediane_tore"
1671 blabla = "Dans {} :".format(nom_fonction)
1674 if self._verbose_max:
1675 print_tab (n_recur, blabla)
1676 print_tab (n_recur, "face_1 : ", caract_face_1)
1677 print_tab (n_recur, "face_2 : ", caract_face_2)
1679 # Caractéristiques des tores
1680 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 = self._cree_face_mediane_tore_0 ( caract_face_1, caract_face_2, n_recur )
1682 # Contrôle de la validité de l'épaisseur (bidon)
1683 erreur = self._verif_epaisseur ( EP_MIN*10. )
1685 # Création de la face
1687 face = self._cree_face_mediane_tore_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 )
1693 #=========================== Fin de la méthode ==================================
1695 #=========================== Début de la méthode =================================
1697 def _cree_face_mediane_tore_0 ( self, caract_face_1, caract_face_2, n_recur ):
1698 """Crée la face médiane entre deux autres - cas des tores
1700 Décodage des caractéristiques
1703 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1704 :n_recur: niveau de récursivité
1707 :coo_x, coo_y, coo_z: coordonnées du centre du tore
1708 :axe_x, axe_y, axe_z: coordonnées de l'axe
1709 :rayon_1 : rayon principal
1710 :rayon_2 : rayon secondaire
1713 nom_fonction = __name__ + "/_cree_face_mediane_tore_0"
1714 blabla = "Dans {} :".format(nom_fonction)
1717 if self._verbose_max:
1718 print_tab (n_recur, blabla)
1719 print_tab (n_recur, "face_1 : ", caract_face_1)
1720 print_tab (n_recur, "face_2 : ", caract_face_2)
1722 # Coordonnées du centre du tore
1723 coo_x = caract_face_1[2][1]
1724 coo_y = caract_face_1[2][2]
1725 coo_z = caract_face_1[2][3]
1726 # Coordonnées de l'axe
1727 axe_x = caract_face_1[2][4]
1728 axe_y = caract_face_1[2][5]
1729 axe_z = caract_face_1[2][6]
1731 rayon_1 = caract_face_2[2][7]
1732 rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1734 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2
1736 #=========================== Fin de la méthode ==================================
1738 #=========================== Début de la méthode =================================
1740 def _cree_face_mediane_tore_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 ):
1741 """Crée la face médiane entre deux autres - cas des tores
1743 Création des objets temporaires et de la face externe du tore support
1746 :coo_x, coo_y, coo_z: coordonnées du centre du tore
1747 :axe_x, axe_y, axe_z: coordonnées de l'axe
1748 :rayon_1 : rayon principal
1749 :rayon_2 : rayon secondaire
1752 :face: la face externe du tore support
1755 nom_fonction = __name__ + "/_cree_face_mediane_tore_1"
1756 blabla = "Dans {} :\n".format(nom_fonction)
1759 if self._verbose_max:
1761 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1762 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1763 texte += "Rayon principal : {}\n".format(rayon_1)
1764 texte += "Rayon secondaire : {}".format(rayon_2)
1767 # Création du point central
1768 centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1769 nom_centre = "{}_centre".format(self.nom_solide)
1770 centre.result().setName(nom_centre)
1773 axe = model.addAxis(self.part_doc, axe_x, axe_y, axe_z)
1774 nom_axe = "{}_axe".format(self.nom_solide)
1775 axe.result().setName(nom_axe)
1777 # Création d'un plan passant par ce centre et cet axe
1778 plan = model.addPlane(self.part_doc, model.selection("EDGE", nom_axe), model.selection("VERTEX", nom_centre), False)
1779 nom_plan = "{}_plan".format(self.nom_solide)
1780 plan.result().setName(nom_plan)
1782 # Création de l'esquisse
1783 nom_par_1 = "{}_R_1".format(self.nom_solide)
1784 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1785 nom_par_2 = "{}_R_2".format(self.nom_solide)
1786 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1788 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1790 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
1791 SketchPoint_1 = SketchProjection_1.createdFeature()
1793 SketchProjection_2 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
1794 SketchLine_1 = SketchProjection_2.createdFeature()
1796 SketchPoint_2 = sketch.addPoint(rayon_1, 0.)
1797 sketch.setDistance(SketchPoint_1.result(), SketchPoint_2.coordinates(), nom_par_1, True)
1799 SketchLine_2 = sketch.addLine(0., 0., rayon_1, 0.)
1800 SketchLine_2.setAuxiliary(True)
1801 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.startPoint())
1802 sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_2.endPoint())
1803 sketch.setPerpendicular(SketchLine_1.result(), SketchLine_2.result())
1805 SketchCircle_1 = sketch.addCircle(0., 0., rayon_2)
1806 sketch.setCoincident(SketchPoint_2.result(), SketchCircle_1.center())
1807 sketch.setRadius(SketchCircle_1.results()[1], nom_par_2)
1810 nom_sketch = "{}_esquisse".format(self.nom_solide)
1811 sketch.setName(nom_sketch)
1812 sketch.result().setName(nom_sketch)
1814 # Création du tore complet
1815 nom_tore = "{}_tore".format(self.nom_solide)
1816 self._cree_revolution ( nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_tore )
1818 # Intersection de la face torique avec le solide initial
1819 face = self._creation_face_inter ( nom_tore )
1823 #=========================== Fin de la méthode ==================================
1825 #=========================== Début de la méthode =================================
1827 def _cree_face_mediane_cone ( self, caract_face_1, caract_face_2, n_recur ):
1828 """Crée la face médiane entre deux autres - cas des cones
1831 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1832 :n_recur: niveau de récursivité
1835 :face: la face médiane
1838 nom_fonction = __name__ + "/_cree_face_mediane_cone"
1839 blabla = "Dans {} :".format(nom_fonction)
1842 if self._verbose_max:
1843 print_tab (n_recur, blabla)
1844 print_tab (n_recur, "face_1 : ", caract_face_1)
1845 print_tab (n_recur, "face_2 : ", caract_face_2)
1847 # Caractéristiques des cones
1848 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur = self._cree_face_mediane_cone_0 ( caract_face_1, caract_face_2, n_recur )
1850 # Contrôle de la validité de l'épaisseur (bidon)
1851 erreur = self._verif_epaisseur ( EP_MIN*10. )
1853 # Création de la face
1855 face = self._cree_face_mediane_cone_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur )
1861 #=========================== Fin de la méthode ==================================
1863 #=========================== Début de la méthode =================================
1865 def _cree_face_mediane_cone_0 ( self, caract_face_1, caract_face_2, n_recur ):
1866 """Crée la face médiane entre deux autres - cas des cones
1868 Décodage des caractéristiques
1871 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1872 :n_recur: niveau de récursivité
1875 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1876 :axe_x, axe_y, axe_z: coordonnées de l'axe
1877 :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1878 :hauteur: hauteur du cone
1881 nom_fonction = __name__ + "/_cree_face_mediane_cone_0"
1882 blabla = "Dans {} :".format(nom_fonction)
1885 if self._verbose_max:
1886 print_tab (n_recur, blabla)
1887 print_tab (n_recur, "face_1 : ", caract_face_1)
1888 print_tab (n_recur, "face_2 : ", caract_face_2)
1890 # Coordonnées du centre de la base
1891 coo_x = caract_face_1[2][1]
1892 coo_y = caract_face_1[2][2]
1893 coo_z = caract_face_1[2][3]
1894 # Coordonnées de l'axe
1895 axe_x = caract_face_1[2][4]
1896 axe_y = caract_face_1[2][5]
1897 axe_z = caract_face_1[2][6]
1899 rayon_1 = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1900 rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1902 hauteur = caract_face_1[2][9]
1905 if self._verbose_max:
1906 print_tab (n_recur, "coo_x : ", coo_x)
1907 print_tab (n_recur, "coo_y : ", coo_y)
1908 print_tab (n_recur, "coo_z : ", coo_z)
1909 print_tab (n_recur, "axe_x : ", axe_x)
1910 print_tab (n_recur, "axe_y : ", axe_y)
1911 print_tab (n_recur, "axe_z : ", axe_z)
1912 print_tab (n_recur, "rayon_1 : ", rayon_1)
1913 print_tab (n_recur, "rayon_2 : ", rayon_2)
1914 print_tab (n_recur, "hauteur : ", hauteur)
1916 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur
1918 #=========================== Fin de la méthode ==================================
1920 #=========================== Début de la méthode =================================
1922 def _cree_face_mediane_cone_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur ):
1923 """Crée la face médiane entre deux autres - cas des cones
1925 Création des objets temporaires et de la face externe du cone support
1928 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1929 :axe_x, axe_y, axe_z: coordonnées de l'axe
1930 :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1931 :hauteur: hauteur du cone
1934 :face: la face externe du cone support
1936 nom_fonction = __name__ + "/_cree_face_mediane_cone_1"
1937 blabla = "Dans {} :\n".format(nom_fonction)
1940 if self._verbose_max:
1942 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1943 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1944 texte += "Rayons : {}, {}\n".format(rayon_1, rayon_2)
1945 texte += "Hauteur : {}".format(hauteur)
1948 # 1. Création du point central de la base, côté rayon_1
1949 centre_1 = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1950 nom_centre_1 = "{}_centre_1".format(self.nom_solide)
1951 centre_1.result().setName(nom_centre_1)
1953 # 2. Création du point central, du côté de rayon_2
1954 centre_2 = model.addPoint(self.part_doc, coo_x+hauteur*axe_x, coo_y+hauteur*axe_y, coo_z+hauteur*axe_z)
1955 nom_centre_2 = "{}_centre_2".format(self.nom_solide)
1956 centre_2.result().setName(nom_centre_2)
1958 # 3. Création de l'axe
1959 axe = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre_1), model.selection("VERTEX", nom_centre_2))
1960 nom_axe = "{}_axe".format(self.nom_solide)
1961 axe.result().setName(nom_axe)
1963 # 4. Création d'un plan passant par le centre de la base et l'axe
1964 # 4.1. Création d'un vecteur perpendiculaire à l'axe
1966 v_perp = model.addAxis(self.part_doc, -coeff*axe_y, coeff*axe_x, 0.)
1967 nom_v_perp = "{}_v_perp".format(self.nom_solide)
1968 v_perp.result().setName(nom_v_perp)
1969 # 4.2. Création du plan
1970 plan = model.addPlane(self.part_doc, model.selection("EDGE",nom_v_perp), model.selection("VERTEX", nom_centre_1), True)
1971 nom_plan = "{}_plan".format(self.nom_solide)
1972 plan.result().setName(nom_plan)
1975 nom_par_1 = "{}_R_1".format(self.nom_solide)
1976 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1977 nom_par_2 = "{}_R_2".format(self.nom_solide)
1978 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1979 nom_par_3 = "{}_H".format(self.nom_solide)
1980 model.addParameter(self.part_doc, "{}".format(nom_par_3), "{}".format(hauteur))
1982 # 6. Création de l'esquisse
1984 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1986 # 6.1. Projection des centres et de l'axe
1987 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre_1), False)
1988 SketchPoint_1 = SketchProjection_1.createdFeature()
1989 sk_coo_x_1 = SketchAPI_Point(SketchPoint_1).coordinates().x()
1990 sk_coo_y_1 = SketchAPI_Point(SketchPoint_1).coordinates().y()
1992 SketchProjection_2 = sketch.addProjection(model.selection("VERTEX", nom_centre_2), False)
1993 SketchPoint_2 = SketchProjection_2.createdFeature()
1994 sk_coo_x_2 = SketchAPI_Point(SketchPoint_2).coordinates().x()
1995 sk_coo_y_2 = SketchAPI_Point(SketchPoint_2).coordinates().y()
1997 SketchProjection_3 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
1998 SketchLine_0 = SketchProjection_3.createdFeature()
2000 # 6.2. Lignes perpendiculaires à l'axe passant par les centres
2001 SketchLine_1 = sketch.addLine(sk_coo_x_1, sk_coo_y_1, sk_coo_x_1+rayon_1, sk_coo_y_1)
2002 SketchLine_1.setAuxiliary(True)
2003 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.startPoint())
2004 sketch.setPerpendicular(SketchLine_0.result(), SketchLine_1.result())
2005 sketch.setLength(SketchLine_1.result(), nom_par_1)
2007 SketchLine_2 = sketch.addLine(sk_coo_x_2, sk_coo_y_2, sk_coo_x_2+rayon_2, sk_coo_y_2)
2008 SketchLine_2.setAuxiliary(True)
2009 sketch.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_2.startPoint())
2010 sketch.setPerpendicular(SketchLine_0.result(), SketchLine_2.result())
2011 sketch.setLength(SketchLine_2.result(), nom_par_2)
2013 # 6.3. Ligne joignant les extrémités des précédentes et point milieu
2014 SketchLine_3 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
2015 sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_1.endPoint())
2016 sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_2.endPoint())
2017 SketchLine_3.setAuxiliary(True)
2018 SketchPoint_3 = sketch.addPoint(sk_coo_x_1, sk_coo_y_1)
2019 sketch.setMiddlePoint(SketchLine_3.result(), SketchPoint_3.coordinates())
2021 # 6.4. Ligne support de la future révolution
2022 SketchLine_4 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
2023 sketch.setMiddlePoint(SketchLine_4.result(), SketchPoint_3.coordinates())
2024 sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_4.result())
2025 sketch.setLength(SketchLine_4.result(), "1.2*{}".format(nom_par_3))
2028 nom_sketch = "{}_esquisse".format(self.nom_solide)
2029 sketch.setName(nom_sketch)
2030 sketch.result().setName(nom_sketch)
2032 # Création du cone complet
2033 nom_cone = "{}_cone".format(self.nom_solide)
2034 self._cree_revolution ( nom_sketch, nom_centre_1, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_cone )
2036 # Intersection de la face conique avec le solide initial
2037 face = self._creation_face_inter ( nom_cone )
2041 #=========================== Fin de la méthode ==================================
2043 #=========================== Début de la méthode =================================
2045 def _cree_centre_axe_plan ( self, coo_c, vnor, prefixe, n_recur ):
2046 """Crée un centre, un axe, un plan
2051 :coo_c: coordonnées du centre de la base
2052 :vnor: coordonnées du vecteur normal
2053 :prefix: prefixe du nom des objets
2054 :n_recur: niveau de récursivité
2058 :normal: vecteur normal
2062 nom_fonction = __name__ + "/_cree_centre_axe_plan"
2063 blabla = "Dans {} :".format(nom_fonction)
2064 if self._verbose_max:
2065 print_tab (n_recur, blabla)
2066 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
2067 print_tab (n_recur, "Normale : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
2069 # Création du point central
2070 centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
2071 nom_centre = "{}_centre".format(prefixe)
2072 nommage (centre, nom_centre)
2074 # Création du vecteur normal
2075 v_norm = model.addAxis(self.part_doc, vnor[0], vnor[1], vnor[2])
2076 nom_vnorm = "{}_normale".format(prefixe)
2077 nommage (v_norm, nom_vnorm)
2079 # Création du plan perpendiculaire au vecteur normal
2080 plan = model.addPlane(self.part_doc, model.selection("EDGE", v_norm.name()), model.selection("VERTEX", centre.name()), True)
2081 nom_plan = "{}_plan".format(prefixe)
2082 nommage (plan, nom_plan)
2084 #print ("fin de {}".format(nom_fonction))
2086 return centre, v_norm, plan
2088 #=========================== Fin de la méthode ==================================
2090 #=========================== Début de la méthode =================================
2092 def _calcul_boite_englobante ( self, objet, n_recur ):
2093 """Crée la hauteur englobant à coup sûr l'objet
2095 Remarque : pour une raison inconnue, le calcul de la boître englobante fait planter
2096 en mode GUI. On controune l'obstacle enclculantr une lingueur caractéristique
2099 :objet: l'objet à traiter
2100 :n_recur: niveau de récursivité
2103 :l_caract: longueur caractéristique ; longueur de la diagonale de la boîte englobante
2106 nom_fonction = __name__ + "/_calcul_boite_englobante"
2107 blabla = "Dans {} :".format(nom_fonction)
2109 if self._verbose_max:
2110 print_tab (n_recur, blabla)
2112 # Hauteur : la diagonale de la boîte englobante permet d'être certain de tout prendre
2113 #if self._verbose_max:
2114 #print_tab (n_recur, "Création de la boite englobante pour l'objet ", objet.name())
2115 #print_tab (n_recur, "de type ", objet.shapeType())
2116 #bbox = model.getBoundingBox(self.part_doc, model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
2119 #bbox_nom = bbox.result().name()
2120 #if self._verbose_max:
2121 #print_tab (n_recur, "Boîte englobante : '{}' '{}'".format(bbox.name(), bbox_nom))
2123 #saux_0 = "[{}/Back]".format(bbox_nom)
2124 #saux_0 +="[{}/Left]".format(bbox_nom)
2125 #saux_0 +="[{}/Bottom]".format(bbox_nom)
2126 #saux_1 = "[{}/Front]".format(bbox_nom)
2127 #saux_1 +="[{}/Right]".format(bbox_nom)
2128 #saux_1 +="[{}/Top]".format(bbox_nom)
2129 #if self._verbose_max:
2130 #coo_min = model.getPointCoordinates(self.part_doc, model.selection("VERTEX", saux_0))
2131 #coo_max = model.getPointCoordinates(self.part_doc, model.selection("VERTEX", saux_1))
2132 #texte = "Xmin = {}, Xmax = {}\n".format(coo_min[0],coo_max[0])
2133 #texte += "\tYmin = {}, Ymax = {}\n".format(coo_min[1],coo_max[1])
2134 #texte += "\tZmin = {}, Zmax = {}".format(coo_min[2],coo_max[2])
2135 #print_tab (n_recur, texte)
2137 #l_caract = model.measureDistance(self.part_doc, model.selection("VERTEX", saux_0), model.selection("VERTEX", saux_1) )
2138 properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
2139 l_caract = properties[0]
2141 if self._verbose_max:
2142 print_tab (n_recur, "Longueur caractéristique : ", l_caract)
2146 #=========================== Fin de la méthode ==================================
2148 #=========================== Début de la méthode =================================
2150 def _calcul_lg_caract ( self, objet, n_recur ):
2151 """Crée une longueur caractéristique de l'objet
2154 :objet: l'objet à traiter
2155 :n_recur: niveau de récursivité
2158 :l_caract: longueur caractéristique de l'objet
2161 nom_fonction = __name__ + "/_calcul_lg_caract"
2162 blabla = "Dans {} :".format(nom_fonction)
2164 if self._verbose_max:
2165 print_tab (n_recur, blabla)
2167 properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
2168 l_caract = properties[0]
2170 if self._verbose_max:
2171 print_tab (n_recur, "Longueur caractéristique : ", l_caract)
2175 #=========================== Fin de la méthode ==================================
2177 #=========================== Début de la méthode =================================
2179 def _cree_revolution ( self, nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_objet ):
2180 """Crée un volume de révolution
2183 :nom_sketch: nom de l'esquisse à révolutionner
2184 :nom_centre: nom du point associé au centre du volume de révolution
2185 :coo_x, coo_y, coo_z: coordonnées du centre du tore
2186 :axe_x, axe_y, axe_z: coordonnées de l'axe
2187 :rayon_1 : rayon principal
2188 :rayon_2 : rayon secondaire
2189 :nom_objet: nom de l'objet 2D créé
2192 nom_fonction = __name__ + "/_cree_revolution"
2193 blabla = "Dans {} :\n".format(nom_fonction)
2195 if self._verbose_max:
2197 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
2198 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
2201 # Création d'un point décalé par rapport au point central
2202 point = model.addPoint(self.part_doc, coo_x+axe_x, coo_y+axe_y, coo_z+axe_z)
2203 nom_point = "{}_point".format(self.nom_solide)
2204 point.result().setName(nom_point)
2206 # Création de l'axe de la rotation
2207 axe_r = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("VERTEX", nom_point))
2208 nom_axe_r = "{}_axe_r".format(self.nom_solide)
2209 axe_r.result().setName(nom_axe_r)
2211 # Création de l'objet complet
2212 objet = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", nom_axe_r), 360, 0, "Edges")
2214 nommage (objet, nom_objet, (85, 0, 255))
2216 #=========================== Fin de la méthode ==================================
2218 #=========================== Début de la méthode =================================
2220 def _creation_face_inter ( self, nom_objet ):
2221 """Crée la face par intersection entre l'objet initial et une face complète
2223 . Repère la face principale de l'objet support
2224 . Réalise l'intersection avec le solide initial
2227 :nom_objet: nom de l'objet 2D créé
2230 :face: la face externe de l'objet support intersecté avec le solide initial
2233 nom_fonction = __name__ + "/_creation_face_inter"
2234 blabla = "Dans {} :\n".format(nom_fonction)
2236 if self._verbose_max:
2239 face = model.addCommon(self.part_doc, [model.selection("SOLID", self.nom_solide_aux), model.selection("FACE", nom_objet)], keepSubResults = True)
2243 #=========================== Fin de la méthode ==================================
2245 #=========================== Début de la méthode =================================
2247 def face_mediane_solide (self, solide, n_recur=0):
2248 """Calcul de la face médiane pour un solide
2251 :solide: solide SHAPER à traiter
2252 :n_recur: niveau de récursivité
2255 :erreur: code d'erreur
2256 :message: message d'erreur
2259 nom_fonction = __name__ + "/face_mediane_solide"
2260 blabla = "Dans {} :".format(nom_fonction)
2262 if self._verbose_max:
2263 print_tab (n_recur, blabla, saut_av=True)
2265 print_tab (n_recur, "Traitement du solide ", solide.name())
2274 # 2. Calcul des caractéristiques géométriques des faces
2276 tb_caract = self._calcul_caract_faces ( solide, n_recur )
2278 # 3. Tri des faces en fonction de leurs caractéristiques géométriques
2280 erreur, message, caract_face_1, caract_face_2 = self._tri_faces ( tb_caract, n_recur )
2284 # 4. Création de la face médiane
2286 erreur, face = self._cree_face_mediane ( solide, caract_face_1, caract_face_2, n_recur )
2290 # 6. Exportation step
2292 if self._export_step:
2293 fichier = os.path.join(self.rep_step, "{}.stp".format(face.result().name()))
2294 export = model.exportToFile(self.part_doc, fichier, [model.selection(face.result().shapeType(), face.result().name())])
2295 export.execute(True)
2302 if ( erreur and self._verbose_max ):
2303 print (blabla, message)
2305 return erreur, message
2307 #=========================== Fin de la méthode ==================================
2309 #=========================== Début de la méthode =================================
2311 def _traitement_objet (self, solide, n_recur=0):
2312 """Traitement d'un objet
2315 :solide: solide SHAPER à traiter
2316 :n_recur: niveau de récursivité
2319 :erreur: code d'erreur
2320 :message: message d'erreur
2323 nom_fonction = __name__ + "/_traitement_objet"
2324 blabla = "Dans {} :".format(nom_fonction)
2326 if self._verbose_max:
2327 print_tab (n_recur, blabla, saut_av=True)
2328 texte = "solide = {} ".format(solide.name())
2329 print_tab (n_recur, texte, solide)
2331 # 1. En cas d'exportation step, répertoire de travail associé à l'éventuel fichier de départ
2332 # Attention à ne pas recréer le répertoire à chaque fois
2333 if self._export_step:
2335 if self.rep_step is None:
2337 if self._verbose_max:
2338 print_tab (n_recur, "Préparation de l'export STEP")
2340 if self.ficcao is None:
2341 self.rep_step = tempfile.mkdtemp(prefix="{}_".format(self.objet_principal.name()))
2343 self.rep_step = os.path.join(os.path.dirname(self.ficcao),"{}_M".format(self.objet_principal.name()))
2344 if os.path.isdir(self.rep_step):
2345 l_aux = os.listdir(self.rep_step)
2346 for nomfic in l_aux:
2347 os.remove(os.path.join(self.rep_step,nomfic))
2349 os.mkdir(self.rep_step)
2351 if self._verbose_max:
2352 print_tab (n_recur, "Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
2354 # 2. Calcul réel de la face médiane
2356 erreur, message = self.face_mediane_solide (solide, n_recur)
2358 return erreur, message
2360 #=========================== Fin de la méthode ==================================
2362 #=========================== Début de la méthode =================================
2364 def surf_fic_cao (self, ficcao, nom_objet=None):
2365 """Calcule la surface médiane pour un objet dans un fichier passé en argument
2368 :ficcao: fichier de l'objet à traiter
2369 :nom_objet: un nom à donner à l'objet à traiter
2372 :erreur: code d'erreur
2373 :message: message d'erreur
2376 nom_fonction = __name__ + "/surf_fic_cao"
2377 blabla = "Dans {} :".format(nom_fonction)
2379 if self._verbose_max:
2389 if self.affiche_aide_globale:
2392 # 1. Définition de la pièce
2394 self.part_doc = model.activeDocument()
2395 if ( self.part_doc.kind() == "PartSet" ):
2396 part = model.addPart(self.part_doc)
2397 self.part_doc = part.document()
2399 # 2. Import de la CAO
2401 self.ficcao = ficcao
2402 print ("Traitement du fichier {}".format(ficcao))
2404 erreur, message, objet = import_cao (self.part_doc, ficcao, nom_objet, self._verbose_max)
2408 # 3. Calcul des surfaces
2410 erreur, message = self.surf_objet_shaper ( objet )
2419 if ( erreur and self._verbose_max ):
2420 print (blabla, message)
2422 return erreur, message
2424 #=========================== Fin de la méthode ==================================
2426 #=========================== Début de la méthode =================================
2428 def surf_objet_shaper (self, objet):
2429 """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2432 :objet: objet à traiter
2435 :erreur: code d'erreur
2436 :message: message d'erreur
2439 nom_fonction = __name__ + "/surf_objet_shaper"
2440 blabla = "Dans {} :".format(nom_fonction)
2442 if self._verbose_max:
2450 if self.affiche_aide_globale:
2453 # 1. Acquisition de la liste des noms des sous-objets solides
2455 self.d_statut_so = dict()
2456 self.l_noms_so = list()
2457 self.l_faces_m = list()
2459 _ = self._nom_sous_objets (objet, True)
2460 if self._verbose_max:
2461 print ("Noms des sous-objets : {}".format(self.l_noms_so))
2463 # 2. Les faces médianes
2465 erreur, message = self._surf_objet_shaper_0 ( objet )
2469 # 3. Gestion des faces créées
2471 self._surf_objet_shaper_1 ( )
2473 # 4. Futur message pour le résultat
2475 if ( self._export_step and not erreur ):
2476 message = "Les fichiers des CAO des surfaces sont dans le répertoire {}".format(self.rep_step)
2480 return erreur, message
2482 #=========================== Fin de la méthode ==================================
2484 #=========================== Début de la méthode =================================
2486 def _surf_objet_shaper_0 (self, objet, n_recur=0):
2487 """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2490 :objet: objet à traiter
2491 :n_recur: niveau de récursivité
2494 :erreur: code d'erreur
2495 :message: message d'erreur
2498 nom_fonction = __name__ + "/_surf_objet_shaper_0"
2499 blabla = "Dans {} :".format(nom_fonction)
2501 if self._verbose_max:
2502 print_tab (n_recur, blabla)
2503 print_tab (n_recur, "n_recur = ", n_recur)
2510 # 1. Au premier passage, il faut récupérer la pièce SHAPER et garder la référence au résultat principal
2512 if ( n_recur == 0 ):
2513 self.part_doc = model.activeDocument()
2514 objet_0 = objet.result()
2515 self.objet_principal = objet_0
2516 objet_bis = objet.defaultResult().shape()
2517 if self._verbose_max:
2518 print_tab (0, "Examen de l'objet initial ", objet.result().name(), saut_av=True)
2519 print_tab (0, "Type python : ", type(objet))
2520 print_tab (0, "Type {} / {} ; volume = ".format(objet_bis.shapeType(),objet_bis.shapeTypeStr()), GeomAlgoAPI_ShapeTools.volume(objet_bis))
2523 if self._verbose_max:
2524 print_tab (n_recur, "Examen de l'objet ", objet.name(), saut_av=True)
2525 print_tab (n_recur, "Type python : ", type(objet))
2526 print_tab (n_recur, "shapeType : ", objet.shapeType())
2528 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
2530 nb_sub_results = objet_0.numberOfSubs()
2532 if self._verbose_max:
2533 print_tab (n_recur, "Examen de l'objet '{}' de type ".format(objet_0.name()), objet_0.shapeType(), saut_av=True)
2534 print_tab (n_recur, "objet.result().numberOfSubs() : ", nb_sub_results)
2536 for n_sobj in range(nb_sub_results):
2538 # 2.1. Exploration récursive de l'arborescence
2540 erreur, message = self._surf_objet_shaper_0 ( objet_0.subResult(n_sobj), n_recur+1 )
2547 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
2549 if ( objet_0.shapeType() == "SOLID" ):
2550 erreur, message = self.surf_solide_shaper ( objet_0, n_recur )
2554 # 3. Futur message pour le résultat
2556 if self._export_step:
2557 message = "Les fichiers STEP des surfaces sont dans le répertoire {}".format(self.rep_step)
2561 return erreur, message
2563 #=========================== Fin de la méthode ==================================
2565 #=========================== Début de la méthode =================================
2567 def _surf_objet_shaper_1 (self, n_recur=0):
2568 """Gestion des surfaces médianes créées
2571 :n_recur: niveau de récursivité
2574 :erreur: code d'erreur
2575 :message: message d'erreur
2578 nom_fonction = __name__ + "/_surf_objet_shaper_1"
2579 blabla = "Dans {} :\n".format(nom_fonction)
2581 if self._verbose_max:
2582 print_tab (n_recur, blabla)
2584 # 1. Informations sur les faces à problème
2586 if self.faces_pb_nb:
2587 if ( self.faces_pb_nb == 1 ):
2588 texte = "1 face pose"
2590 texte = "{} faces posent".format(self.faces_pb_nb)
2591 print_tab (n_recur, "{} problème.".format(texte), self.faces_pb_msg, saut_av=True)
2593 # 2. Si plus d'une face a été créée
2594 if ( len(self.l_faces_m) > 1 ):
2596 # 2.1. Partition du paquet de faces
2598 if self._verbose_max:
2599 print_tab (n_recur, "Partitionnnement des faces créées.")
2601 # 2.1.1. Pour une raison mystérieuse, il faut commencer par les faces entières, puis mettre les sous-faces éventuelles
2603 for (face,_) in self.l_faces_m:
2604 if not face.result().numberOfSubs():
2605 d_faces[face.name()] = [face.name()]
2606 for (face,_) in self.l_faces_m:
2607 nb_sub_results = face.result().numberOfSubs()
2610 for n_sobj in range(nb_sub_results):
2611 laux.append(face.result().subResult(n_sobj).name())
2612 d_faces[face.name()] = laux
2615 for _, laux in d_faces.items():
2616 for s_face_n in laux:
2617 l_objets.append(model.selection("FACE", s_face_n))
2619 Partition_1 = model.addPartition(self.part_doc, l_objets, keepSubResults = True)
2621 Partition_1.result().setName("{}_M".format(self.objet_principal.name()))
2623 for face_n, laux in d_faces.items():
2624 Partition_1.result().subResult(iaux).setName("{}".format(face_n))
2625 if ( len(laux) > 1 ):
2626 for jaux, s_face_n in enumerate(laux):
2627 Partition_1.result().subResult(iaux).subResult(jaux).setName("{}_M".format(s_face_n))
2629 self._couleur_objet (Partition_1, n_recur, coul_r=0, coul_g=170, coul_b=0)
2631 # 2.2. Récupération des faces individuelles
2633 if self._verbose_max:
2634 print_tab (n_recur, "Récupération des faces individuelles.")
2637 for iaux, (face,_) in enumerate(self.l_faces_m):
2638 l_objets.append(face.result())
2640 Recover_1 = model.addRecover(self.part_doc, Partition_1, l_objets)
2641 for iaux, (face,_) in enumerate(self.l_faces_m):
2642 Recover_1.results()[iaux].setName("{}".format(face.name()))
2643 Recover_1.results()[iaux].setColor(0, 170, 0)
2644 nb_sub_results = Recover_1.results()[iaux].numberOfSubs()
2645 for n_sobj in range(nb_sub_results):
2646 Recover_1.results()[iaux].subResult(n_sobj).setName("{}_{}".format(face.name(),n_sobj))
2647 Recover_1.results()[iaux].subResult(n_sobj).setColor(0, 170, 0)
2649 # 2.3. Mise en dossier
2651 if self._verbose_max:
2652 print_tab (n_recur, "Mise en dossier.")
2654 for (face,fonction_0) in self.l_faces_m:
2655 dossier = model.addFolder(self.part_doc, fonction_0, face)
2656 dossier.setName(face.name()[:-2])
2657 dossier = model.addFolder(self.part_doc, Partition_1, Recover_1)
2658 dossier.setName(self.objet_principal.name())
2660 #=========================== Fin de la méthode ==================================
2662 #=========================== Début de la méthode =================================
2664 def surf_solide_shaper (self, solide, n_recur):
2665 """Calcule les surfaces médianes pour un solide SHAPER solide passé en argument
2668 :solide: solide SHAPER à traiter
2669 :n_recur: numéro de la récurrence
2672 :erreur: code d'erreur
2673 :message: message d'erreur
2676 nom_fonction = __name__ + "/surf_solide_shaper"
2677 blabla = "Dans {} :".format(nom_fonction)
2679 if self._verbose_max:
2680 print_tab (n_recur, blabla, saut_av=True)
2687 self.nom_solide = solide.name()
2688 if self._verbose_max:
2689 print_tab (n_recur, "solide : ", self.nom_solide)
2691 # 1. Isolement du solide
2692 solide_aux, recover = self._isole_solide ( solide, n_recur )
2694 # 2. Traitement de l'objet correspondant
2695 erreur, message = self._traitement_objet ( solide_aux, n_recur=n_recur )
2697 if ( erreur and self._verbose_max ):
2698 print (blabla, message)
2700 # 3. Neutralisation des erreurs dues à l'épaisseur
2701 if ( erreur in (-2,-1,2) ):
2707 # 4. Mise en forme de l'objet principal récupéré
2708 if ( recover is not None ):
2709 _ = self._nom_sous_objets (recover, False)
2713 return erreur, message
2715 #=========================== Fin de la méthode ==================================
2717 #========================== Fin de la classe ====================================
2719 #==================================================================================
2721 #==================================================================================
2723 if __name__ == "__main__" :
2725 HOME_SH_SM_EXCHANGE = os.environ["HOME_SH_SM_EXCHANGE"]
2727 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "Solid_7.step"))
2728 L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Objet_1.stp"))
2729 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval_007.stp"))
2730 ##L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval.stp"))
2731 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2.step"))
2732 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_22.step"))
2733 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_5.step"))
2734 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Observatoire.stp"))
2736 for FIC_CAO in L_FIC_CAO:
2741 #L_OPTIONS.append("-h")
2742 #L_OPTIONS.append("-v")
2743 L_OPTIONS.append("-vmax")
2744 L_OPTIONS.append("-export_step")
2746 # 2. Lancement de la classe
2748 #print ("L_OPTIONS :", L_OPTIONS)
2750 SURFACE_MEDIANE = SurfaceMediane(L_OPTIONS)
2751 if SURFACE_MEDIANE.affiche_aide_globale:
2752 sys.stdout.write(SURFACE_MEDIANE.__doc__+"\n")
2755 PARTSET = model.moduleDocument()
2756 _ = model.addPart(PARTSET)
2757 ERREUR, MESSAGE_ERREUR = SURFACE_MEDIANE.surf_fic_cao(FIC_CAO)
2759 MESSAGE_ERREUR += "\n Code d'erreur : %d\n" % ERREUR
2760 sys.stderr.write(MESSAGE_ERREUR)