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