]> SALOME platform Git repositories - modules/shaper.git/blob - src/PythonAddons/macros/midSurface/surfaceMediane.py
Salome HOME
ajout d'un test
[modules/shaper.git] / src / PythonAddons / macros / midSurface / surfaceMediane.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2016-2022  CEA/DEN, EDF R&D
3 #
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.
8 #
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.
13 #
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
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 """Obtention des surfaces médianes à partir d'un objet GEOM ou SHAPER
21
22 On sait traiter les faces :
23   . planes
24   . cylindriques
25   . sphériques
26   . toriques
27   . coniques
28
29 Pour un objet complexe, on crée l'objet final comme étant la partition de toutes
30 les surfaces médianes.
31
32 Version initiale par :
33 alexandre.prunie@blastsolutions.io
34 guillaume.schweitzer@blastsolutions.io
35
36 Gérald NICOLAS
37 """
38
39 __revision__ = "V11.23"
40
41 #========================= Les imports - Début ===================================
42
43 import os
44 import tempfile
45
46 import salome
47
48 salome.salome_init()
49
50 import SALOMEDS
51 from SketchAPI import *
52 from salome.shaper import model
53 from salome.shaper import geom
54 from GeomAPI import *
55 from GeomAlgoAPI import *
56
57 import numpy as np
58
59 #========================== Les imports - Fin ====================================
60
61 D_FMT = dict()
62 D_FMT["stp"] = ["stp", "step"]
63 D_FMT["igs"] = ["igs", "iges"]
64 for CLE in ("brep", "xao"):
65   D_FMT[CLE] = [CLE]
66
67 # statut = 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
68 D_COLOR_R = dict()
69 D_COLOR_G = dict()
70 D_COLOR_B = dict()
71 D_COLOR_R[-2] = 255
72 D_COLOR_G[-2] = 255
73 D_COLOR_B[-2] = 0
74 D_COLOR_R[-1] = 255
75 D_COLOR_G[-1] = 0
76 D_COLOR_B[-1] = 0
77 D_COLOR_R[0] = 50
78 D_COLOR_G[0] = 50
79 D_COLOR_B[0] = 50
80 D_COLOR_R[1] = 170
81 D_COLOR_G[1] = 255
82 D_COLOR_B[1] = 120
83 D_COLOR_R[2] = 0
84 D_COLOR_G[2] = 0
85 D_COLOR_B[2] = 255
86 # Transparence des solides traités correctement
87 TRANSPARENCE = 0.7
88
89 # Limite basse de l'épaisseur pour pouvoir faire les intersections
90 EP_MIN = 0.0001
91 #EP_MIN = 0.1
92 #========================= Début de la fonction ==================================
93
94 def decode_cao (fmt_cao):
95   """Décode le format de la cao
96
97 Entrées :
98   :fmt_cao: format du fichier, step, iges, etc.
99 Sorties :
100   :fmt_cao_0: format décodé
101 """
102
103   fmt_cao_0 = ""
104
105   fmt_cao_low = fmt_cao.lower()
106
107   for cle, l_aux in D_FMT.items():
108     if ( fmt_cao_low in l_aux ):
109       fmt_cao_0 = cle
110       break
111
112   return fmt_cao_0
113
114 #=========================  Fin de la fonction ===================================
115
116 #========================= Début de la fonction ==================================
117
118 def import_cao (part_doc, ficcao, nom_objet=None, verbose=False):
119   """Importation d'une cao
120
121 Entrées :
122   :part_doc: part
123   :ficcao: le fichier de la CAO
124   :nom_objet: nom à donner à l'objet lu, éventuellement
125 Sorties :
126   :objet: l'objet importé dans SHAPER
127 """
128
129   nom_fonction = __name__ + "/import_cao"
130   blabla = "Dans {} :\n".format(nom_fonction)
131   message_0 = "Fichier : {}\n".format(ficcao)
132   if verbose:
133     message = blabla + message_0
134     message += "nom_objet : {}".format(nom_objet)
135     print (message)
136   message = message_0
137
138   erreur = 0
139
140   objet = None
141
142   laux = ficcao.split(".")
143   fmt_cao_0 = decode_cao (laux[-1])
144
145   if ( fmt_cao_0 not in ("stp", "brep", "igs", "xao") ):
146     message += "Le format de CAO est inconnu"
147     erreur = 1
148
149   elif not ficcao:
150     message += "Le fichier de CAO n'a pas été décodé correctement."
151     erreur = 2
152
153   elif not os.path.isfile(ficcao):
154     message += "Le fichier de CAO est inconnu."
155     erreur = 3
156
157   else:
158
159     message = ""
160     objet = model.addImport(part_doc, ficcao)
161     exec_nom (objet, nom_objet)
162     model.do()
163
164     if verbose:
165       texte  = "Objet   : '{}'\n".format(objet.result().name())
166       texte += "De type : '{}'".format(objet.result().shapeType())
167       print (texte)
168
169   return erreur, message, objet
170
171 #=========================  Fin de la fonction ===================================
172
173 #========================= Début de la fonction ==================================
174
175 def couleur_objet (objet, n_recur=0, coul_r=1, coul_g=0, coul_b=0, verbose=False):
176   """Appliquer une couleur à un objet et à ses sous_objets
177
178 Entrées :
179   :objet: objet à traiter
180   :n_recur: niveau de récursivité
181   :coul_r,coul_g,coul_b: code RGB de la couleur à appliquer
182
183 Sorties :
184   :rang: rang du sous-objet
185 """
186
187   nom_fonction = __name__ + "/couleur_objet"
188   blabla = "Dans {} :".format(nom_fonction)
189
190   if verbose:
191     print (blabla)
192     print ("n_recur = {}".format(n_recur))
193     print_tab(n_recur, "objet : ", objet.name())
194     print_tab(n_recur, "RGB = ({},{},{})".format(coul_r,coul_g,coul_b))
195
196 # 1. Au premier passage, il faut garder la référence au résultat principal
197
198   if ( n_recur == 0 ):
199     objet_0 = objet.result()
200   else:
201     objet_0 = objet
202
203 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
204
205   nb_sub_results = objet_0.numberOfSubs()
206
207   if verbose:
208     print_tab(n_recur, "Examen de l'objet",objet_0.name())
209     texte = "Formé de {} sous-objets".format(nb_sub_results)
210     print_tab(n_recur, texte)
211
212   for n_sobj in range(nb_sub_results):
213
214 # 2.1. Exploration récursive de l'arborescence
215
216     couleur_objet ( objet_0.subResult(n_sobj), n_recur+1, coul_r, coul_g, coul_b, verbose )
217
218 # 2.2. Cet objet n'a pas de sous-objets : on le colore
219   if verbose:
220     print_tab(n_recur, "Couleur affectée à l'objet ",objet_0.name())
221   objet_0.setColor (int(coul_r),int(coul_g),int(coul_b))
222
223   #print ("sortie de {}".format(nom_fonction))
224
225 #=========================  Fin de la fonction ===================================
226
227 #========================= Début de la fonction ==================================
228
229 def print_tab (nb_tab, message, argu=None, saut_av=False, saut_ap=False):
230   """Imprime avec des tabulations
231
232 Entrées :
233   :nb_tab: nombre de tabulations à appliquer
234   :message: message principal
235   :argu: argument du format
236   :saut_av: saut de ligne avant le texte
237   :saut_ap: saut de ligne après le texte
238 """
239
240   texte = ""
241
242   if saut_av:
243     texte += "\n"
244
245   for _ in range(nb_tab):
246     texte += "\t"
247
248   texte += message
249   if ( argu is not None ):
250     texte += "{}".format(argu)
251
252   if saut_ap:
253     texte += "\n"
254
255   print (texte)
256
257 #=========================  Fin de la fonction ===================================
258
259 #========================= Début de la fonction ==================================
260
261 def nommage (objet, nom, couleur=None):
262   """Nomme un objet et son résultat
263
264 Entrées :
265   :objet: objet à traiter
266   :nom: nom à attribuer
267   :couleur: éventuellement couleur
268 """
269
270   objet.setName(nom)
271   objet.result().setName(nom)
272
273   if ( couleur is not None ):
274     objet.result().setColor(couleur[0], couleur[1], couleur[2])
275
276 #=========================  Fin de la fonction ===================================
277
278 #========================= Début de la fonction ==================================
279
280 def exec_nom (fonction, nom=None, couleur=None):
281   """Exécute la fonction puis éventuellement la nomme et nomme son résultat ; Couleur éventuelle
282
283 Attention : il faut commencer par exécuter la fonction sinon l enommage n'est pas cohérent en mode macro. Mystère...
284
285 Entrées :
286   :fonction: fonction à traiter
287   :nom: nom à attribuer éventuellement
288   :couleur: éventuellement couleur
289 """
290
291   fonction.execute(True)
292
293   if ( nom is not None ):
294     nommage (fonction, nom, couleur)
295
296 #=========================  Fin de la fonction ===================================
297
298
299 #=================================== La classe ===================================
300
301 class SurfaceMediane (object):
302
303   """Calcul des surfaces médianes de solides minces
304
305 L'objectif de ce programme est de créer les surfaces médianes, encore appelées fibres neutres, pour \
306 une structure qui est un solide ou un assemblage de solides (compound).
307 Pour réaliser l'opération, trois façons de faire :
308
309 1. On lance le script en précisant le fichier à analyser dans la zone d'auto-test.
310
311 2. Si on part d'un script qui manipule un fichier au format CAO, on crée une instance de la classe SurfaceMediane \
312 puis on appelle la méthode surf_fic_cao avec ce fichier en argument.
313
314 3. Si on part d'un script qui crée un objet SHAPER, on crée une instance de la classe SurfaceMediane \
315 puis on appelle la méthode surf_objet_shaper avec cet objet en argument.
316
317
318 Le programme crée les surfaces sous réserve que pour le solide envisagé, il a réussi à trouver deux faces \
319 de taille identique et supérieure aux tailles des autres faces du solide. \
320 Cela fonctionne pour des surfaces planes ou de forme canonique.
321 Il crée alors une surface au milieu de ces deux grandes faces. \
322 Cette face est coloriée en vert, le solide est en vert et transparent.
323
324 On sait traiter les faces :
325   . planes
326   . cylindriques
327   . sphériques
328   . toriques
329   . coniques
330
331 Si la création n'a pas eu lieu, un message est émis et les solides sont mis en couleur :
332 . Rouge : le solide n'est pas assez mince.
333 . Bleu : le solide est trop mince, vis-à-vis de la précision de SHAPER.
334 . Orange : la forme de la face n'est pas reconnue.
335
336 Options obligatoires
337 ********************
338 Aucune
339
340 Options facultatives
341 ********************
342 . Exportation finale dans un fichier step. Par défaut, pas d'export.
343 -export_step/-no_export_step
344
345 Arborescence :
346 surf_fic_cao --> import_cao
347              --> surf_objet_shaper (récursif) --> _nom_sous_objets
348                                               --> _surf_objet_shaper_0
349                                               --> surf_solide_shaper --> _isole_solide --> _isole_solide_a
350                                                                                        --> _isole_solide_b
351                                                                      --> _traitement_objet --> face_mediane_solide --> _faces_du_solide
352                                                                                                                    --> _tri_faces
353                                                                                                                    --> _cree_face_mediane
354
355 _cree_face_mediane --> _cree_face_mediane_plane
356                    --> _cree_face_mediane_cylindre
357                    --> _cree_face_mediane_sphere
358                    --> _cree_face_mediane_tore
359                    --> _cree_face_mediane_cone
360                    --> _cree_face_mediane_0
361
362 """
363
364 # A. La base
365
366   message_info = ""
367   _verbose = 0
368   _verbose_max = 0
369   affiche_aide_globale = 0
370
371 # B. Les variables
372
373   _choix_objet = 0
374   _export_step = False
375   nom_solide = None
376   nom_solide_aux = None
377   _epsilon = 5.e-2
378   part_doc = None
379
380   ficcao = None
381   rep_step = None
382   objet_principal = None
383   # Pour chaque sous-objet dans l'ordre de l'arborescence : nom
384   l_noms_so = list()
385   # Statut de chaque sous-objet connu par son nom :
386   # 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
387   d_statut_so = dict()
388   # Liste des faces médianes créées et des fonctions initiales
389   l_faces_m = list()
390   # La fonction initiale
391   fonction_0 = None
392
393   faces_pb_nb = 0
394   faces_pb_msg = ""
395
396 #=========================== Début de la méthode =================================
397
398   def __init__ ( self, liste_option ):
399
400     """Le constructeur de la classe SurfaceMediane
401
402 Décodage des arguments
403 On cherche ici les arguments généraux : aide, verbeux
404 """
405
406     for option in liste_option :
407
408       #print (option)
409       if isinstance(option,str):
410         saux = option.upper()
411       #print (saux)
412       if saux in ( "-H", "-HELP" ):
413         self.affiche_aide_globale = 1
414       elif saux == "-V" :
415         self._verbose = 1
416       elif saux == "-VMAX" :
417         self._verbose = 1
418         self._verbose_max = 1
419       elif saux == "-EXPORT_STEP":
420         self._export_step = True
421       elif saux == "-NO_EXPORT_STEP":
422         self._export_step = False
423
424 #===========================  Fin de la méthode ==================================
425
426 #=========================== Début de la méthode =================================
427
428   def __del__(self):
429     """A la suppression de l'instance de classe"""
430     if self._verbose_max:
431       print ("Suppression de l'instance de la classe.")
432
433 #===========================  Fin de la méthode ==================================
434
435 #=========================== Début de la méthode =================================
436
437   def _nom_sous_objets (self, objet, lecture, n_recur=0, rang=0):
438     """Gère les noms des sous_objets solides
439
440 Entrées :
441   :objet: objet à traiter
442   :lecture: vrai pour lire les noms, faux pour les attribuer
443   :n_recur: niveau de récursivité
444   :rang: rang du sous-objet
445
446 Sorties :
447   :rang: rang du sous-objet
448 """
449
450     nom_fonction = __name__ + "/_nom_sous_objets"
451     blabla = "Dans {} :\n".format(nom_fonction)
452
453     if self._verbose_max:
454       prefixe = ""
455       for _ in range(n_recur):
456         prefixe += "\t"
457       texte = "\n{}{}".format(prefixe,blabla)
458       texte += "{}n_recur = {}".format(prefixe,n_recur)
459       texte += "\n{}lecture = {}".format(prefixe,lecture)
460       print (texte)
461
462 # 1. Au premier passage, il faut garder la référence au résultat principal
463
464     if ( n_recur ==  0 ):
465       objet_0 = objet.result()
466       if self._verbose_max:
467         print ("d_statut_so = {}".format(self.d_statut_so))
468     else:
469       objet_0 = objet
470
471 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
472
473     nb_sub_results = objet_0.numberOfSubs()
474
475     if self._verbose_max:
476       texte = "{}Examen de l'objet '{}' ".format(prefixe,objet_0.name())
477       texte += "de type '{}'".format(objet_0.shapeType())
478       texte += "\n{}objet.result().numberOfSubs() : {}".format(prefixe,nb_sub_results)
479       print (texte)
480
481     for n_sobj in range(nb_sub_results):
482
483 # 2.1. Exploration récursive de l'arborescence
484
485       rang = self._nom_sous_objets ( objet_0.subResult(n_sobj), lecture, n_recur+1, rang )
486
487 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
488
489     if ( objet_0.shapeType() == "SOLID" ):
490       # A la lecture, on enregistre le nom
491       if lecture:
492         nom = objet_0.name()
493         self.l_noms_so.append(nom)
494         self.d_statut_so[nom] = 0
495       # A la récupération, on redonne le nom et on affecte une couleur dépendant de l'état
496       else:
497         nom = self.l_noms_so[rang]
498         objet_0.setName(nom)
499         etat = self.d_statut_so[nom]
500         objet_0.setColor (D_COLOR_R[etat],D_COLOR_G[etat],D_COLOR_B[etat])
501         if ( etat == 1 ):
502           objet_0.setTransparency (TRANSPARENCE)
503         rang += 1
504
505     return rang
506
507 #===========================  Fin de la méthode ==================================
508
509 #=========================== Début de la méthode =================================
510
511   def _isole_solide ( self, solide, n_recur ):
512     """Isole le solide de son arboresence
513
514 Entrées :
515   :solide: le solide à traiter
516   :n_recur: numéro de la récurrence
517
518 Sorties :
519   :objet: le solide isolé
520   :recover: la fonction de récupération
521 """
522
523     nom_fonction = __name__ + "/_isole_solide"
524     blabla = "Dans {} :".format(nom_fonction)
525     if self._verbose_max:
526       print_tab (n_recur, blabla)
527       texte = "Pour le solide '{}' ".format(solide.name())
528       texte += "de l'objet principal '{}'".format(self.objet_principal.name())
529       print_tab (n_recur, texte)
530
531     if ( solide.name() != self.objet_principal.name() ):
532       objet, recover = self._isole_solide_a ( solide, n_recur )
533
534     else:
535       objet, recover = self._isole_solide_b ( solide, n_recur )
536
537     if self._verbose_max:
538       print_tab (n_recur, "objet final : ", objet.name())
539       print_tab (n_recur, "fonction_0 : {}".format(self.fonction_0))
540       print_tab (n_recur, "recover : {}".format(recover))
541
542     return objet, recover
543
544 #===========================  Fin de la méthode ==================================
545
546 #=========================== Début de la méthode =================================
547
548   def _isole_solide_a ( self, solide, n_recur ):
549     """Isole le solide de son arboresence
550
551 Entrées :
552   :solide: le solide à traiter
553   :n_recur: numéro de la récurrence
554
555 Sorties :
556   :objet: le solide isolé
557   :recover: la fonction de récupération
558 """
559
560     nom_fonction = __name__ + "/_isole_solide_a"
561     blabla = "Dans {} :".format(nom_fonction)
562     if self._verbose_max:
563       print_tab (n_recur, blabla)
564       texte = "Pour le solide '{}' ".format(solide.name())
565       texte += "de l'objet principal '{}'".format(self.objet_principal.name())
566       print_tab (n_recur, texte)
567
568     if self._verbose_max:
569       print_tab (n_recur, ". Extraction du solide '{}'".format(self.objet_principal.name()))
570
571 # 1. Extraction du solide
572     remove_subshapes = model.addRemoveSubShapes(self.part_doc, model.selection("COMPOUND", self.objet_principal.name()))
573     remove_subshapes.setSubShapesToKeep([model.selection("SOLID", solide.name())])
574
575     self.nom_solide_aux = "{}_S".format(solide.name())
576     if self._verbose_max:
577       print_tab (n_recur, "\tAttribution à remove_subshapes.result() du nom '{}'".format(self.nom_solide_aux))
578     exec_nom (remove_subshapes,self.nom_solide_aux)
579
580     self.fonction_0 = remove_subshapes
581
582 # 2. Récupération de l'objet principal
583     recover = model.addRecover(self.part_doc, remove_subshapes, [self.objet_principal])
584     if self._verbose_max:
585       print_tab (n_recur, "\tAttribution à recover du nom '{}'".format(self.objet_principal.name()))
586     exec_nom (recover,self.objet_principal.name())
587
588     return remove_subshapes.result(), recover
589
590 #===========================  Fin de la méthode ==================================
591
592 #=========================== Début de la méthode =================================
593
594   def _isole_solide_b ( self, solide, n_recur ):
595     """Isole le solide de son arboresence
596
597 Entrées :
598   :solide: le solide à traiter
599   :n_recur: numéro de la récurrence
600
601 Sorties :
602   :objet: le solide isolé
603   :recover: la fonction de récupération
604 """
605
606     nom_fonction = __name__ + "/_isole_solide_b"
607     blabla = "Dans {} :".format(nom_fonction)
608     if self._verbose_max:
609       print_tab (n_recur, blabla)
610       texte = "Pour le solide '{}' ".format(solide.name())
611       texte += "de l'objet principal '{}'".format(self.objet_principal.name())
612       print_tab (n_recur, texte)
613
614     if self._verbose_max:
615       print_tab (n_recur, ". Mise en place du solide")
616
617     self.nom_solide_aux = self.objet_principal.name()
618     self.fonction_0 = None
619
620     return solide, None
621
622 #===========================  Fin de la méthode ==================================
623
624 #=========================== Début de la méthode =================================
625
626   def _faces_du_solide ( self, solide, n_recur=0 ):
627     """Détermine les faces d'un solide
628
629 Entrées :
630   :solide: solide SHAPER à traiter
631   :n_recur: niveau de récursivité
632
633 Sorties :
634   :l_faces_car: pour chaque face du solide (surface,caractéristiques)
635 """
636
637     nom_fonction = __name__ + "/_faces_du_solide"
638     blabla = "Dans {} :".format(nom_fonction)
639     if self._verbose_max:
640       print_tab (n_recur, blabla, saut_av=True)
641
642     l_faces = list()
643
644     if self._verbose_max:
645       print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
646       print_tab (n_recur, ".. shapeType : ", solide.shapeType())
647
648     #print (dir(solide))
649     #print_tab (n_recur, "volume = ", GeomAlgoAPI_ShapeTools.volume(solide.shape()))
650 # 1. Repérage des faces
651     objResult = solide.resultSubShapePair()[0]
652     l_faces = list()
653     exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
654     while exp.more():
655       l_faces.append(exp.current().face())
656       exp.next()
657
658 # 2. Calcul
659     l_faces_car = list()
660     for iface, face in enumerate(l_faces):
661       surf = GeomAlgoAPI_ShapeTools.area(face)
662       caract = geom.shapeInfo(face)
663       if self._verbose_max:
664         print_tab (n_recur, "\tFace n°{} ; ".format(iface), "surface = {}, caractéristiques = {}".format(surf,caract))
665       l_faces_car.append((surf,caract))
666
667     return l_faces_car
668
669 #===========================  Fin de la méthode ==================================
670
671 #=========================== Début de la méthode =================================
672
673   def _calcul_caract_faces ( self, solide, n_recur ):
674     """Calcule les caractéristiques géométriques des faces du solide
675
676 Entrées :
677   :solide: solide SHAPER à traiter
678   :n_recur: niveau de récursivité
679
680 Sorties :
681   :tb_caract: tableau des caractéristiques géométriques des faces
682 """
683
684     nom_fonction = __name__ + "/_calcul_caract_faces"
685     blabla = "Dans {} :".format(nom_fonction)
686     if self._verbose_max:
687       print_tab (n_recur, blabla, saut_av=True)
688       print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
689       print_tab (n_recur, ".. shapeType : ", solide.shapeType())
690
691 # 1. Repérage des faces
692     objResult = solide.resultSubShapePair()[0]
693     l_faces = list()
694     exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
695     while exp.more():
696       l_faces.append(exp.current().face())
697       exp.next()
698
699 # 2. Caractéristiques
700     nb_faces = len(l_faces)
701     tb_caract = np.zeros((nb_faces,3), dtype = 'object')
702     for iaux, face in enumerate(l_faces):
703       surf = GeomAlgoAPI_ShapeTools.area(face)
704       caract = geom.shapeInfo(face)
705       if self._verbose_max:
706         print_tab (n_recur, "\tFace n°{} ; ".format(iaux), "surface = {}, caractéristiques = {}".format(surf,caract))
707
708       tb_caract [iaux][0] = face
709       tb_caract [iaux][1] = surf
710       tb_caract [iaux][2] = caract
711
712     #if self._verbose_max:
713       #for iaux in range(nb_faces):
714         #print ("\t. tb_caract : {} {}".format(surf,tb_caract[iaux][2]))
715
716     return tb_caract
717
718 #===========================  Fin de la méthode ==================================
719
720 #=========================== Début de la méthode =================================
721
722   def _tri_faces ( self, tb_caract, n_recur ):
723     """Trie les faces en fonction de leurs surfaces
724
725 Entrées :
726   :tb_caract: tableau des caractéristiques géométriques des faces
727   :n_recur: niveau de récursivité
728
729 Sorties :
730   :tb_caract_1[-1], tb_caract_1[-2]: les caractéristiques des 2 faces les plus grandes
731 """
732
733     erreur = 0
734     message = ""
735
736     nom_fonction = __name__ + "/_tri_faces"
737     blabla = "Dans {} :".format(nom_fonction)
738
739 # 1. Tri du tableau en fonction des surfaces
740     if self._verbose_max:
741       print_tab (n_recur, blabla)
742       print_tab (n_recur, "tb_caract brut : ", tb_caract)
743     tb_caract_1 = sorted(tb_caract, key=lambda colonnes: colonnes[1])
744     if self._verbose_max:
745       print_tab (n_recur, "tb_caract trié :", tb_caract_1)
746
747     if self._verbose_max:
748       texte  = "\tSurface de la plus grande face      : {}, de caractéristiques {}\n".format(tb_caract_1[-1][1],tb_caract_1[-1][2])
749       texte += "\tSurface de la face suivante         : {}, de caractéristiques {}".format(tb_caract_1[-2][1],tb_caract_1[-2][2])
750       print (texte)
751
752 # 2. La surface suivante doit être différente, sinon ce n'est pas un solide mince
753     if ( len(tb_caract) > 2 ):
754
755       if self._verbose_max:
756         texte += "\tSurface de la 3ème face suivante    : {}, de caractéristiques {}".format(tb_caract_1[-3][1],tb_caract_1[-3][2])
757         print (texte)
758       ecart = np.abs((tb_caract_1[-1][1]-tb_caract_1[-3][1])/tb_caract_1[-1][1])
759       if ( ecart < self._epsilon ):
760         message  = "\nSolide '{}'\n".format(self.nom_solide)
761         message += ". Surface de la plus grande face   : {}\n".format(tb_caract_1[-1][1])
762         message += ". Surface de la 1ère face suivante : {}\n".format(tb_caract_1[-2][1])
763         message += ". Surface de la 2ème face suivante : {}\n".format(tb_caract_1[-3][1])
764         if self._verbose_max:
765           message += ". Ecart relatif :{:4.1f}%\n".format(ecart*100.)
766         message += "L'écart est trop faible par rapport à la limite de {}%.\n".format(self._epsilon*100.)
767         message += "==> Impossible de créer la face médiane car le solide n'est pas assez mince.\n"
768         erreur = -1
769         self.d_statut_so[self.nom_solide] = -1
770         self.faces_pb_nb += 1
771         self.faces_pb_msg += message
772
773     return erreur, message, tb_caract_1[-1], tb_caract_1[-2]
774
775 #===========================  Fin de la méthode ==================================
776
777 #=========================== Début de la méthode =================================
778
779   def _verif_epaisseur ( self, epaisseur ):
780     """Contrôle de la validité de l'épaisseur
781
782 Entrées :
783   :epaisseur: épaisseur du solide
784 """
785
786     nom_fonction = __name__ + "/_verif_epaisseur"
787     blabla = "Dans {} :\n".format(nom_fonction)
788
789     if self._verbose_max:
790       texte = blabla
791       texte += ". Epaisseur du solide : {}\n".format(epaisseur)
792       texte += ". EP_MIN              : {}".format(EP_MIN)
793       print (texte)
794
795     if ( epaisseur <= EP_MIN ):
796       message  = "\nSolide '{}'\n".format(self.nom_solide)
797       message += ". Epaisseur : {}\n".format(epaisseur)
798       message += "L'épaisseur est trop faible par rapport à la limite de {}.\n".format(EP_MIN)
799       message += "==> Impossible de créer la face médiane car le solide est trop mince.\n"
800       erreur = 2
801       self.d_statut_so[self.nom_solide] = 2
802       self.faces_pb_nb += 1
803       self.faces_pb_msg += message
804
805     else:
806       erreur = 0
807     #print ("erreur = {}".format(erreur))
808
809     return erreur
810
811 #===========================  Fin de la méthode ==================================
812
813 #=========================== Début de la méthode =================================
814
815   def _cree_face_mediane ( self, solide, caract_face_1, caract_face_2, n_recur ):
816     """Crée la face médiane entre deux autres
817
818 Entrées :
819   :solide: solide SHAPER à traiter
820   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
821   :n_recur: niveau de récursivité
822
823 Sorties :
824   :face: la face médiane créée
825 """
826
827     nom_fonction = __name__ + "/_cree_face_mediane"
828     blabla = "Dans {} :".format(nom_fonction)
829
830     if self._verbose_max:
831       print_tab (n_recur, blabla)
832       print_tab (n_recur, "face_1 : " ,caract_face_1)
833       print_tab (n_recur, "face_2 : " ,caract_face_2)
834
835     erreur = 0
836     face =  None
837
838 # 1. Forme de la face
839     forme = caract_face_1[2][0]
840
841 # 2. Traitement selon la forme de la face
842 # 2.1. Face plane
843     if forme in ( "Disk" , "Plane", "Rectangle"):
844       erreur, face = self._cree_face_mediane_plane ( solide, caract_face_1, caract_face_2, n_recur )
845
846 # 2.2. Face cylindrique
847     elif ( forme == "Cylinder" ):
848       erreur, face = self._cree_face_mediane_cylindre ( solide, caract_face_1, caract_face_2, n_recur )
849
850 # 2.3. Face sphérique
851     elif ( forme == "Sphere" ):
852       erreur, face = self._cree_face_mediane_sphere ( caract_face_1, caract_face_2, n_recur )
853
854 # 2.4. Face torique
855     elif ( forme == "Torus" ):
856       erreur, face = self._cree_face_mediane_tore ( caract_face_1, caract_face_2, n_recur )
857
858 # 2.5. Face conique
859     elif ( forme == "Cone" ):
860       erreur, face = self._cree_face_mediane_cone ( caract_face_1, caract_face_2, n_recur )
861
862 # 2.N. Face de forme inconnue
863     else:
864       message  = "\nSolide '{}'\n".format(self.nom_solide)
865       message += "sa face la plus grande est de forme : {}\n".format(forme)
866       message += "==> Impossible de créer la face médiane.\n"
867       erreur = -2
868       self.d_statut_so[self.nom_solide] = -2
869       self.faces_pb_nb += 1
870       self.faces_pb_msg += message
871
872 # 3. Gestion de la face produite
873
874     if face is not None:
875       self._cree_face_mediane_0 ( face, n_recur )
876
877     return erreur, face
878
879 #===========================  Fin de la méthode ==================================
880
881 #=========================== Début de la méthode =================================
882
883   def _cree_face_mediane_0 ( self, face, n_recur ):
884     """Gestion de la face médiane créée entre deux autres
885
886 Entrées :
887   :face: la face médiane créée
888   :n_recur: niveau de récursivité
889 """
890
891     nom_fonction = __name__ + "/_cree_face_mediane_0"
892     blabla = "Dans {} :".format(nom_fonction)
893
894     if self._verbose_max:
895       print_tab (n_recur, blabla)
896
897 # 1. Nom de la face
898     nom_face = self.nom_solide+"_M"
899     if self._verbose_max:
900       print_tab (n_recur,"Nom de la face créée : ", nom_face)
901     #if ( self.nom_solide_aux != self.objet_principal.name() ):
902       #nom_face += "S"
903     nommage (face, nom_face)
904
905 # 2. Mémorisation de la face et de la fonction initiale
906     self.l_faces_m.append((face, self.fonction_0))
907
908 # 3. Couleur verte pour la face
909     couleur_objet (face, coul_r=0, coul_g=170, coul_b=0, verbose=self._verbose_max)
910
911 # 4. Changement de statut pour le solide
912     self.d_statut_so[self.nom_solide] = 1
913
914 #===========================  Fin de la méthode ==================================
915
916 #=========================== Début de la méthode =================================
917
918   def _cree_face_mediane_plane ( self, solide, caract_face_1, caract_face_2, n_recur ):
919     """Crée la face médiane entre deux autres - cas des surfaces planes
920
921 Entrées :
922   :solide: l'objet solide à traiter
923   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
924   :n_recur: niveau de récursivité
925
926 Sorties :
927   :face: la face médiane
928 """
929
930     nom_fonction = __name__ + "/_cree_face_mediane_plane"
931     blabla = "Dans {} :".format(nom_fonction)
932     if self._verbose_max:
933       print_tab (n_recur, blabla)
934
935 #   Caractéristiques des surfaces
936     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 )
937
938 #   Contrôle de la validité de l'épaisseur
939     erreur = self._verif_epaisseur ( d_face_1_2 )
940
941 #   Création de la face
942     if not erreur:
943       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 )
944     else:
945       face = None
946
947     return erreur, face
948
949 #===========================  Fin de la méthode ==================================
950
951 #=========================== Début de la méthode =================================
952
953   def _cree_face_mediane_plane_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
954     """Crée la face médiane entre deux autres - cas des surfaces planes
955
956 Décodage des caractéristiques
957
958 Entrées :
959   :solide: l'objet solide à traiter
960   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
961   :n_recur: niveau de récursivité
962
963 Sorties :
964   :coo_x, coo_y, coo_z: coordonnées du centre de la base
965   :vnor_x, vnor_y, vnor_z: coordonnées du vecteur normal
966   :taille: estimation de la taille de la future face
967   :d_face_1_2: la distance entre les deux faces
968 """
969
970     nom_fonction = __name__ + "/_cree_face_mediane_plane_0"
971     blabla = "Dans {} :".format(nom_fonction)
972
973     if self._verbose_max:
974       print_tab (n_recur, blabla)
975       print_tab (n_recur, "caract_face_1 : ", caract_face_1)
976       print_tab (n_recur, "caract_face_2 : ", caract_face_2)
977
978 # 1. Caractéristiques de la base
979 #   Coordonnées du centre de la base
980     coo_x = caract_face_1[2][1]
981     coo_y = caract_face_1[2][2]
982     coo_z = caract_face_1[2][3]
983 #   Coordonnées du vecteur normal
984     vnor_x = caract_face_1[2][4]
985     vnor_y = caract_face_1[2][5]
986     vnor_z = caract_face_1[2][6]
987 #   taille : une longueur caractéristique pour être certain de tout prendre
988     l_diag = self._calcul_lg_caract ( solide, n_recur )
989     taille = 10.*l_diag
990     if self._verbose_max:
991       print_tab (n_recur, "Taille englobante : ",taille)
992
993 # 2. Distance entre les deux faces
994     face_1 = caract_face_1[0]
995     face_2 = caract_face_2[0]
996     d_face_1_2 = GeomAlgoAPI_ShapeTools.minimalDistance(face_1, face_2)
997     if self._verbose_max:
998       print_tab (n_recur, "Distance entre les deux faces = ", d_face_1_2)
999
1000     return coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2
1001
1002 #===========================  Fin de la méthode ==================================
1003
1004 #=========================== Début de la méthode =================================
1005
1006   def _cree_face_mediane_plane_1 ( self, solide, coo_c, vnor, taille, d_face_1_2, n_recur ):
1007     """Crée la face médiane entre deux autres - cas des surfaces planes
1008
1009 Création des objets de construction et de la face médiane
1010
1011 Entrées :
1012   :solide: l'objet solide à traiter
1013   :coo_c: coordonnées du centre de la base
1014   :vnor: coordonnées du vecteur normal
1015   :taille: estimation de la taille de la future face
1016   :d_face_1_2: la distance entre les deux faces
1017   :n_recur: niveau de récursivité
1018
1019 Sorties :
1020   :face: la face médiane
1021 """
1022
1023     nom_fonction = __name__ + "/_cree_face_mediane_plane_1"
1024     blabla = "Dans {} :".format(nom_fonction)
1025     if self._verbose_max:
1026       print_tab (n_recur, blabla)
1027       print_tab (n_recur, "Centre   : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1028       print_tab (n_recur, "Normale  : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
1029       print_tab (n_recur, "Taille   : ", taille)
1030       print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1031
1032 # 1. Préalables
1033     _, v_norm, plan = self._cree_centre_axe_plan ( coo_c, vnor, self.nom_solide, n_recur )
1034
1035 # 2. Création de l'esquisse
1036     sketch = self._cree_face_mediane_plane_1_a ( plan, taille, n_recur )
1037
1038 # 3. La face
1039     face = self._cree_face_mediane_plane_1_b ( solide, sketch, v_norm, d_face_1_2, n_recur )
1040
1041     #print ("fin de {}".format(nom_fonction))
1042
1043     return face
1044
1045 #===========================  Fin de la méthode ==================================
1046
1047 #=========================== Début de la méthode =================================
1048
1049   def _cree_face_mediane_plane_1_a ( self, plan, taille, n_recur ):
1050     """Crée la face médiane entre deux autres - cas des surfaces planes - l'esquisse
1051
1052 Entrées :
1053   :plan: plan
1054   :taille: estimation de la taille de la future face
1055   :n_recur: niveau de récursivité
1056
1057 Sorties :
1058   :sketch: l'esquisse
1059 """
1060
1061     nom_fonction = __name__ + "/_cree_face_mediane_plane_1_a"
1062     blabla = "Dans {} :".format(nom_fonction)
1063     if self._verbose_max:
1064       print_tab (n_recur, blabla)
1065       print_tab (n_recur, "Plan      : {}".format(plan.name()))
1066       print_tab (n_recur, "taille    : {}".format(taille))
1067
1068     sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
1069     sketch.execute(True)
1070
1071     ### Create SketchLine
1072     SketchLine_1 = sketch.addLine(-taille/2., taille/2., taille/2., taille/2.)
1073     SketchLine_1.execute(True)
1074
1075     ### Create SketchLine
1076     SketchLine_2 = sketch.addLine(taille/2., taille/2., taille/2., -taille/2.)
1077     SketchLine_2.execute(True)
1078
1079     ### Create SketchLine
1080     SketchLine_3 = sketch.addLine(taille/2., -taille/2., -taille/2., -taille/2.)
1081     SketchLine_3.execute(True)
1082
1083     ### Create SketchLine
1084     SketchLine_4 = sketch.addLine(-taille/2., -taille/2., -taille/2., taille/2.)
1085     SketchLine_4.execute(True)
1086
1087     model.do()
1088
1089     nom_sketch = "{}_esquisse".format(self.nom_solide)
1090     exec_nom (sketch,nom_sketch)
1091
1092     #print ("fin de {}".format(nom_fonction))
1093
1094     return sketch
1095
1096 #===========================  Fin de la méthode ==================================
1097
1098 #=========================== Début de la méthode =================================
1099
1100   def _cree_face_mediane_plane_1_b ( self, solide, sketch, v_norm, d_face_1_2, n_recur ):
1101     """Crée la face médiane entre deux autres - cas des surfaces planes
1102
1103 Création de la face médiane
1104
1105 Entrées :
1106   :solide: l'objet solide à traiter
1107   :sketch: l'esquisse
1108   :v_norm: vecteur normal
1109   :d_face_1_2: la distance entre les deux faces
1110   :n_recur: niveau de récursivité
1111
1112 Sorties :
1113   :face: la face médiane
1114 """
1115
1116     nom_fonction = __name__ + "/_cree_face_mediane_plane_1_b"
1117     blabla = "Dans {} :".format(nom_fonction)
1118     if self._verbose_max:
1119       print_tab (n_recur, blabla)
1120       print_tab (n_recur, "Esquisse : ", sketch.name())
1121       print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1122
1123 # 1. Copie du solide pour gérer les intersections
1124     #Copy_1 = model.addCopy(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(self.nom_solide_aux))], 1)
1125     Copy_1 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", self.nom_solide_aux)], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
1126     nom = "{}_Copy_1".format(self.nom_solide_aux)
1127     exec_nom (Copy_1,nom)
1128     if self._verbose_max:
1129       print_tab (n_recur, "Après addMultiTranslation Copy_1 de nom ", nom)
1130     nom_solide = Copy_1.result().name()
1131
1132     ### Create Recover
1133     Recover_1 = model.addRecover(self.part_doc, Copy_1, [solide])
1134     nom = "{}_Recover_1".format(self.nom_solide_aux)
1135     exec_nom (Recover_1,nom)
1136     if self._verbose_max:
1137       print_tab (n_recur, "Après addRecover Recover_1 de nom ", nom)
1138
1139 # 2. Création d'une face ; on la translate d'une demi-épaisseur.
1140     for iaux in range(2):
1141
1142 # 2.1. Création d'une face à partir du sketch et translation perpendiculaire au plan de la face
1143 #      On essaie les 2 côtés alternativement car on ne sait pas lequel sera le bon
1144
1145       d_trans = -0.5*d_face_1_2*float(2*iaux-1)
1146
1147       face = self._cree_face_mediane_plane_2 ( sketch.name(), v_norm.name(), nom_solide, d_trans, iaux, n_recur )
1148
1149 # 2.2. Si on est du bon côté, alors on intersecte la face avec le solide et c'est bon
1150       if face.results():
1151         face = self._cree_face_mediane_plane_11 ( face, Recover_1, n_recur )
1152         break
1153
1154 # 2.3. Si l'intersection est vide, on crée une nouvelle copie du solide avant de tester l'autre côté
1155       else:
1156         if self._verbose_max:
1157           print_tab (n_recur, "L'intersection est vide. On essaie l'autre côté")
1158
1159         ### Create LinearCopy
1160         #Copy_2 = model.addCopy(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(self.nom_solide_aux))], 1)
1161         Copy_2 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", Recover_1.result().name())], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
1162         nom = "{}_Copy_2".format(self.nom_solide_aux)
1163         exec_nom (Copy_2,nom)
1164         if self._verbose_max:
1165           print_tab (n_recur, "Après addMultiTranslation Copy_2 de nom ", nom)
1166         nom_solide = Copy_2.result().name()
1167
1168     #print ("fin de {}".format(nom_fonction))
1169
1170     return face
1171
1172 #===========================  Fin de la méthode ==================================
1173
1174 #=========================== Début de la méthode =================================
1175
1176   def _cree_face_mediane_plane_11 ( self, face, Recover_1, n_recur ):
1177     """Crée la face médiane entre deux autres - cas des surfaces planes
1178
1179 Création des objets de construction et de la face médiane
1180
1181 Entrées :
1182   :face: la face médiane
1183   :Recover_1: la récupératiuon du solide
1184   :n_recur: niveau de récursivité
1185
1186 Sorties :
1187   :face: la face médiane
1188 """
1189
1190     nom_fonction = __name__ + "/_cree_face_mediane_plane_11"
1191     blabla = "Dans {} :".format(nom_fonction)
1192     if self._verbose_max:
1193       print_tab (n_recur, blabla)
1194       print_tab (n_recur, "face : ", face.name())
1195
1196     # Si on traite un objet solide unique, on le récupère
1197     if ( self.nom_solide_aux == self.objet_principal.name() ):
1198       if self._verbose_max:
1199         print_tab (n_recur, "On traite un objet solide unique ==> on le récupère.")
1200       Recover_2 = model.addRecover(self.part_doc, face, [Recover_1.result()])
1201       nom = "{}_Recover_2".format(self.nom_solide_aux)
1202       exec_nom (Recover_2,nom)
1203
1204     nb_inter = face.result().numberOfSubs()
1205     if self._verbose_max:
1206       print_tab (n_recur, "Nombre d'intersections : ", nb_inter)
1207
1208     if (nb_inter > 1 ):
1209       face = self._cree_face_mediane_plane_3 ( face )
1210
1211     return face
1212
1213 #===========================  Fin de la méthode ==================================
1214
1215 #=========================== Début de la méthode =================================
1216
1217   def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, d_trans, icpt, n_recur ):
1218     """Crée la face médiane entre deux autres - cas des surfaces planes
1219
1220 Intersection de la face avec le solide
1221
1222 Entrées :
1223   :nom_sketch: nom de l'esquisse
1224   :nom_normal: nom du vecteur normal
1225   :nom_solide: nom du solide à intersecter
1226   :d_trans: la distance de translation
1227   :icpt: numéro de la tentative
1228
1229 Sorties :
1230   :face: la face médiane
1231 """
1232
1233     nom_fonction = __name__ + "/_cree_face_mediane_plane_2"
1234     blabla = "Dans {} :".format(nom_fonction)
1235     if self._verbose_max:
1236       print_tab (n_recur, blabla)
1237       print_tab (n_recur, "nom_sketch : ", nom_sketch)
1238       print_tab (n_recur, "nom_normal : ", nom_normal)
1239       print_tab (n_recur, "nom_solide : ", nom_solide)
1240       print_tab (n_recur, "d_trans    : ", d_trans)
1241
1242     # Création d'une face
1243     Face_1 = model.addFace(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(nom_sketch))])
1244     nom = "{}_Face_1_{}".format(self.nom_solide_aux,icpt)
1245     exec_nom (Face_1,nom)
1246     if self._verbose_max:
1247       print_tab (n_recur, "Après addFace pour Face_1 de nom ", nom)
1248
1249 #   On la translate
1250     Translation_1 = model.addTranslation(self.part_doc, [model.selection("FACE", Face_1.result().name())], axis = model.selection("EDGE", nom_normal), distance = d_trans, keepSubResults = True)
1251     nom = "{}_trans_{}".format(self.nom_solide_aux,icpt)
1252     exec_nom (Translation_1,nom)
1253     if self._verbose_max:
1254       print_tab (n_recur, "Après addTranslation pour Translation_1 de nom ", nom)
1255     Translation_1.result().setColor(85, 0, 255)
1256
1257 #   Intersection de cette face avec le solide initial
1258     face = self._creation_face_inter ( Translation_1.result().name(), nom_solide )
1259
1260     return face
1261
1262 #===========================  Fin de la méthode ==================================
1263
1264 #=========================== Début de la méthode =================================
1265
1266   def _cree_face_mediane_plane_3 ( self, face ):
1267     """Crée la face médiane entre deux autres - cas des surfaces planes
1268
1269 Fusion des 2 intersections
1270
1271 Entrées :
1272   :face: la face médiane composée de plusieurs intersections
1273
1274 Sorties :
1275   :face_m: la face médiane
1276 """
1277
1278     nom_fonction = __name__ + "/_cree_face_mediane_plane_3"
1279     blabla = "Dans {} :\n".format(nom_fonction)
1280     if self._verbose_max:
1281       texte = blabla
1282       print (texte)
1283
1284 # Nommage des sous-objets
1285     l_fuse = list()
1286     for iaux in range(face.result().numberOfSubs()):
1287       nom = "{}_common_{}".format(self.nom_solide_aux,iaux)
1288       face.result().subResult(iaux).setName(nom)
1289       l_fuse.append(model.selection("FACE", '{}'.format(nom)))
1290
1291 #   Fusion
1292     if self._verbose_max:
1293       print ("Fusion de {} faces.".format(len(l_fuse)))
1294     face_m = model.addFuse(self.part_doc, l_fuse, keepSubResults = True)
1295     face_m.execute(True)
1296
1297     return face_m
1298
1299 #===========================  Fin de la méthode ==================================
1300
1301 #=========================== Début de la méthode =================================
1302
1303   def _cree_face_mediane_cylindre ( self, solide, caract_face_1, caract_face_2, n_recur ):
1304     """Crée la face médiane entre deux autres - cas des cylindres
1305
1306 Entrées :
1307   :solide: solide SHAPER à traiter
1308   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1309   :n_recur: niveau de récursivité
1310
1311 Sorties :
1312   :face: la face médiane
1313 """
1314
1315     nom_fonction = __name__ + "/_cree_face_mediane_cylindre"
1316     blabla = "Dans {} :".format(nom_fonction)
1317
1318 #   Les deux faces
1319     if self._verbose_max:
1320       print_tab (n_recur, blabla)
1321       print_tab (n_recur, "face_1 : ", caract_face_1)
1322       print_tab (n_recur, "face_2 : ", caract_face_2)
1323
1324 #   Caractéristiques des cylindres
1325     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 )
1326
1327 #   Contrôle de la validité de l'épaisseur
1328     erreur = self._verif_epaisseur ( epaisseur )
1329
1330 #   Création de la face, de couleur bleue si problème
1331     if not erreur:
1332       face = self._cree_face_mediane_cylindre_1 ( (coo_x, coo_y, coo_z), (axe_x, axe_y, axe_z), rayon, hauteur, n_recur )
1333     else:
1334       couleur_objet (solide, n_recur, coul_r=0, coul_g=0, coul_b=255, verbose=self._verbose_max)
1335       face = None
1336
1337     return erreur, face
1338
1339 #===========================  Fin de la méthode ==================================
1340
1341 #=========================== Début de la méthode =================================
1342
1343   def _cree_face_mediane_cylindre_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
1344     """Crée la face médiane entre deux autres - cas des cylindres
1345
1346 Décodage des caractéristiques
1347
1348 Entrées :
1349   :solide: l'objet solide à traiter
1350   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1351   :n_recur: niveau de récursivité
1352
1353 Sorties :
1354   :coo_x, coo_y, coo_z: coordonnées du centre de la base
1355   :axe_x, axe_y, axe_z: coordonnées de l'axe
1356   :rayon: rayon moyen entre les deux faces
1357   :hauteur: hauteur du cylindre
1358   :epaisseur: épaisseur de l'interface entre les deux faces
1359 """
1360
1361     nom_fonction = __name__ + "/_cree_face_mediane_cylindre_0"
1362     blabla = "Dans {} :".format(nom_fonction)
1363
1364     if self._verbose_max:
1365       print_tab (n_recur, blabla)
1366       print_tab (n_recur, "face_1 : ", caract_face_1)
1367       print_tab (n_recur, "face_2 : ", caract_face_2)
1368
1369 #   Coordonnées du centre de la base
1370     coo_x = caract_face_1[2][1]
1371     coo_y = caract_face_1[2][2]
1372     coo_z = caract_face_1[2][3]
1373 #   Coordonnées de l'axe
1374     axe_x = caract_face_1[2][4]
1375     axe_y = caract_face_1[2][5]
1376     axe_z = caract_face_1[2][6]
1377 #   Rayons
1378     rayon = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1379 #   Hauteur : une longueur caractéristique pour être certain de tout prendre
1380     l_diag = self._calcul_lg_caract ( solide, n_recur )
1381     hauteur = 10.*l_diag
1382     if self._verbose_max:
1383       print_tab (n_recur, "Hauteur englobante : ", hauteur)
1384 #   Epaisseur
1385     epaisseur = np.abs(caract_face_2[2][7]-caract_face_1[2][7])
1386
1387     return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur
1388
1389 #===========================  Fin de la méthode ==================================
1390
1391 #=========================== Début de la méthode =================================
1392
1393   def _cree_face_mediane_cylindre_1 ( self, coo_c, v_axe, rayon, hauteur, n_recur ):
1394     """Crée la face médiane entre deux autres - cas des cylindres
1395
1396 Création des objets temporaires et de la face externe du cylindre support
1397
1398 Entrées :
1399   :coo_x, coo_y, coo_z: coordonnées du centre de la base
1400   :axe_x, axe_y, axe_z: coordonnées de l'axe
1401   :rayon: rayon moyen entre les deux faces
1402   :hauteur: hauteur du cylindre
1403   :n_recur: niveau de récursivité
1404
1405 Sorties :
1406   :face: la face médiane
1407 """
1408     nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1"
1409     blabla = "Dans {} :\n".format(nom_fonction)
1410
1411 #   Les caractéristiques du cylindre à créer
1412     if self._verbose_max:
1413       print_tab (n_recur, blabla)
1414       print_tab (n_recur, "Centre  : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1415       print_tab (n_recur, "Axe     : ({}, {}, {})".format(v_axe[0], v_axe[1], v_axe[2]))
1416       print_tab (n_recur, "Rayon   : ", rayon)
1417       print_tab (n_recur, "Hauteur : ", hauteur)
1418
1419 # 1. Création du point central
1420     centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
1421     nom_centre = "{}_centre".format(self.nom_solide)
1422     exec_nom (centre,nom_centre)
1423     if self.fonction_0 is None:
1424       self.fonction_0 = centre
1425
1426 # 2. Création du vecteur axial
1427     axe = model.addAxis(self.part_doc, v_axe[0], v_axe[1], v_axe[2])
1428     nom_axe = "{}_vecteur".format(self.nom_solide)
1429     exec_nom (axe,nom_axe)
1430
1431 # 3. Création du cylindre en volume, de rayon médian
1432     Cylinder_1 = model.addCylinder(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("EDGE", nom_axe), rayon, hauteur)
1433     nom = "{}_Cylinder_1".format(self.nom_solide)
1434     exec_nom (Cylinder_1,nom)
1435
1436 # 4. Création du cylindre en surface
1437     cylindre = self._creation_face_surface ( nom, "cylindre" )
1438
1439 # 5. Mise en place
1440     Translation_1 = model.addTranslation(self.part_doc, [model.selection("COMPOUND", cylindre.name())], axis = model.selection("EDGE", nom_axe), distance = -0.5*hauteur, keepSubResults = True)
1441     nom = "{}_Translation_1".format(self.nom_solide)
1442     exec_nom (Translation_1,nom)
1443
1444 # 6. Intersection de la face cylindrique avec le solide initial
1445     face = self._creation_face_inter ( nom )
1446
1447     return face
1448
1449 #===========================  Fin de la méthode ==================================
1450
1451 #=========================== Début de la méthode =================================
1452
1453   def _cree_face_mediane_sphere ( self, caract_face_1, caract_face_2, n_recur ):
1454     """Crée la face médiane entre deux autres - cas des sphères
1455
1456 Entrées :
1457   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1458   :n_recur: niveau de récursivité
1459
1460 Sorties :
1461   :face: la face médiane
1462 """
1463
1464     nom_fonction = __name__ + "/_cree_face_mediane_sphere"
1465     blabla = "Dans {} :".format(nom_fonction)
1466
1467 #   Les deux faces
1468     if self._verbose_max:
1469       print_tab (n_recur, blabla)
1470       print_tab (n_recur, "face_1 : ", caract_face_1)
1471       print_tab (n_recur, "face_2 : ", caract_face_2)
1472
1473 #   Caractéristiques des sphères
1474     coo_x, coo_y, coo_z, rayon, epaisseur = self._cree_face_mediane_sphere_0 ( caract_face_1, caract_face_2, n_recur )
1475
1476 #   Contrôle de la validité de l'épaisseur
1477     erreur = self._verif_epaisseur ( epaisseur )
1478
1479 #   Création de la face
1480     if not erreur:
1481       face = self._cree_face_mediane_sphere_1 ( coo_x, coo_y, coo_z, rayon )
1482     else:
1483       face = None
1484
1485     return erreur, face
1486
1487 #===========================  Fin de la méthode ==================================
1488
1489 #=========================== Début de la méthode =================================
1490
1491   def _cree_face_mediane_sphere_0 ( self, caract_face_1, caract_face_2, n_recur ):
1492     """Crée la face médiane entre deux autres - cas des sphères
1493
1494 Décodage des caractéristiques
1495
1496 Entrées :
1497   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1498   :n_recur: niveau de récursivité
1499
1500 Sorties :
1501   :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1502   :rayon: rayon moyen entre les deux faces
1503   :epaisseur: épaisseur de l'interface entre les deux faces
1504 """
1505
1506     nom_fonction = __name__ + "/_cree_face_mediane_sphere_0"
1507     blabla = "Dans {} :".format(nom_fonction)
1508
1509 #   Les deux faces
1510     if self._verbose_max:
1511       print_tab (n_recur, blabla)
1512       print_tab (n_recur, "face_1 : ", caract_face_1)
1513       print_tab (n_recur, "face_2 : ", caract_face_2)
1514
1515 #   Coordonnées du centre de la sphère
1516     coo_x = caract_face_1[2][1]
1517     coo_y = caract_face_1[2][2]
1518     coo_z = caract_face_1[2][3]
1519 #   Rayons
1520     rayon = (caract_face_2[2][4]+caract_face_1[2][4])/2.
1521 #   Epaisseur
1522     epaisseur = np.abs(caract_face_2[2][4]-caract_face_1[2][4])
1523
1524     return coo_x, coo_y, coo_z, rayon, epaisseur
1525
1526 #===========================  Fin de la méthode ==================================
1527
1528 #=========================== Début de la méthode =================================
1529
1530   def _cree_face_mediane_sphere_1 ( self, coo_x, coo_y, coo_z, rayon ):
1531     """Crée la face médiane entre deux autres - cas des sphères
1532
1533 Création des objets de construction et de la face externe de la sphère support
1534
1535 Entrées :
1536   :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1537   :rayon: rayon moyen entre les deux faces
1538
1539 Sorties :
1540   :face: la face externe de la sphère support
1541 """
1542
1543     nom_fonction = __name__ + "/_cree_face_mediane_sphere_1"
1544     blabla = "Dans {} :\n".format(nom_fonction)
1545
1546 #   Les caractéristiques de la sphère à créer
1547     if self._verbose_max:
1548       texte = blabla
1549       texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1550       texte += "Rayon : {}".format(rayon)
1551       print (texte)
1552
1553 # 1. Création du point central
1554     centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1555     nom_centre = "{}_centre".format(self.nom_solide)
1556     exec_nom (centre,nom_centre)
1557     if self.fonction_0 is None:
1558       self.fonction_0 = centre
1559
1560 # 2. Création de la sphère en volume, de rayon médian
1561     Sphere_1 = model.addSphere(self.part_doc, model.selection("VERTEX", nom_centre), rayon)
1562     nom = "{}_Sphere_1".format(self.nom_solide)
1563     exec_nom (Sphere_1,nom)
1564
1565 # 3. Création de la sphère en surface
1566     sphere = self._creation_face_surface ( nom, "sphere" )
1567
1568 # 4. Intersection de la face sphérique avec le solide initial
1569     face = self._creation_face_inter ( sphere.name() )
1570
1571     return face
1572
1573 #===========================  Fin de la méthode ==================================
1574
1575 #=========================== Début de la méthode =================================
1576
1577   def _cree_face_mediane_tore ( self, caract_face_1, caract_face_2, n_recur ):
1578     """Crée la face médiane entre deux autres - cas des tores
1579
1580 Entrées :
1581   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1582   :n_recur: niveau de récursivité
1583
1584 Sorties :
1585   :face: la face médiane
1586 """
1587
1588     nom_fonction = __name__ + "/_cree_face_mediane_tore"
1589     blabla = "Dans {} :".format(nom_fonction)
1590
1591 #   Les deux faces
1592     if self._verbose_max:
1593       print_tab (n_recur, blabla)
1594       print_tab (n_recur, "face_1 : ", caract_face_1)
1595       print_tab (n_recur, "face_2 : ", caract_face_2)
1596
1597 #   Caractéristiques des tores
1598     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 )
1599
1600 #   Contrôle de la validité de l'épaisseur (bidon)
1601     erreur = self._verif_epaisseur ( EP_MIN*10. )
1602
1603 #   Création de la face
1604     if not erreur:
1605       face = self._cree_face_mediane_tore_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 )
1606     else:
1607       face = None
1608
1609     return erreur, face
1610
1611 #===========================  Fin de la méthode ==================================
1612
1613 #=========================== Début de la méthode =================================
1614
1615   def _cree_face_mediane_tore_0 ( self, caract_face_1, caract_face_2, n_recur ):
1616     """Crée la face médiane entre deux autres - cas des tores
1617
1618 Décodage des caractéristiques
1619
1620 Entrées :
1621   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1622   :n_recur: niveau de récursivité
1623
1624 Sorties :
1625   :coo_x, coo_y, coo_z: coordonnées du centre du tore
1626   :axe_x, axe_y, axe_z: coordonnées de l'axe
1627   :rayon_1 : rayon principal
1628   :rayon_2 : rayon secondaire
1629 """
1630
1631     nom_fonction = __name__ + "/_cree_face_mediane_tore_0"
1632     blabla = "Dans {} :".format(nom_fonction)
1633
1634 #   Les deux faces
1635     if self._verbose_max:
1636       print_tab (n_recur, blabla)
1637       print_tab (n_recur, "face_1 : ", caract_face_1)
1638       print_tab (n_recur, "face_2 : ", caract_face_2)
1639
1640 #   Coordonnées du centre du tore
1641     coo_x = caract_face_1[2][1]
1642     coo_y = caract_face_1[2][2]
1643     coo_z = caract_face_1[2][3]
1644 #   Coordonnées de l'axe
1645     axe_x = caract_face_1[2][4]
1646     axe_y = caract_face_1[2][5]
1647     axe_z = caract_face_1[2][6]
1648 #   Rayons
1649     rayon_1 = caract_face_2[2][7]
1650     rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1651
1652     return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2
1653
1654 #===========================  Fin de la méthode ==================================
1655
1656 #=========================== Début de la méthode =================================
1657
1658   def _cree_face_mediane_tore_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 ):
1659     """Crée la face médiane entre deux autres - cas des tores
1660
1661 Création des objets de construction et de la face externe du tore support
1662
1663 Entrées :
1664   :coo_x, coo_y, coo_z: coordonnées du centre du tore
1665   :axe_x, axe_y, axe_z: coordonnées de l'axe
1666   :rayon_1 : rayon principal
1667   :rayon_2 : rayon secondaire
1668
1669 Sorties :
1670   :face: la face externe du tore support
1671 """
1672
1673     nom_fonction = __name__ + "/_cree_face_mediane_tore_1"
1674     blabla = "Dans {} :\n".format(nom_fonction)
1675
1676 #   Les deux faces
1677     if self._verbose_max:
1678       texte = blabla
1679       texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1680       texte += "Axe    : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1681       texte += "Rayon principal : {}\n".format(rayon_1)
1682       texte += "Rayon secondaire : {}".format(rayon_2)
1683       print (texte)
1684
1685 # 1. Création du point central
1686     centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1687     nom_centre = "{}_centre".format(self.nom_solide)
1688     exec_nom (centre,nom_centre)
1689
1690 # 2. Création de l'axe
1691     axe = model.addAxis(self.part_doc, axe_x, axe_y, axe_z)
1692     nom_axe = "{}_axe".format(self.nom_solide)
1693     exec_nom (axe,nom_axe)
1694
1695 # 3. Création du tore en volume, de rayon médian
1696     Tore_1 = model.addTorus(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("EDGE", nom_axe), rayon_1, rayon_2)
1697     nom = "{}_Tore_1".format(self.nom_solide)
1698     exec_nom (Tore_1,nom)
1699
1700 # 4. Création du tore en surface
1701     tore = self._creation_face_surface ( nom, "tore" )
1702
1703 # 5. Intersection de la face torique avec le solide initial
1704     face = self._creation_face_inter ( tore.name() )
1705
1706     return face
1707
1708 #===========================  Fin de la méthode ==================================
1709
1710 #=========================== Début de la méthode =================================
1711
1712   def _cree_face_mediane_cone ( self, caract_face_1, caract_face_2, n_recur ):
1713     """Crée la face médiane entre deux autres - cas des cones
1714
1715 Entrées :
1716   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1717   :n_recur: niveau de récursivité
1718
1719 Sorties :
1720   :face: la face médiane
1721 """
1722
1723     nom_fonction = __name__ + "/_cree_face_mediane_cone"
1724     blabla = "Dans {} :".format(nom_fonction)
1725
1726 #   Les deux faces
1727     if self._verbose_max:
1728       print_tab (n_recur, blabla)
1729       print_tab (n_recur, "face_1 : ", caract_face_1)
1730       print_tab (n_recur, "face_2 : ", caract_face_2)
1731
1732 #   Caractéristiques des cones
1733     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 )
1734
1735 #   Contrôle de la validité de l'épaisseur (bidon)
1736     erreur = self._verif_epaisseur ( EP_MIN*10. )
1737
1738 #   Création de la face
1739     if not erreur:
1740       face = self._cree_face_mediane_cone_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur )
1741     else:
1742       face = None
1743
1744     return erreur, face
1745
1746 #===========================  Fin de la méthode ==================================
1747
1748 #=========================== Début de la méthode =================================
1749
1750   def _cree_face_mediane_cone_0 ( self, caract_face_1, caract_face_2, n_recur ):
1751     """Crée la face médiane entre deux autres - cas des cones
1752
1753 Décodage des caractéristiques
1754
1755 Entrées :
1756   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1757   :n_recur: niveau de récursivité
1758
1759 Sorties :
1760   :coo_x, coo_y, coo_z: coordonnées du centre de la base
1761   :axe_x, axe_y, axe_z: coordonnées de l'axe
1762   :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1763   :hauteur: hauteur du cone
1764 """
1765
1766     nom_fonction = __name__ + "/_cree_face_mediane_cone_0"
1767     blabla = "Dans {} :".format(nom_fonction)
1768
1769 #   Les deux faces
1770     if self._verbose_max:
1771       print_tab (n_recur, blabla)
1772       print_tab (n_recur, "face_1 : ", caract_face_1)
1773       print_tab (n_recur, "face_2 : ", caract_face_2)
1774
1775 #   Coordonnées du centre de la base
1776     coo_x = caract_face_1[2][1]
1777     coo_y = caract_face_1[2][2]
1778     coo_z = caract_face_1[2][3]
1779 #   Coordonnées de l'axe
1780     axe_x = caract_face_1[2][4]
1781     axe_y = caract_face_1[2][5]
1782     axe_z = caract_face_1[2][6]
1783 #   Rayons
1784     rayon_1 = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1785     rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1786 #   Hauteur
1787     hauteur = caract_face_1[2][9]
1788
1789 #   Bilan
1790     if self._verbose_max:
1791       print_tab (n_recur, "coo_x : ", coo_x)
1792       print_tab (n_recur, "coo_y : ", coo_y)
1793       print_tab (n_recur, "coo_z : ", coo_z)
1794       print_tab (n_recur, "axe_x : ", axe_x)
1795       print_tab (n_recur, "axe_y : ", axe_y)
1796       print_tab (n_recur, "axe_z : ", axe_z)
1797       print_tab (n_recur, "rayon_1 : ", rayon_1)
1798       print_tab (n_recur, "rayon_2 : ", rayon_2)
1799       print_tab (n_recur, "hauteur : ", hauteur)
1800
1801     return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur
1802
1803 #===========================  Fin de la méthode ==================================
1804
1805 #=========================== Début de la méthode =================================
1806
1807   def _cree_face_mediane_cone_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur ):
1808     """Crée la face médiane entre deux autres - cas des cones
1809
1810 Création des objets de construction et de la face externe du cone support
1811
1812 Entrées :
1813   :coo_x, coo_y, coo_z: coordonnées du centre de la base
1814   :axe_x, axe_y, axe_z: coordonnées de l'axe
1815   :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1816   :hauteur: hauteur du cone
1817
1818 Sorties :
1819   :face: la face externe du cone support
1820 """
1821     nom_fonction = __name__ + "/_cree_face_mediane_cone_1"
1822     blabla = "Dans {} :\n".format(nom_fonction)
1823
1824 #   Les deux faces
1825     if self._verbose_max:
1826       texte = blabla
1827       texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1828       texte += "Axe    : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1829       texte += "Rayons : {}, {}\n".format(rayon_1, rayon_2)
1830       texte += "Hauteur : {}".format(hauteur)
1831       print (texte)
1832
1833 #   1. Création du point central de la base, côté rayon_1
1834     centre_1 = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1835     nom_centre_1 = "{}_centre_1".format(self.nom_solide)
1836     exec_nom (centre_1,nom_centre_1)
1837
1838 #   2. Création du point central, du côté de rayon_2
1839     centre_2 = model.addPoint(self.part_doc, coo_x+hauteur*axe_x, coo_y+hauteur*axe_y, coo_z+hauteur*axe_z)
1840     nom_centre_2 = "{}_centre_2".format(self.nom_solide)
1841     exec_nom (centre_2,nom_centre_2)
1842
1843 #   3. Création de l'axe
1844     axe = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre_1), model.selection("VERTEX", nom_centre_2))
1845     nom_axe = "{}_axe".format(self.nom_solide)
1846     exec_nom (axe,nom_axe)
1847
1848 #   4. Création d'un plan passant par le centre de la base et l'axe
1849 #   4.1. Création d'un vecteur perpendiculaire à l'axe
1850     coeff = 10.
1851     if ( (abs(axe_x)+abs(axe_y)) < self._epsilon ):
1852       v_perp = model.addAxis(self.part_doc, coeff, 0., 0.)
1853     else:
1854       v_perp = model.addAxis(self.part_doc, -coeff*axe_y, coeff*axe_x, 0.)
1855     nom_v_perp = "{}_v_perp".format(self.nom_solide)
1856     exec_nom (v_perp,nom_v_perp)
1857 #   4.2. Création du plan
1858     plan = model.addPlane(self.part_doc, model.selection("EDGE",nom_v_perp), model.selection("VERTEX", nom_centre_1), True)
1859     nom_plan = "{}_plan".format(self.nom_solide)
1860     exec_nom (plan,nom_plan)
1861
1862 #   5. Paramétrage
1863     nom_par_1 = "{}_R_1".format(self.nom_solide)
1864     param = model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1865     param.execute(True)
1866     nom_par_2 = "{}_R_2".format(self.nom_solide)
1867     param = model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1868     param.execute(True)
1869     nom_par_3 = "{}_H".format(self.nom_solide)
1870     param = model.addParameter(self.part_doc, "{}".format(nom_par_3), "{}".format(hauteur))
1871     param.execute(True)
1872
1873 #   6. Création de l'esquisse
1874
1875     sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1876     sketch.execute(True)
1877
1878 #   6.1. Projection des centres et de l'axe
1879     SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre_1), False)
1880     SketchProjection_1.execute(True)
1881     SketchPoint_1 = SketchProjection_1.createdFeature()
1882     SketchPoint_1.execute(True)
1883     sk_coo_x_1 = SketchAPI_Point(SketchPoint_1).coordinates().x()
1884     sk_coo_y_1 = SketchAPI_Point(SketchPoint_1).coordinates().y()
1885
1886     SketchProjection_2 = sketch.addProjection(model.selection("VERTEX", nom_centre_2), False)
1887     SketchProjection_2.execute(True)
1888     SketchPoint_2 = SketchProjection_2.createdFeature()
1889     SketchPoint_2.execute(True)
1890     sk_coo_x_2 = SketchAPI_Point(SketchPoint_2).coordinates().x()
1891     sk_coo_y_2 = SketchAPI_Point(SketchPoint_2).coordinates().y()
1892
1893     SketchProjection_3 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
1894     SketchProjection_3.execute(True)
1895     SketchLine_0 = SketchProjection_3.createdFeature()
1896     SketchLine_0.execute(True)
1897
1898 #   6.2. Lignes perpendiculaires à l'axe passant par les centres
1899     SketchLine_1 = sketch.addLine(sk_coo_x_1, sk_coo_y_1, sk_coo_x_1+rayon_1, sk_coo_y_1)
1900     SketchLine_1.execute(True)
1901     SketchLine_1.setAuxiliary(True)
1902     contrainte = sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.startPoint())
1903     contrainte.execute(True)
1904     contrainte = sketch.setPerpendicular(SketchLine_0.result(), SketchLine_1.result())
1905     contrainte.execute(True)
1906     contrainte = sketch.setLength(SketchLine_1.result(), nom_par_1)
1907     contrainte.execute(True)
1908
1909     SketchLine_2 = sketch.addLine(sk_coo_x_2, sk_coo_y_2, sk_coo_x_2+rayon_2, sk_coo_y_2)
1910     SketchLine_2.execute(True)
1911     SketchLine_2.setAuxiliary(True)
1912     contrainte = sketch.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_2.startPoint())
1913     contrainte.execute(True)
1914     contrainte = sketch.setPerpendicular(SketchLine_0.result(), SketchLine_2.result())
1915     contrainte.execute(True)
1916     contrainte = sketch.setLength(SketchLine_2.result(), nom_par_2)
1917     contrainte.execute(True)
1918
1919 #   6.3. Ligne joignant les extrémités des précédentes et point milieu
1920     SketchLine_3 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
1921     SketchLine_3.execute(True)
1922     contrainte = sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_1.endPoint())
1923     contrainte.execute(True)
1924     contrainte = sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_2.endPoint())
1925     contrainte.execute(True)
1926     SketchLine_3.setAuxiliary(True)
1927     SketchPoint_3 = sketch.addPoint(sk_coo_x_1, sk_coo_y_1)
1928     SketchPoint_3.execute(True)
1929     contrainte = sketch.setMiddlePoint(SketchLine_3.result(), SketchPoint_3.coordinates())
1930     contrainte.execute(True)
1931
1932 #   6.4. Ligne support de la future révolution
1933     SketchLine_4 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
1934     SketchLine_4.execute(True)
1935     contrainte = sketch.setMiddlePoint(SketchLine_4.result(), SketchPoint_3.coordinates())
1936     contrainte.execute(True)
1937     contrainte = sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_4.result())
1938     contrainte.execute(True)
1939     contrainte = sketch.setLength(SketchLine_4.result(), "1.2*{}".format(nom_par_3))
1940     contrainte.execute(True)
1941
1942     model.do()
1943
1944     nom_sketch = "{}_esquisse".format(self.nom_solide)
1945     exec_nom (sketch,nom_sketch)
1946
1947 #   7. Création du cone complet
1948     nom_cone = "{}_cone".format(self.nom_solide)
1949     self._cree_revolution ( nom_sketch, nom_centre_1, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_cone )
1950
1951 #   8. Intersection de la face conique avec le solide initial
1952     face = self._creation_face_inter ( nom_cone )
1953
1954     return face
1955
1956 #===========================  Fin de la méthode ==================================
1957
1958 #=========================== Début de la méthode =================================
1959
1960   def _cree_centre_axe_plan ( self, coo_c, vect, prefixe, n_recur ):
1961     """Crée un centre, un axe, un plan
1962
1963 Entrées :
1964   :coo_c: coordonnées du centre de la base
1965   :vect: coordonnées du vecteur
1966   :prefix: prefixe du nom des objets
1967   :n_recur: niveau de récursivité
1968
1969 Sorties :
1970   :centre: centre
1971   :normal: vecteur normal
1972   :plan: plan
1973 """
1974
1975     nom_fonction = __name__ + "/_cree_centre_axe_plan"
1976     blabla = "Dans {} :".format(nom_fonction)
1977     if self._verbose_max:
1978       print_tab (n_recur, blabla)
1979       print_tab (n_recur, "Centre   : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1980       print_tab (n_recur, "Normale  : ({}, {}, {})".format(vect[0], vect[1], vect[2]))
1981
1982 #   Création du point central
1983     centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
1984     nom_centre = "{}_centre".format(prefixe)
1985     exec_nom (centre,nom_centre)
1986     if self.fonction_0 is None:
1987       self.fonction_0 = centre
1988
1989 #   Création du vecteur
1990     vecteur = model.addAxis(self.part_doc, vect[0], vect[1], vect[2])
1991     nom_vect = "{}_vecteur".format(prefixe)
1992     exec_nom (vecteur,nom_vect)
1993
1994 #   Création du plan perpendiculaire au vecteur normal
1995     plan = model.addPlane(self.part_doc, model.selection("EDGE", vecteur.name()), model.selection("VERTEX", centre.name()), True)
1996     nom_plan = "{}_plan".format(prefixe)
1997     exec_nom (plan,nom_plan)
1998
1999     #print ("fin de {}".format(nom_fonction))
2000
2001     return centre, vecteur, plan
2002
2003 #===========================  Fin de la méthode ==================================
2004
2005 #=========================== Début de la méthode =================================
2006
2007   def _calcul_lg_caract ( self, objet, n_recur ):
2008     """Crée une longueur caractéristique de l'objet
2009
2010 Entrées :
2011   :objet: l'objet à traiter
2012   :n_recur: niveau de récursivité
2013
2014 Sorties :
2015   :l_caract: longueur caractéristique de l'objet
2016 """
2017
2018     nom_fonction = __name__ + "/_calcul_lg_caract"
2019     blabla = "Dans {} :".format(nom_fonction)
2020
2021     if self._verbose_max:
2022       print_tab (n_recur, blabla)
2023
2024     properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
2025     l_caract = properties[0]
2026
2027     if self._verbose_max:
2028       print_tab (n_recur, "Longueur caractéristique : ", l_caract)
2029
2030     return l_caract
2031
2032 #===========================  Fin de la méthode ==================================
2033
2034 #=========================== Début de la méthode =================================
2035
2036   def _cree_revolution ( self, nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_objet ):
2037     """Crée un volume de révolution
2038
2039 Entrées :
2040   :nom_sketch: nom de l'esquisse à révolutionner
2041   :nom_centre: nom du point associé au centre du volume de révolution
2042   :coo_x, coo_y, coo_z: coordonnées du centre du tore
2043   :axe_x, axe_y, axe_z: coordonnées de l'axe
2044   :rayon_1 : rayon principal
2045   :rayon_2 : rayon secondaire
2046   :nom_objet: nom de l'objet 2D créé
2047 """
2048
2049     nom_fonction = __name__ + "/_cree_revolution"
2050     blabla = "Dans {} :\n".format(nom_fonction)
2051
2052     if self._verbose_max:
2053       texte = blabla
2054       texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
2055       texte += "Axe    : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
2056       print (texte)
2057
2058 #   Création d'un point décalé par rapport au point central
2059     point = model.addPoint(self.part_doc, coo_x+axe_x, coo_y+axe_y, coo_z+axe_z)
2060     nom_point = "{}_point".format(self.nom_solide)
2061     exec_nom (point,nom_point)
2062
2063 #   Création de l'axe de la rotation
2064     axe_r = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("VERTEX", nom_point))
2065     nom_axe_r = "{}_axe_r".format(self.nom_solide)
2066     exec_nom (axe_r,nom_axe_r)
2067
2068 #   Création de l'objet complet
2069     objet = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", nom_axe_r), 360, 0, "Edges")
2070     exec_nom (objet, nom_objet, (85, 0, 255))
2071
2072 #===========================  Fin de la méthode ==================================
2073
2074 #=========================== Début de la méthode =================================
2075
2076   def _creation_face_surface ( self, nom_objet, suffixe ):
2077     """Crée la face qui est la surface externe d'un objet
2078
2079 . Crée le groupe de la face externe
2080 . Transforme le groupe en face résultat
2081
2082 Entrées :
2083   :nom_objet: nom de l'objet 3D à traiter
2084   :suffixe: suffixe pour nommer l'objet 2D
2085   :nom_solide: nom du solide initial ; si None, on prend self.nom_solide_aux
2086
2087 Sorties :
2088   :objet_2d: l'objet 2D support de la face externe de l'objet 3D
2089 """
2090
2091     nom_fonction = __name__ + "/_creation_face_inter"
2092     blabla = "Dans {} :\n".format(nom_fonction)
2093
2094     if self._verbose_max:
2095       print (blabla)
2096
2097 # 1. Le groupe de la surface
2098     groupe = model.addGroup(self.part_doc, "Faces", [model.selection("FACE", "{}/Face_1".format(nom_objet))])
2099     nom = "{}_{}_groupe".format(self.nom_solide,suffixe)
2100     exec_nom (groupe, nom, (85, 0, 255))
2101
2102 # 2. Création de la face en surface
2103     objet_2d = model.addGroupShape(self.part_doc, [model.selection("COMPOUND", nom)])
2104     nom = "{}_{}".format(self.nom_solide,suffixe)
2105     exec_nom (objet_2d, nom, (85, 0, 255))
2106
2107     return objet_2d
2108
2109 #===========================  Fin de la méthode ==================================
2110
2111 #=========================== Début de la méthode =================================
2112
2113   def _creation_face_inter ( self, nom_objet, nom_solide=None ):
2114     """Crée la face par intersection entre l'objet initial et une face complète
2115
2116 . Repère la face principale de l'objet support
2117 . Réalise l'intersection avec le solide initial
2118
2119 Entrées :
2120   :nom_objet: nom de l'objet 2D créé
2121   :nom_solide: nom du solide initial ; si None, on prend self.nom_solide_aux
2122
2123 Sorties :
2124   :face: la face externe de l'objet support intersecté avec le solide initial
2125 """
2126
2127     nom_fonction = __name__ + "/_creation_face_inter"
2128     blabla = "Dans {} :\n".format(nom_fonction)
2129
2130     if self._verbose_max:
2131       print (blabla)
2132
2133     if nom_solide is None:
2134       nom_solide = self.nom_solide_aux
2135
2136     face = model.addCommon(self.part_doc, [model.selection("SOLID", nom_solide), model.selection("FACE", nom_objet)], keepSubResults = True)
2137     face.execute(True)
2138
2139     return face
2140
2141 #===========================  Fin de la méthode ==================================
2142
2143 #=========================== Début de la méthode =================================
2144
2145   def face_mediane_solide (self, solide, n_recur=0):
2146     """Calcul de la face médiane pour un solide
2147
2148 Entrées :
2149   :solide: solide SHAPER à traiter
2150   :n_recur: niveau de récursivité
2151
2152 Sorties :
2153   :erreur: code d'erreur
2154   :message: message d'erreur
2155 """
2156
2157     nom_fonction = __name__ + "/face_mediane_solide"
2158     blabla = "Dans {} :".format(nom_fonction)
2159
2160     if self._verbose_max:
2161       print_tab (n_recur, blabla, saut_av=True)
2162     if self._verbose:
2163       print_tab (n_recur, "Traitement du solide ", solide.name())
2164
2165 # 1. Préalables
2166
2167     erreur = 0
2168     message = ""
2169
2170     while not erreur :
2171
2172 # 2. Calcul des caractéristiques géométriques des faces
2173
2174       tb_caract = self._calcul_caract_faces ( solide, n_recur )
2175
2176 # 3. Tri des faces en fonction de leurs caractéristiques géométriques
2177
2178       erreur, message, caract_face_1, caract_face_2 = self._tri_faces ( tb_caract, n_recur )
2179       if erreur:
2180         break
2181
2182 # 4. Création de la face médiane
2183
2184       erreur, face = self._cree_face_mediane ( solide, caract_face_1, caract_face_2, n_recur )
2185       if ( erreur or ( face is None ) ):
2186         break
2187
2188 # 6. Exportation step
2189
2190       if self._export_step:
2191         fichier = os.path.join(self.rep_step, "{}.stp".format(face.result().name()))
2192         export = model.exportToFile(self.part_doc, fichier, [model.selection(face.result().shapeType(), face.result().name())])
2193         export.execute(True)
2194         model.do()
2195
2196 # 7. La fin
2197
2198       break
2199
2200     if ( erreur and self._verbose_max ):
2201       print (blabla, message)
2202
2203     return erreur, message
2204
2205 #===========================  Fin de la méthode ==================================
2206
2207 #=========================== Début de la méthode =================================
2208
2209   def _traitement_objet (self, solide, n_recur=0):
2210     """Traitement d'un objet
2211
2212 Entrées :
2213   :solide: solide SHAPER à traiter
2214   :n_recur: niveau de récursivité
2215
2216 Sorties :
2217   :erreur: code d'erreur
2218   :message: message d'erreur
2219 """
2220
2221     nom_fonction = __name__ + "/_traitement_objet"
2222     blabla = "Dans {} :".format(nom_fonction)
2223
2224     if self._verbose_max:
2225       print_tab (n_recur, blabla, saut_av=True)
2226       texte = "solide = {} ".format(solide.name())
2227       print_tab (n_recur, texte, solide)
2228
2229 # 1. En cas d'exportation step, répertoire de travail associé à l'éventuel fichier de départ
2230 #    Attention à ne pas recréer le répertoire à chaque fois
2231     if self._export_step:
2232
2233       if self.rep_step is None:
2234
2235         if self._verbose_max:
2236           print_tab (n_recur, "Préparation de l'export STEP")
2237
2238         if self.ficcao is None:
2239           self.rep_step = tempfile.mkdtemp(prefix="{}_".format(self.objet_principal.name()))
2240         else:
2241           self.rep_step = os.path.join(os.path.dirname(self.ficcao),"{}_M".format(self.objet_principal.name()))
2242           if os.path.isdir(self.rep_step):
2243             l_aux = os.listdir(self.rep_step)
2244             for nomfic in l_aux:
2245               os.remove(os.path.join(self.rep_step,nomfic))
2246           else:
2247             os.mkdir(self.rep_step)
2248
2249       if self._verbose_max:
2250         print_tab (n_recur, "Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
2251
2252 # 2. Calcul réel de la face médiane
2253
2254     erreur, message = self.face_mediane_solide (solide, n_recur)
2255
2256     return erreur, message
2257
2258 #===========================  Fin de la méthode ==================================
2259
2260 #=========================== Début de la méthode =================================
2261
2262   def surf_fic_cao (self, ficcao, nom_objet=None):
2263     """Calcule la surface médiane pour un objet dans un fichier passé en argument
2264
2265 Entrées :
2266   :ficcao: fichier de l'objet à traiter
2267   :nom_objet: un nom à donner à l'objet à traiter
2268
2269 Sorties :
2270   :erreur: code d'erreur
2271   :message: message d'erreur
2272 """
2273
2274     nom_fonction = __name__ + "/surf_fic_cao"
2275     blabla = "Dans {} :".format(nom_fonction)
2276
2277     if self._verbose_max:
2278       print (blabla)
2279
2280     erreur = 0
2281     message = ""
2282
2283     model.begin()
2284
2285     while not erreur :
2286
2287       if self.affiche_aide_globale:
2288         break
2289
2290 # 1. Définition de la pièce
2291
2292       self.part_doc = model.activeDocument()
2293       if ( self.part_doc.kind() == "PartSet" ):
2294         part = model.addPart(self.part_doc)
2295         self.part_doc = part.document()
2296
2297 # 2. Import de la CAO
2298
2299       self.ficcao = ficcao
2300       print ("Traitement du fichier {}".format(ficcao))
2301
2302       erreur, message, objet = import_cao (self.part_doc, ficcao, nom_objet, self._verbose_max)
2303       if erreur:
2304         break
2305
2306 # 3. Calcul des surfaces
2307
2308       erreur, message = self.surf_objet_shaper ( objet )
2309       if erreur:
2310         break
2311       #print (message)
2312
2313       break
2314
2315     if ( erreur and self._verbose_max ):
2316       print (blabla, message)
2317
2318     return erreur, message
2319
2320 #===========================  Fin de la méthode ==================================
2321
2322 #=========================== Début de la méthode =================================
2323
2324   def surf_objet_shaper (self, objet):
2325     """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2326
2327 Entrées :
2328   :objet: objet à traiter
2329
2330 Sorties :
2331   :erreur: code d'erreur
2332   :message: message d'erreur
2333 """
2334
2335     nom_fonction = __name__ + "/surf_objet_shaper"
2336     blabla = "Dans {} :".format(nom_fonction)
2337
2338     if self._verbose_max:
2339       print (blabla)
2340
2341     erreur = 0
2342     message = ""
2343
2344     while not erreur :
2345
2346       if self.affiche_aide_globale:
2347         break
2348
2349 # 1. Acquisition de la liste des noms des sous-objets solides
2350
2351       self.d_statut_so = dict()
2352       self.l_noms_so = list()
2353       self.l_faces_m = list()
2354
2355       _ = self._nom_sous_objets (objet, True)
2356       if self._verbose_max:
2357         print ("Noms des sous-objets : {}".format(self.l_noms_so))
2358
2359 # 2. Les faces médianes
2360
2361       erreur, message = self._surf_objet_shaper_0 ( objet )
2362       if erreur:
2363         break
2364
2365 # 3. Gestion des faces créées
2366
2367       self._surf_objet_shaper_1 ( )
2368
2369 # 4. Futur message pour le résultat
2370
2371       if ( self._export_step and not erreur ):
2372         message = "Les fichiers des CAO des surfaces sont dans le répertoire {}".format(self.rep_step)
2373
2374       break
2375
2376     return erreur, message
2377
2378 #===========================  Fin de la méthode ==================================
2379
2380 #=========================== Début de la méthode =================================
2381
2382   def _surf_objet_shaper_0 (self, objet, n_recur=0):
2383     """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2384
2385 Entrées :
2386   :objet: objet à traiter
2387   :n_recur: niveau de récursivité
2388
2389 Sorties :
2390   :erreur: code d'erreur
2391   :message: message d'erreur
2392 """
2393
2394     nom_fonction = __name__ + "/_surf_objet_shaper_0"
2395     blabla = "Dans {} :".format(nom_fonction)
2396
2397     if self._verbose_max:
2398       print_tab (n_recur, blabla)
2399       print_tab (n_recur, "n_recur = ", n_recur)
2400
2401     erreur = 0
2402     message = ""
2403
2404     while not erreur :
2405
2406 # 1. Au premier passage, il faut récupérer la pièce SHAPER et garder la référence au résultat principal
2407
2408       if ( n_recur == 0 ):
2409         self.part_doc = model.activeDocument()
2410         objet_0 = objet.result()
2411         self.objet_principal = objet_0
2412         objet_bis = objet.defaultResult().shape()
2413         if self._verbose_max:
2414           print_tab (0, "Examen de l'objet initial ", objet.result().name(), saut_av=True)
2415           print_tab (0, "Type python : ", type(objet))
2416           print_tab (0, "Type {} / {} ; volume = ".format(objet_bis.shapeType(),objet_bis.shapeTypeStr()), GeomAlgoAPI_ShapeTools.volume(objet_bis))
2417       else:
2418         objet_0 = objet
2419         if self._verbose_max:
2420           print_tab (n_recur, "Examen de l'objet ", objet.name(), saut_av=True)
2421           print_tab (n_recur, "Type python : ", type(objet))
2422           print_tab (n_recur, "shapeType : ", objet.shapeType())
2423
2424 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
2425
2426       nb_sub_results = objet_0.numberOfSubs()
2427
2428       if self._verbose_max:
2429         print_tab (n_recur, "Examen de l'objet '{}' de type ".format(objet_0.name()), objet_0.shapeType(), saut_av=True)
2430         print_tab (n_recur, "objet.result().numberOfSubs() : ", nb_sub_results)
2431
2432       for n_sobj in range(nb_sub_results):
2433
2434 # 2.1. Exploration récursive de l'arborescence
2435
2436         erreur, message = self._surf_objet_shaper_0 ( objet_0.subResult(n_sobj), n_recur+1 )
2437         if erreur:
2438           break
2439
2440       if erreur:
2441         break
2442
2443 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
2444
2445       if ( objet_0.shapeType() == "SOLID" ):
2446         erreur, message = self.surf_solide_shaper ( objet_0, n_recur )
2447         if erreur:
2448           break
2449
2450 # 3. Futur message pour le résultat
2451
2452       if self._export_step:
2453         message = "Les fichiers STEP des surfaces sont dans le répertoire {}".format(self.rep_step)
2454
2455       break
2456
2457     return erreur, message
2458
2459 #===========================  Fin de la méthode ==================================
2460
2461 #=========================== Début de la méthode =================================
2462
2463   def _surf_objet_shaper_1 (self, n_recur=0):
2464     """Gestion des surfaces médianes créées
2465
2466 Entrées :
2467   :n_recur: niveau de récursivité
2468
2469 Sorties :
2470   :erreur: code d'erreur
2471   :message: message d'erreur
2472 """
2473
2474     nom_fonction = __name__ + "/_surf_objet_shaper_1"
2475     blabla = "Dans {} :\n".format(nom_fonction)
2476
2477     if self._verbose_max:
2478       print_tab (n_recur, blabla)
2479
2480 # 1. Informations sur les faces à problème
2481
2482     if self.faces_pb_nb:
2483       if ( self.faces_pb_nb == 1 ):
2484         texte = "1 face pose"
2485       else:
2486         texte = "{} faces posent".format(self.faces_pb_nb)
2487       print_tab (n_recur, "{} problème.".format(texte), self.faces_pb_msg, saut_av=True)
2488
2489 # 2. Si plus d'une face a été créée
2490     if ( len(self.l_faces_m) > 1 ):
2491
2492 # 2.1. Partition du paquet de faces
2493
2494       if self._verbose_max:
2495         print_tab (n_recur, "Partitionnnement des faces créées.")
2496
2497 # 2.1.1. Pour une raison mystérieuse, il faut commencer par les faces entières, puis mettre les sous-faces éventuelles
2498       d_faces = dict()
2499       for (face,_) in self.l_faces_m:
2500         if not face.result().numberOfSubs():
2501           d_faces[face.name()] = [face.name()]
2502       for (face,_) in self.l_faces_m:
2503         nb_sub_results = face.result().numberOfSubs()
2504         if nb_sub_results:
2505           laux = list()
2506           for n_sobj in range(nb_sub_results):
2507             laux.append(face.result().subResult(n_sobj).name())
2508           d_faces[face.name()] = laux
2509
2510       l_objets = list()
2511       for _, laux in d_faces.items():
2512         for s_face_n in laux:
2513           l_objets.append(model.selection("FACE", s_face_n))
2514
2515       Partition_1 = model.addPartition(self.part_doc, l_objets, keepSubResults = True)
2516       nom = "{}_M".format(self.objet_principal.name())
2517       exec_nom (Partition_1,nom)
2518
2519       iaux = 0
2520       for face_n, laux in d_faces.items():
2521         Partition_1.result().subResult(iaux).setName("{}".format(face_n))
2522         if ( len(laux) > 1 ):
2523           for jaux, s_face_n in enumerate(laux):
2524             Partition_1.result().subResult(iaux).subResult(jaux).setName("{}_M".format(s_face_n))
2525         iaux += 1
2526       couleur_objet (Partition_1, n_recur, coul_r=0, coul_g=170, coul_b=0, verbose=self._verbose_max)
2527
2528 # 2.2. Récupération des faces individuelles
2529
2530       if self._verbose_max:
2531         print_tab (n_recur, "Récupération des faces individuelles.")
2532
2533       l_objets = list()
2534       for iaux, (face,_) in enumerate(self.l_faces_m):
2535         l_objets.append(face.result())
2536
2537       Recover_1 = model.addRecover(self.part_doc, Partition_1, l_objets)
2538       exec_nom (Recover_1)
2539       for iaux, (face,_) in enumerate(self.l_faces_m):
2540         Recover_1.results()[iaux].setName("{}".format(face.name()))
2541         Recover_1.results()[iaux].setColor(0, 170, 0)
2542         nb_sub_results = Recover_1.results()[iaux].numberOfSubs()
2543         for n_sobj in range(nb_sub_results):
2544           Recover_1.results()[iaux].subResult(n_sobj).setName("{}_{}".format(face.name(),n_sobj))
2545           Recover_1.results()[iaux].subResult(n_sobj).setColor(0, 170, 0)
2546
2547 # 3. Mise en dossier
2548
2549     if self._verbose_max:
2550       print_tab (n_recur, "Mise en dossier.")
2551
2552     for (face,fonction_0) in self.l_faces_m:
2553       if fonction_0 is not None:
2554         nom = face.name()[:-2]
2555         if self._verbose_max:
2556           print ( "Dossier {} de {} à {}".format(nom,fonction_0.name(),face.name()))
2557         dossier = model.addFolder(self.part_doc, fonction_0, face)
2558         dossier.setName(nom)
2559
2560     if ( len(self.l_faces_m) > 1 ):
2561
2562       nom = self.objet_principal.name()
2563       if self._verbose_max:
2564         print ( "Dossier {} de {} à {}".format(nom,Partition_1.name(),Recover_1.name()))
2565       dossier = model.addFolder(self.part_doc, Partition_1, Recover_1)
2566       dossier.setName(nom)
2567
2568 #===========================  Fin de la méthode ==================================
2569
2570 #=========================== Début de la méthode =================================
2571
2572   def surf_solide_shaper (self, solide, n_recur):
2573     """Calcule les surfaces médianes pour un solide SHAPER solide passé en argument
2574
2575 Entrées :
2576   :solide: solide SHAPER à traiter
2577   :n_recur: numéro de la récurrence
2578
2579 Sorties :
2580   :erreur: code d'erreur
2581   :message: message d'erreur
2582 """
2583
2584     nom_fonction = __name__ + "/surf_solide_shaper"
2585     blabla = "Dans {} :".format(nom_fonction)
2586
2587     if self._verbose_max:
2588       print_tab (n_recur, blabla, saut_av=True)
2589
2590     erreur = 0
2591     message = ""
2592
2593     while not erreur :
2594
2595       self.nom_solide = solide.name()
2596       if self._verbose_max:
2597         print_tab (n_recur, "solide : ", self.nom_solide)
2598
2599 # 1. Isolement du solide
2600       solide_aux, recover = self._isole_solide ( solide, n_recur )
2601
2602 # 2. Traitement de l'objet correspondant
2603       erreur, message = self._traitement_objet ( solide_aux, n_recur=n_recur )
2604
2605       if ( erreur and self._verbose_max ):
2606         print (blabla, message)
2607
2608 # 3. Neutralisation des erreurs dues à l'épaisseur
2609       if ( erreur in (-2,-1,2) ):
2610         erreur = 0
2611         message = ""
2612       if erreur:
2613         break
2614
2615 # 4. Mise en forme de l'objet principal récupéré
2616       if ( recover is not None ):
2617         _ = self._nom_sous_objets (recover, False)
2618
2619       break
2620
2621     return erreur, message
2622
2623 #===========================  Fin de la méthode ==================================
2624
2625 #==========================  Fin de la classe ====================================