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