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