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