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