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