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