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