1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2016-2022 CEA/DEN, EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 """Obtention des surfaces médianes à partir d'un objet GEOM ou SHAPER
22 On sait traiter les faces :
29 Pour un objet complexe, on crée l'objet final comme étant la partition de toutes
30 les surfaces médianes.
32 Version initiale par :
33 alexandre.prunie@blastsolutions.io
34 guillaume.schweitzer@blastsolutions.io
39 __revision__ = "V11.05"
41 #========================= Les imports - Début ===================================
53 from SketchAPI import *
54 from salome.shaper import model
55 from salome.shaper import geom
57 from GeomAlgoAPI import *
61 #========================== Les imports - Fin ====================================
64 D_FMT["stp"] = ["stp", "step"]
65 D_FMT["igs"] = ["igs", "iges"]
66 for CLE in ("brep", "xao"):
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.
88 # Transparence des solides traités correctement
91 # Limite basse de l'épaisseur pour pouvoir faire les intersections
94 #========================= Début de la fonction ==================================
96 def decode_cao (fmt_cao):
97 """Décode le format de la cao
100 :fmt_cao: format du fichier, step, iges, etc.
102 :fmt_cao_0: format décodé
107 fmt_cao_low = fmt_cao.lower()
109 for cle, l_aux in D_FMT.items():
110 if ( fmt_cao_low in l_aux ):
116 #========================= Fin de la fonction ===================================
118 #========================= Début de la fonction ==================================
120 def import_cao (part_doc, ficcao, nom_objet=None, verbose=False):
121 """Importation d'une cao
125 :ficcao: le fichier de la CAO
126 :nom_objet: nom à donner à l'objet lu, éventuellement
128 :objet: l'objet importé dans SHAPER
131 nom_fonction = __name__ + "/import_cao"
132 blabla = "Dans {} :\n".format(nom_fonction)
133 message_0 = "Fichier : {}\n".format(ficcao)
135 message = blabla + message_0
136 message += "nom_objet : {}".format(nom_objet)
144 laux = ficcao.split(".")
145 fmt_cao_0 = decode_cao (laux[-1])
147 if ( fmt_cao_0 not in ("stp", "brep", "igs", "xao") ):
148 message += "Le format de CAO est inconnu"
152 message += "Le fichier de CAO n'a pas été décodé correctement."
155 elif not os.path.isfile(ficcao):
156 message += "Le fichier de CAO est inconnu."
162 objet = model.addImport(part_doc, ficcao)
163 exec_nom (objet, nom_objet)
167 texte = "Objet : '{}'\n".format(objet.result().name())
168 texte += "De type : '{}'".format(objet.result().shapeType())
171 return erreur, message, objet
173 #========================= Fin de la fonction ===================================
175 #========================= Début de la fonction ==================================
177 def print_tab (nb_tab, message, argu=None, saut_av=False, saut_ap=False):
178 """Imprime avec des tabulations
181 :nb_tab: nombre de tabulations à appliquer
182 :message: message principal
183 :argu: argument du format
184 :saut_av: saut de ligne avant le texte
185 :saut_ap: saut de ligne après le texte
193 for _ in range(nb_tab):
197 if ( argu is not None ):
198 texte += "{}".format(argu)
205 #========================= Fin de la fonction ===================================
207 #========================= Début de la fonction ==================================
209 def nommage (objet, nom, couleur=None):
210 """Nomme un objet et son résultat
213 :objet: objet à traiter
214 :nom: nom à attribuer
215 :couleur: éventuellement couleur
219 objet.result().setName(nom)
221 if ( couleur is not None ):
222 objet.result().setColor(couleur[0], couleur[1], couleur[2])
224 #========================= Fin de la fonction ===================================
226 #========================= Début de la fonction ==================================
228 def exec_nom (fonction, nom=None):
229 """Execute la fonction après l'avoir nommée et nommé son résultat
232 :fonction: fonction à traiter
233 :nom: nom à attribuer éventuellement
236 if ( nom is not None ):
237 nommage (fonction, nom)
239 fonction.execute(True)
241 #========================= Fin de la fonction ===================================
244 #=================================== La classe ===================================
246 class SurfaceMediane (object):
248 """Calcul des surfaces médianes de solides minces
250 L'objectif de ce programme est de créer les surfaces médianes, encore appelées fibres neutres, pour \
251 une structure qui est un solide ou un assemblage de solides (compound).
252 Pour réaliser l'opération, trois façons de faire :
254 1. On lance le script en précisant le fichier à analyser dans la zone d'auto-test.
256 2. Si on part d'un script qui manipule un fichier au format CAO, on crée une instance de la classe SurfaceMediane \
257 puis on appelle la méthode surf_fic_cao avec ce fichier en argument.
259 3. Si on part d'un script qui crée un objet SHAPER, on crée une instance de la classe SurfaceMediane \
260 puis on appelle la méthode surf_objet_shaper avec cet objet en argument.
263 Le programme crée les surfaces sous réserve que pour le solide envisagé, il a réussi à trouver deux faces \
264 de taille identique et supérieure aux tailles des autres faces du solide. \
265 Cela fonctionne pour des surfaces planes ou de forme canonique.
266 Il crée alors une surface au milieu de ces deux grandes faces. \
267 Cette face est coloriée en vert, le solide est en vert et transparent.
269 On sait traiter les faces :
276 Si la création n'a pas eu lieu, un message est émis et les solides sont mis en couleur :
277 . Rouge : le solide n'est pas assez mince.
278 . Bleu : le solide est trop mince, vis-à-vis de la précision de SHAPER.
279 . Orange : la forme de la face n'est pas reconnue.
287 . Exportation finale dans un fichier step. Par défaut, pas d'export.
288 -export_step/-no_export_step
291 surf_fic_cao --> import_cao
292 --> surf_objet_shaper (récursif) --> _nom_sous_objets
293 --> _surf_objet_shaper_0
294 --> surf_solide_shaper --> _isole_solide
295 --> _traitement_objet --> face_mediane_solide --> _faces_du_solide
297 --> _cree_face_mediane
299 _cree_face_mediane --> _cree_face_mediane_plane
300 --> _cree_face_mediane_cylindre
301 --> _cree_face_mediane_sphere
302 --> _cree_face_mediane_tore
303 --> _cree_face_mediane_cone
304 --> _cree_face_mediane_0
313 affiche_aide_globale = 0
320 nom_solide_aux = None
326 objet_principal = None
327 # Pour chaque sous-objet dans l'ordre de l'arborescence : nom
329 # Statut de chaque sous-objet connu par son nom :
330 # 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
332 # Liste des faces médianes créées et des fonctions initiales
334 # La fonction initiale
340 #=========================== Début de la méthode =================================
342 def __init__ ( self, liste_option ):
344 """Le constructeur de la classe SurfaceMediane
346 Décodage des arguments
347 On cherche ici les arguments généraux : aide, verbeux
350 for option in liste_option :
353 if isinstance(option,str):
354 saux = option.upper()
356 if saux in ( "-H", "-HELP" ):
357 self.affiche_aide_globale = 1
360 elif saux == "-VMAX" :
362 self._verbose_max = 1
363 elif saux == "-EXPORT_STEP":
364 self._export_step = True
365 elif saux == "-NO_EXPORT_STEP":
366 self._export_step = False
368 #=========================== Fin de la méthode ==================================
370 #=========================== Début de la méthode =================================
373 """A la suppression de l'instance de classe"""
374 if self._verbose_max:
375 print ("Suppression de l'instance de la classe.")
377 #=========================== Fin de la méthode ==================================
379 #=========================== Début de la méthode =================================
381 def _nom_sous_objets (self, objet, lecture, n_recur=0, rang=0):
382 """Gère les noms des sous_objets solides
385 :objet: objet à traiter
386 :lecture: vrai pour lire les noms, faux pour les attribuer
387 :n_recur: niveau de récursivité
388 :rang: rang du sous-objet
391 :rang: rang du sous-objet
394 nom_fonction = __name__ + "/_nom_sous_objets"
395 blabla = "Dans {} :\n".format(nom_fonction)
397 if self._verbose_max:
399 for _ in range(n_recur):
401 texte = "\n{}{}".format(prefixe,blabla)
402 texte += "{}n_recur = {}".format(prefixe,n_recur)
403 texte += "\n{}lecture = {}".format(prefixe,lecture)
406 # 1. Au premier passage, il faut garder la référence au résultat principal
409 objet_0 = objet.result()
410 if self._verbose_max:
411 print ("d_statut_so = {}".format(self.d_statut_so))
415 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
417 nb_sub_results = objet_0.numberOfSubs()
419 if self._verbose_max:
420 texte = "{}Examen de l'objet '{}' ".format(prefixe,objet_0.name())
421 texte += "de type '{}'".format(objet_0.shapeType())
422 texte += "\n{}objet.result().numberOfSubs() : {}".format(prefixe,nb_sub_results)
425 for n_sobj in range(nb_sub_results):
427 # 2.1. Exploration récursive de l'arborescence
429 rang = self._nom_sous_objets ( objet_0.subResult(n_sobj), lecture, n_recur+1, rang )
431 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
433 if ( objet_0.shapeType() == "SOLID" ):
434 # A la lecture, on enregistre le nom
437 self.l_noms_so.append(nom)
438 self.d_statut_so[nom] = 0
439 # A la récupération, on redonne le nom et on affecte une couleur dépendant de l'état
441 nom = self.l_noms_so[rang]
443 etat = self.d_statut_so[nom]
444 objet_0.setColor (D_COLOR_R[etat],D_COLOR_G[etat],D_COLOR_B[etat])
446 objet_0.setTransparency (TRANSPARENCE)
451 #=========================== Fin de la méthode ==================================
453 #=========================== Début de la méthode =================================
455 def _couleur_objet (self, objet, n_recur=0, coul_r=1, coul_g=0, coul_b=0):
456 """Appliquer une couleur à un objet et à ses sous_objets
459 :objet: objet à traiter
460 :n_recur: niveau de récursivité
461 :coul_r,coul_g,coul_b: code RGB de la couleur à appliquer
464 :rang: rang du sous-objet
467 nom_fonction = __name__ + "/_couleur_objet"
468 blabla = "Dans {} :".format(nom_fonction)
470 if self._verbose_max:
472 print_tab(n_recur, "objet : ", objet.name())
473 print_tab(n_recur, "RGB = ({},{},{})".format(coul_r,coul_g,coul_b))
475 # 1. Au premier passage, il faut garder la référence au résultat principal
478 objet_0 = objet.result()
482 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
484 nb_sub_results = objet_0.numberOfSubs()
486 if self._verbose_max:
487 print_tab(n_recur, "Examen de l'objet ",objet_0.name())
488 texte = "de type '{}' ".format(objet_0.shapeType())
489 texte += "et de {} sous-objets".format(nb_sub_results)
490 print_tab(n_recur, texte)
492 for n_sobj in range(nb_sub_results):
494 # 2.1. Exploration récursive de l'arborescence
496 self._couleur_objet ( objet_0.subResult(n_sobj), n_recur+1, coul_r, coul_g, coul_b )
498 # 2.2. Cet objet n'a pas de sous-objets : on le colore
499 if self._verbose_max:
500 print_tab(n_recur, "Couleur affectée à l'objet ",objet_0.name())
501 objet_0.setColor (int(coul_r),int(coul_g),int(coul_b))
503 #print ("sortie de {}".format(nom_fonction))
505 #=========================== Fin de la méthode ==================================
507 #=========================== Début de la méthode =================================
509 def _isole_solide ( self, solide, n_recur ):
510 """Isole le solide de son arboresence
513 :solide: le solide à traiter
514 :n_recur: numéro de la récurrence
517 :objet: le solide isolé
518 :recover: la fonction de récupération
521 nom_fonction = __name__ + "/_isole_solide"
522 blabla = "Dans {} :".format(nom_fonction)
523 if self._verbose_max:
524 print_tab (n_recur, blabla)
525 texte = "Pour le solide '{}' ".format(solide.name())
526 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
527 print_tab (n_recur, texte)
529 if ( solide.name() != self.objet_principal.name() ):
530 objet, recover = self._isole_solide_a ( solide, n_recur )
533 objet, recover = self._isole_solide_b ( solide, n_recur )
535 if self._verbose_max:
536 print_tab (n_recur, "objet final : ", objet.name())
537 print_tab (n_recur, "fonction_0 : {}".format(self.fonction_0))
538 print_tab (n_recur, "recover : {}".format(recover))
540 return objet, recover
542 #=========================== Fin de la méthode ==================================
544 #=========================== Début de la méthode =================================
546 def _isole_solide_a ( self, solide, n_recur ):
547 """Isole le solide de son arboresence
550 :solide: le solide à traiter
551 :n_recur: numéro de la récurrence
554 :objet: le solide isolé
555 :recover: la fonction de récupération
558 nom_fonction = __name__ + "/_isole_solide_a"
559 blabla = "Dans {} :".format(nom_fonction)
560 if self._verbose_max:
561 print_tab (n_recur, blabla)
562 texte = "Pour le solide '{}' ".format(solide.name())
563 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
564 print_tab (n_recur, texte)
566 if self._verbose_max:
567 print_tab (n_recur, ". Extraction du solide '{}'".format(self.objet_principal.name()))
569 # 1. Extraction du solide
570 remove_subshapes = model.addRemoveSubShapes(self.part_doc, model.selection("COMPOUND", self.objet_principal.name()))
571 exec_nom (remove_subshapes)
572 remove_subshapes.setSubShapesToKeep([model.selection("SOLID", solide.name())])
574 self.nom_solide_aux = "{}_S".format(solide.name())
575 if self._verbose_max:
576 print_tab (n_recur, "\tAttribution à remove_subshapes.result() du nom '{}'".format(self.nom_solide_aux))
577 remove_subshapes.result().setName(self.nom_solide_aux)
579 self.fonction_0 = remove_subshapes
581 # 2. Récupération de l'objet principal
582 recover = model.addRecover(self.part_doc, remove_subshapes, [self.objet_principal])
583 if self._verbose_max:
584 print_tab (n_recur, "\tAttribution à recover du nom '{}'".format(self.objet_principal.name()))
585 exec_nom (recover,self.objet_principal.name())
587 return remove_subshapes.result(), recover
589 #=========================== Fin de la méthode ==================================
591 #=========================== Début de la méthode =================================
593 def _isole_solide_b ( self, solide, n_recur ):
594 """Isole le solide de son arboresence
597 :solide: le solide à traiter
598 :n_recur: numéro de la récurrence
601 :objet: le solide isolé
602 :recover: la fonction de récupération
605 nom_fonction = __name__ + "/_isole_solide_b"
606 blabla = "Dans {} :".format(nom_fonction)
607 if self._verbose_max:
608 print_tab (n_recur, blabla)
609 texte = "Pour le solide '{}' ".format(solide.name())
610 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
611 print_tab (n_recur, texte)
613 if self._verbose_max:
614 print_tab (n_recur, ". Mise en place du solide")
616 self.nom_solide_aux = self.objet_principal.name()
617 self.fonction_0 = None
621 #=========================== Fin de la méthode ==================================
623 #=========================== Début de la méthode =================================
625 def _faces_du_solide ( self, solide, n_recur=0 ):
626 """Détermine les faces d'un solide
629 :solide: solide SHAPER à traiter
630 :n_recur: niveau de récursivité
633 :l_faces_car: pour chaque face du solide (surface,caractéristiques)
636 nom_fonction = __name__ + "/_faces_du_solide"
637 blabla = "Dans {} :".format(nom_fonction)
638 if self._verbose_max:
639 print_tab (n_recur, blabla, saut_av=True)
643 if self._verbose_max:
644 print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
645 print_tab (n_recur, ".. shapeType : ", solide.shapeType())
648 #print_tab (n_recur, "volume = ", GeomAlgoAPI_ShapeTools.volume(solide.shape()))
649 # 1. Repérage des faces
650 objResult = solide.resultSubShapePair()[0]
652 exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
654 l_faces.append(exp.current().face())
659 for iface, face in enumerate(l_faces):
660 surf = GeomAlgoAPI_ShapeTools.area(face)
661 caract = geom.shapeInfo(face)
662 if self._verbose_max:
663 print_tab (n_recur, "\tFace n°{} ; ".format(iface), "surface = {}, caractéristiques = {}".format(surf,caract))
664 l_faces_car.append((surf,caract))
668 #=========================== Fin de la méthode ==================================
670 #=========================== Début de la méthode =================================
672 def _calcul_caract_faces ( self, solide, n_recur ):
673 """Calcule les caractéristiques géométriques des faces du solide
676 :solide: solide SHAPER à traiter
677 :n_recur: niveau de récursivité
680 :tb_caract: tableau des caractéristiques géométriques des faces
683 nom_fonction = __name__ + "/_calcul_caract_faces"
684 blabla = "Dans {} :".format(nom_fonction)
685 if self._verbose_max:
686 print_tab (n_recur, blabla, saut_av=True)
687 print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
688 print_tab (n_recur, ".. shapeType : ", solide.shapeType())
690 # 1. Repérage des faces
691 objResult = solide.resultSubShapePair()[0]
693 exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
695 l_faces.append(exp.current().face())
698 # 2. Caractéristiques
699 nb_faces = len(l_faces)
700 tb_caract = np.zeros((nb_faces,3), dtype = 'object')
701 for iaux, face in enumerate(l_faces):
702 surf = GeomAlgoAPI_ShapeTools.area(face)
703 caract = geom.shapeInfo(face)
704 if self._verbose_max:
705 print_tab (n_recur, "\tFace n°{} ; ".format(iaux), "surface = {}, caractéristiques = {}".format(surf,caract))
707 tb_caract [iaux][0] = face
708 tb_caract [iaux][1] = surf
709 tb_caract [iaux][2] = caract
711 #if self._verbose_max:
712 #for iaux in range(nb_faces):
713 #print ("\t. tb_caract : {} {}".format(surf,tb_caract[iaux][2]))
717 #=========================== Fin de la méthode ==================================
719 #=========================== Début de la méthode =================================
721 def _tri_faces ( self, tb_caract, n_recur ):
722 """Trie les faces en fonction de leurs surfaces
725 :tb_caract: tableau des caractéristiques géométriques des faces
726 :n_recur: niveau de récursivité
729 :tb_caract_1[-1], tb_caract_1[-2]: les caractéristiques des 2 faces les plus grandes
735 nom_fonction = __name__ + "/_tri_faces"
736 blabla = "Dans {} :".format(nom_fonction)
738 # Tri du tableau en fonction des surfaces
739 if self._verbose_max:
740 print_tab (n_recur, blabla)
741 print_tab (n_recur, "tb_caract brut : ", tb_caract)
742 tb_caract_1 = sorted(tb_caract, key=lambda colonnes: colonnes[1])
743 if self._verbose_max:
744 print_tab (n_recur, "tb_caract trié :", tb_caract_1)
746 if self._verbose_max:
747 texte = "\tSurface de la plus grande face : {}, de caractéristiques {}\n".format(tb_caract_1[-1][1],tb_caract_1[-1][2])
748 texte += "\tSurface de la face suivante : {}, de caractéristiques {}".format(tb_caract_1[-2][1],tb_caract_1[-2][2])
749 if self._verbose_max:
750 texte += "\n\tSurface de la 3ème face suivante : {}, de caractéristiques {}".format(tb_caract_1[-3][1],tb_caract_1[-3][2])
753 # La surface suivante doit être différente, sinon ce n'est pas un solide mince
754 ecart = np.abs((tb_caract_1[-1][1]-tb_caract_1[-3][1])/tb_caract_1[-1][1])
755 if ( ecart < self._epsilon ):
756 message = "\nSolide '{}'\n".format(self.nom_solide)
757 message += ". Surface de la plus grande face : {}\n".format(tb_caract_1[-1][1])
758 message += ". Surface de la 1ère face suivante : {}\n".format(tb_caract_1[-2][1])
759 message += ". Surface de la 2ème face suivante : {}\n".format(tb_caract_1[-3][1])
760 if self._verbose_max:
761 message += ". Ecart relatif :{:4.1f}%\n".format(ecart*100.)
762 message += "L'écart est trop faible par rapport à la limite de {}%.\n".format(self._epsilon*100.)
763 message += "==> Impossible de créer la face médiane car le solide n'est pas assez mince.\n"
765 self.d_statut_so[self.nom_solide] = -1
766 self.faces_pb_nb += 1
767 self.faces_pb_msg += message
769 return erreur, message, tb_caract_1[-1], tb_caract_1[-2]
771 #=========================== Fin de la méthode ==================================
773 #=========================== Début de la méthode =================================
775 def _verif_epaisseur ( self, epaisseur ):
776 """Contrôle de la validité de l'épaisseur
779 :epaisseur: épaisseur du solide
782 nom_fonction = __name__ + "/_verif_epaisseur"
783 blabla = "Dans {} :\n".format(nom_fonction)
785 if self._verbose_max:
787 texte += ". Epaisseur du solide : {}\n".format(epaisseur)
788 texte += ". EP_MIN : {}".format(EP_MIN)
791 if ( epaisseur <= EP_MIN ):
792 message = "\nSolide '{}'\n".format(self.nom_solide)
793 message += ". Epaisseur : {}\n".format(epaisseur)
794 message += "L'épaisseur est trop faible par rapport à la limite de {}.\n".format(EP_MIN)
795 message += "==> Impossible de créer la face médiane car le solide est trop mince.\n"
797 self.d_statut_so[self.nom_solide] = 2
798 self.faces_pb_nb += 1
799 self.faces_pb_msg += message
803 #print ("erreur = {}".format(erreur))
807 #=========================== Fin de la méthode ==================================
809 #=========================== Début de la méthode =================================
811 def _cree_face_mediane ( self, solide, caract_face_1, caract_face_2, n_recur ):
812 """Crée la face médiane entre deux autres
815 :solide: solide SHAPER à traiter
816 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
817 :n_recur: niveau de récursivité
820 :face: la face médiane créée
823 nom_fonction = __name__ + "/_cree_face_mediane"
824 blabla = "Dans {} :".format(nom_fonction)
826 if self._verbose_max:
827 print_tab (n_recur, blabla)
828 print_tab (n_recur, "face_1 : " ,caract_face_1)
829 print_tab (n_recur, "face_2 : " ,caract_face_2)
834 # 1. Forme de la face
835 forme = caract_face_1[2][0]
837 # 2. Traitement selon la forme de la face
839 if forme in ( "Disk" , "Plane", "Rectangle"):
840 erreur, face = self._cree_face_mediane_plane ( solide, caract_face_1, caract_face_2, n_recur )
842 # 2.2. Face cylindrique
843 elif ( forme == "Cylinder" ):
844 erreur, face = self._cree_face_mediane_cylindre ( solide, caract_face_1, caract_face_2, n_recur )
846 # 2.3. Face sphérique
847 elif ( forme == "Sphere" ):
848 erreur, face = self._cree_face_mediane_sphere ( caract_face_1, caract_face_2, n_recur )
851 elif ( forme == "Torus" ):
852 erreur, face = self._cree_face_mediane_tore ( caract_face_1, caract_face_2, n_recur )
855 elif ( forme == "Cone" ):
856 erreur, face = self._cree_face_mediane_cone ( caract_face_1, caract_face_2, n_recur )
858 # 2.N. Face de forme inconnue
860 message = "\nSolide '{}'\n".format(self.nom_solide)
861 message += "sa face la plus grande est de forme : {}\n".format(forme)
862 message += "==> Impossible de créer la face médiane.\n"
864 self.d_statut_so[self.nom_solide] = -2
865 self.faces_pb_nb += 1
866 self.faces_pb_msg += message
868 # 3. Gestion de la face produite
871 self._cree_face_mediane_0 ( face, n_recur )
875 #=========================== Fin de la méthode ==================================
877 #=========================== Début de la méthode =================================
879 def _cree_face_mediane_0 ( self, face, n_recur ):
880 """Gestion de la face médiane créée entre deux autres
883 :face: la face médiane créée
884 :n_recur: niveau de récursivité
887 nom_fonction = __name__ + "/_cree_face_mediane_0"
888 blabla = "Dans {} :".format(nom_fonction)
890 if self._verbose_max:
891 print_tab (n_recur, blabla)
894 nom_face = self.nom_solide+"_M"
895 if self._verbose_max:
896 print_tab (n_recur,"Nom de la face créée : ", nom_face)
897 #if ( self.nom_solide_aux != self.objet_principal.name() ):
899 nommage (face, nom_face)
901 # 2. Mémorisation de la face et de la fonction initiale
902 self.l_faces_m.append((face, self.fonction_0))
904 # 3. Couleur verte pour la face
905 self._couleur_objet (face, coul_r=0, coul_g=170, coul_b=0)
907 # 4. Changement de statut pour le solide
908 self.d_statut_so[self.nom_solide] = 1
910 #=========================== Fin de la méthode ==================================
912 #=========================== Début de la méthode =================================
914 def _cree_face_mediane_plane ( self, solide, caract_face_1, caract_face_2, n_recur ):
915 """Crée la face médiane entre deux autres - cas des surfaces planes
918 :solide: l'objet solide à traiter
919 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
920 :n_recur: niveau de récursivité
923 :face: la face médiane
926 nom_fonction = __name__ + "/_cree_face_mediane_plane"
927 blabla = "Dans {} :".format(nom_fonction)
928 if self._verbose_max:
929 print_tab (n_recur, blabla)
931 # Caractéristiques des surfaces
932 coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2 = self._cree_face_mediane_plane_0 ( solide, caract_face_1, caract_face_2, n_recur )
934 # Contrôle de la validité de l'épaisseur
935 erreur = self._verif_epaisseur ( d_face_1_2 )
937 # Création de la face
939 face = self._cree_face_mediane_plane_1 ( solide, (coo_x, coo_y, coo_z),(vnor_x, vnor_y, vnor_z), taille, d_face_1_2, n_recur )
945 #=========================== Fin de la méthode ==================================
947 #=========================== Début de la méthode =================================
949 def _cree_face_mediane_plane_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
950 """Crée la face médiane entre deux autres - cas des surfaces planes
952 Décodage des caractéristiques
955 :solide: l'objet solide à traiter
956 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
957 :n_recur: niveau de récursivité
960 :coo_x, coo_y, coo_z: coordonnées du centre de la base
961 :vnor_x, vnor_y, vnor_z: coordonnées du vecteur normal
962 :taille: estimation de la taille de la future face
963 :d_face_1_2: la distance entre les deux faces
966 nom_fonction = __name__ + "/_cree_face_mediane_plane_0"
967 blabla = "Dans {} :".format(nom_fonction)
969 if self._verbose_max:
970 print_tab (n_recur, blabla)
971 print_tab (n_recur, "caract_face_1 : ", caract_face_1)
972 print_tab (n_recur, "caract_face_2 : ", caract_face_2)
974 # 1. Caractéristiques de la base
975 # Coordonnées du centre de la base
976 coo_x = caract_face_1[2][1]
977 coo_y = caract_face_1[2][2]
978 coo_z = caract_face_1[2][3]
979 # Coordonnées du vecteur normal
980 vnor_x = caract_face_1[2][4]
981 vnor_y = caract_face_1[2][5]
982 vnor_z = caract_face_1[2][6]
983 # taille : une longueur caractéristique pour être certain de tout prendre
984 l_diag = self._calcul_lg_caract ( solide, n_recur )
986 if self._verbose_max:
987 print_tab (n_recur, "Taille englobante : ",taille)
989 # 2. Distance entre les deux faces
990 face_1 = caract_face_1[0]
991 face_2 = caract_face_2[0]
992 d_face_1_2 = GeomAlgoAPI_ShapeTools.minimalDistance(face_1, face_2)
993 if self._verbose_max:
994 print_tab (n_recur, "Distance entre les deux faces = ", d_face_1_2)
996 return coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2
998 #=========================== Fin de la méthode ==================================
1000 #=========================== Début de la méthode =================================
1002 def _cree_face_mediane_plane_1 ( self, solide, coo_c, vnor, taille, d_face_1_2, n_recur ):
1003 """Crée la face médiane entre deux autres - cas des surfaces planes
1005 Création des objets de construction et de la face médiane
1008 :solide: l'objet solide à traiter
1009 :coo_c: coordonnées du centre de la base
1010 :vnor: coordonnées du vecteur normal
1011 :taille: estimation de la taille de la future face
1012 :d_face_1_2: la distance entre les deux faces
1013 :n_recur: niveau de récursivité
1016 :face: la face médiane
1019 nom_fonction = __name__ + "/_cree_face_mediane_plane_1"
1020 blabla = "Dans {} :".format(nom_fonction)
1021 if self._verbose_max:
1022 print_tab (n_recur, blabla)
1023 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1024 print_tab (n_recur, "Normale : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
1025 print_tab (n_recur, "Taille : ", taille)
1026 print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1028 # 1. Objets préalables
1029 nom_par_1 = "{}_taille".format(self.nom_solide)
1030 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(taille))
1032 centre, v_norm, plan = self._cree_centre_axe_plan ( coo_c, vnor, self.nom_solide, n_recur )
1034 # 2. Création de l'esquisse
1035 sketch = self._cree_face_mediane_plane_1_a ( plan, centre, nom_par_1, taille, n_recur )
1038 face = self._cree_face_mediane_plane_1_b ( solide, sketch, v_norm, d_face_1_2, n_recur )
1040 #print ("fin de {}".format(nom_fonction))
1044 #=========================== Fin de la méthode ==================================
1046 #=========================== Début de la méthode =================================
1048 def _cree_face_mediane_plane_1_a ( self, plan, centre, nom_par_1, taille, n_recur ):
1049 """Crée la face médiane entre deux autres - cas des surfaces planes - l'esquisse
1054 :nom_par_1: nom du paramètre
1055 :taille: estimation de la taille de la future face
1056 :n_recur: niveau de récursivité
1062 nom_fonction = __name__ + "/_cree_face_mediane_plane_1_a"
1063 blabla = "Dans {} :".format(nom_fonction)
1064 if self._verbose_max:
1065 print_tab (n_recur, blabla)
1066 print_tab (n_recur, "Plan : {}".format(plan.name()))
1067 print_tab (n_recur, "Centre : {}".format(centre.name()))
1068 print_tab (n_recur, "Paramètre : {}".format(nom_par_1))
1069 print_tab (n_recur, "taille : {}".format(taille))
1071 sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
1073 ### Create SketchLine
1074 SketchLine_1 = sketch.addLine(-taille/2., taille/2., taille/2., taille/2.)
1075 #sketch.setHorizontal(SketchLine_1.result())
1077 ### Create SketchLine
1078 SketchLine_2 = sketch.addLine(taille/2., taille/2., taille/2., -taille/2.)
1079 #sketch.setVertical(SketchLine_2.result())
1080 #sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
1082 ### Create SketchLine
1083 SketchLine_3 = sketch.addLine(taille/2., -taille/2., -taille/2., -taille/2.)
1084 #sketch.setHorizontal(SketchLine_3.result())
1085 #sketch.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
1086 #sketch.setLength(SketchLine_3.result(), nom_par_1)
1088 ### Create SketchLine
1089 SketchLine_4 = sketch.addLine(-taille/2., -taille/2., -taille/2., taille/2.)
1090 #sketch.setVertical(SketchLine_4.result())
1091 #sketch.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
1092 #sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
1093 #sketch.setEqual(SketchLine_3.result(), SketchLine_4.result())
1097 nom_sketch = "{}_esquisse".format(self.nom_solide)
1098 exec_nom (sketch,nom_sketch)
1100 #print ("fin de {}".format(nom_fonction))
1104 #=========================== Fin de la méthode ==================================
1106 #=========================== Début de la méthode =================================
1108 def _cree_face_mediane_plane_1_b ( self, solide, sketch, v_norm, d_face_1_2, n_recur ):
1109 """Crée la face médiane entre deux autres - cas des surfaces planes
1111 Création de la face médiane
1114 :solide: l'objet solide à traiter
1116 :v_norm: vecteur normal
1117 :d_face_1_2: la distance entre les deux faces
1118 :n_recur: niveau de récursivité
1121 :face: la face médiane
1124 nom_fonction = __name__ + "/_cree_face_mediane_plane_1_b"
1125 blabla = "Dans {} :".format(nom_fonction)
1126 if self._verbose_max:
1127 print_tab (n_recur, blabla)
1128 print_tab (n_recur, "Esquisse : ", sketch.name())
1129 print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1131 ### Create LinearCopy
1132 LinearCopy_1 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", self.nom_solide_aux)], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
1133 nom = "{}_0".format(self.nom_solide_aux)
1134 exec_nom (LinearCopy_1,nom)
1137 Recover_1 = model.addRecover(self.part_doc, LinearCopy_1, [solide])
1138 nom = "{}_1".format(self.nom_solide_aux)
1139 exec_nom (Recover_1,nom)
1141 # Création d'une face ; on la translate d'une demi-épaisseur.
1142 for iaux in range(2):
1144 distance = -0.5*d_face_1_2*float(2*iaux-1)
1145 nom_solide = "{}_{}".format(self.nom_solide_aux,iaux)
1146 face = self._cree_face_mediane_plane_2 ( sketch.name(), v_norm.name(), nom_solide, distance, iaux, n_recur )
1149 face = self._cree_face_mediane_plane_11 ( face, Recover_1, n_recur )
1151 # Si l'intersection est vide, on la translate dans l'autre sens
1153 if self._verbose_max:
1154 print_tab (n_recur, "L'intersection est vide.")
1157 #print ("fin de {}".format(nom_fonction))
1161 #=========================== Fin de la méthode ==================================
1163 #=========================== Début de la méthode =================================
1165 def _cree_face_mediane_plane_11 ( self, face, Recover_1, n_recur ):
1166 """Crée la face médiane entre deux autres - cas des surfaces planes
1168 Création des objets de construction et de la face médiane
1171 :face: la face médiane
1172 :Recover_1: la récupératiuon du solide
1173 :n_recur: niveau de récursivité
1176 :face: la face médiane
1179 nom_fonction = __name__ + "/_cree_face_mediane_plane_11"
1180 blabla = "Dans {} :".format(nom_fonction)
1181 if self._verbose_max:
1182 print_tab (n_recur, blabla)
1183 print_tab (n_recur, "face : ", face.name())
1185 # Si on traite un objet solide unique, on le récupère
1186 if ( self.nom_solide_aux == self.objet_principal.name() ):
1187 if self._verbose_max:
1188 print_tab (n_recur, "On traite un objet solide unique ==> on le récupère.")
1189 Recover_2 = model.addRecover(self.part_doc, face, [Recover_1.result()])
1190 nom = "{}_S".format(self.nom_solide_aux)
1191 exec_nom (Recover_2,nom)
1193 nb_inter = face.result().numberOfSubs()
1194 if self._verbose_max:
1195 print_tab (n_recur, "Nombre d'intersections : ", nb_inter)
1198 face = self._cree_face_mediane_plane_3 ( face )
1202 #=========================== Fin de la méthode ==================================
1204 #=========================== Début de la méthode =================================
1206 def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, distance, icpt, n_recur ):
1207 """Crée la face médiane entre deux autres - cas des surfaces planes
1209 Intersection de la face avec le solide
1212 :nom_sketch: nom de l'esquisse
1213 :nom_normal: nom du vecteur normal
1214 :nom_solide: nom du solide à intersecter
1215 :distance: la distance de translation
1216 :icpt: numéro de la tentative
1219 :face: la face médiane
1222 nom_fonction = __name__ + "/_cree_face_mediane_plane_2"
1223 blabla = "Dans {} :\n".format(nom_fonction)
1224 if self._verbose_max:
1225 print_tab (n_recur, blabla)
1226 print_tab (n_recur, "nom_sketch : ", nom_sketch)
1227 print_tab (n_recur, "nom_normal : ", nom_normal)
1228 print_tab (n_recur, "nom_solide : ", nom_solide)
1229 print_tab (n_recur, "distance : ", distance)
1231 # Création d'une face
1232 Face_1 = model.addFace(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(nom_sketch))])
1233 nom_face_1 = "{}_face_1_{}".format(self.nom_solide_aux,icpt)
1234 exec_nom (Face_1,nom_face_1)
1237 Translation_1 = model.addTranslation(self.part_doc, [model.selection("FACE", nom_face_1)], axis = model.selection("EDGE", nom_normal), distance = distance, keepSubResults = True)
1238 nom_trans = "{}_trans_{}".format(self.nom_solide_aux,icpt)
1239 exec_nom (Translation_1,nom_trans)
1240 Translation_1.result().setColor(85, 0, 255)
1242 # Intersection de cette face avec le solide initial
1243 face = model.addCommon(self.part_doc, [model.selection("SOLID", nom_solide), model.selection("FACE", nom_trans)], keepSubResults = True)
1248 #=========================== Fin de la méthode ==================================
1250 #=========================== Début de la méthode =================================
1252 def _cree_face_mediane_plane_3 ( self, face ):
1253 """Crée la face médiane entre deux autres - cas des surfaces planes
1255 Fusion des 2 intersections
1258 :face: la face médiane composée de plusieurs intersections
1261 :face_m: la face médiane
1264 nom_fonction = __name__ + "/_cree_face_mediane_plane_3"
1265 blabla = "Dans {} :\n".format(nom_fonction)
1266 if self._verbose_max:
1270 # Nommage des sous-objets
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)))
1278 if self._verbose_max:
1279 print ("Fusion de {} faces.".format(len(l_fuse)))
1280 face_m = model.addFuse(self.part_doc, l_fuse, keepSubResults = True)
1281 face_m.execute(True)
1285 #=========================== Fin de la méthode ==================================
1287 #=========================== Début de la méthode =================================
1289 def _cree_face_mediane_cylindre ( self, solide, caract_face_1, caract_face_2, n_recur ):
1290 """Crée la face médiane entre deux autres - cas des cylindres
1293 :solide: solide SHAPER à traiter
1294 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1295 :n_recur: niveau de récursivité
1298 :face: la face médiane
1301 nom_fonction = __name__ + "/_cree_face_mediane_cylindre"
1302 blabla = "Dans {} :".format(nom_fonction)
1305 if self._verbose_max:
1306 print_tab (n_recur, blabla)
1307 print_tab (n_recur, "face_1 : ", caract_face_1)
1308 print_tab (n_recur, "face_2 : ", caract_face_2)
1310 # Caractéristiques des cylindres
1311 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur = self._cree_face_mediane_cylindre_0 ( solide, caract_face_1, caract_face_2, n_recur )
1313 # Contrôle de la validité de l'épaisseur
1314 erreur = self._verif_epaisseur ( epaisseur )
1316 # Création de la face
1318 face = self._cree_face_mediane_cylindre_1 ( (coo_x, coo_y, coo_z), (axe_x, axe_y, axe_z), rayon, hauteur, n_recur )
1320 self._couleur_objet (solide, n_recur, coul_r=0, coul_g=0, coul_b=255)
1325 #=========================== Fin de la méthode ==================================
1327 #=========================== Début de la méthode =================================
1329 def _cree_face_mediane_cylindre_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
1330 """Crée la face médiane entre deux autres - cas des cylindres
1332 Décodage des caractéristiques
1335 :solide: l'objet solide à traiter
1336 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1337 :n_recur: niveau de récursivité
1340 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1341 :axe_x, axe_y, axe_z: coordonnées de l'axe
1342 :rayon: rayon moyen entre les deux faces
1343 :hauteur: hauteur du cylindre
1344 :epaisseur: épaisseur de l'interface entre les deux faces
1347 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_0"
1348 blabla = "Dans {} :".format(nom_fonction)
1350 if self._verbose_max:
1351 print_tab (n_recur, blabla)
1352 print_tab (n_recur, "face_1 : ", caract_face_1)
1353 print_tab (n_recur, "face_2 : ", caract_face_2)
1355 # Coordonnées du centre de la base
1356 coo_x = caract_face_1[2][1]
1357 coo_y = caract_face_1[2][2]
1358 coo_z = caract_face_1[2][3]
1359 # Coordonnées de l'axe
1360 axe_x = caract_face_1[2][4]
1361 axe_y = caract_face_1[2][5]
1362 axe_z = caract_face_1[2][6]
1364 rayon = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1365 # Hauteur : une longueur caractéristique pour être certain de tout prendre
1366 l_diag = self._calcul_lg_caract ( solide, n_recur )
1367 hauteur = 10.*l_diag
1368 if self._verbose_max:
1369 print_tab (n_recur, "Hauteur englobante : ", hauteur)
1371 epaisseur = np.abs(caract_face_2[2][7]-caract_face_1[2][7])
1373 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur
1375 #=========================== Fin de la méthode ==================================
1377 #=========================== Début de la méthode =================================
1379 def _cree_face_mediane_cylindre_1 ( self, coo_c, v_axe, rayon, hauteur, n_recur ):
1380 """Crée la face médiane entre deux autres - cas des cylindres
1382 Création des objets temporaires et de la face externe du cylindre support
1385 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1386 :axe_x, axe_y, axe_z: coordonnées de l'axe
1387 :rayon: rayon moyen entre les deux faces
1388 :hauteur: hauteur du cylindre
1389 :n_recur: niveau de récursivité
1392 :face: la face médiane
1394 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1"
1395 blabla = "Dans {} :\n".format(nom_fonction)
1397 # Les caractéristiques du cylindre à créer
1398 if self._verbose_max:
1399 print_tab (n_recur, blabla)
1400 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1401 print_tab (n_recur, "Axe : ({}, {}, {})".format(v_axe[0], v_axe[1], v_axe[2]))
1402 print_tab (n_recur, "Rayon : ", rayon)
1403 print_tab (n_recur, "Hauteur : ", hauteur)
1405 # 1. Objets préalables
1406 nom_par_1 = "{}_R".format(self.nom_solide)
1407 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon))
1408 nom_par_2 = "{}_H".format(self.nom_solide)
1409 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(hauteur))
1411 centre, _, plan = self._cree_centre_axe_plan ( coo_c, v_axe, self.nom_solide, n_recur )
1413 # 2. Création de l'esquisse
1414 sketch = self._cree_face_mediane_cylindre_1_a ( plan, centre, rayon, nom_par_1, n_recur )
1417 face = self._cree_face_mediane_cylindre_1_b ( sketch, nom_par_2, n_recur )
1421 #=========================== Fin de la méthode ==================================
1423 #=========================== Début de la méthode =================================
1425 def _cree_face_mediane_cylindre_1_a ( self, plan, centre, rayon, nom_par_1, n_recur ):
1426 """Crée la face médiane entre deux autres - cas des cylindres
1428 Création des objets temporaires et de la face externe du cylindre support
1431 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1432 :axe_x, axe_y, axe_z: coordonnées de l'axe
1433 :rayon: rayon moyen entre les deux faces
1434 :nom_par_1: nom_par_1
1435 :n_recur: niveau de récursivité
1438 :face: la face médiane
1440 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1_a"
1441 blabla = "Dans {} :\n".format(nom_fonction)
1443 # Les caractéristiques du cylindre à créer
1444 if self._verbose_max:
1445 print_tab (n_recur, blabla)
1446 print_tab (n_recur, "Plan : {}".format(plan.name()))
1447 print_tab (n_recur, "Centre : {}".format(centre.name()))
1448 print_tab (n_recur, "Rayon : ", rayon)
1450 sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
1452 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", centre.name()), False)
1453 SketchPoint_1 = SketchProjection_1.createdFeature()
1455 SketchCircle_1 = sketch.addCircle(0., 0., rayon)
1456 sketch.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
1457 sketch.setRadius(SketchCircle_1.results()[1], nom_par_1)
1460 nom_sketch = "{}_esquisse".format(self.nom_solide)
1461 exec_nom (sketch, nom_sketch)
1465 #=========================== Fin de la méthode ==================================
1467 #=========================== Début de la méthode =================================
1469 def _cree_face_mediane_cylindre_1_b ( self, sketch, nom_par_2, n_recur ):
1470 """Crée la face médiane entre deux autres - cas des cylindres
1472 Création des objets de construction et de la face externe du cylindre support
1476 :n_recur: niveau de récursivité
1479 :face: la face médiane
1481 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1_b"
1482 blabla = "Dans {} :\n".format(nom_fonction)
1484 # Les caractéristiques du cylindre à créer
1485 if self._verbose_max:
1486 print_tab (n_recur, blabla)
1487 print_tab (n_recur, "Esquisse : ", sketch.name())
1488 print_tab (n_recur, "nom_par_2 : ", nom_par_2)
1490 # Création du cylindre complet
1491 cylindre = model.addExtrusion(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(sketch.name()))], model.selection(), nom_par_2, nom_par_2, "Edges")
1492 cylindre.execute(True)
1494 nom_cylindre = "{}_cylindre".format(self.nom_solide)
1495 nommage (cylindre, nom_cylindre, (85, 0, 255))
1497 # Intersection de la face cylindrique avec le solide initial
1498 face = self._creation_face_inter ( nom_cylindre )
1502 #=========================== Fin de la méthode ==================================
1504 #=========================== Début de la méthode =================================
1506 def _cree_face_mediane_sphere ( self, caract_face_1, caract_face_2, n_recur ):
1507 """Crée la face médiane entre deux autres - cas des sphères
1510 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1511 :n_recur: niveau de récursivité
1514 :face: la face médiane
1517 nom_fonction = __name__ + "/_cree_face_mediane_sphere"
1518 blabla = "Dans {} :".format(nom_fonction)
1521 if self._verbose_max:
1522 print_tab (n_recur, blabla)
1523 print_tab (n_recur, "face_1 : ", caract_face_1)
1524 print_tab (n_recur, "face_2 : ", caract_face_2)
1526 # Caractéristiques des sphères
1527 coo_x, coo_y, coo_z, rayon, epaisseur = self._cree_face_mediane_sphere_0 ( caract_face_1, caract_face_2, n_recur )
1529 # Contrôle de la validité de l'épaisseur
1530 erreur = self._verif_epaisseur ( epaisseur )
1532 # Création de la face
1534 face = self._cree_face_mediane_sphere_1 ( coo_x, coo_y, coo_z, rayon )
1540 #=========================== Fin de la méthode ==================================
1542 #=========================== Début de la méthode =================================
1544 def _cree_face_mediane_sphere_0 ( self, caract_face_1, caract_face_2, n_recur ):
1545 """Crée la face médiane entre deux autres - cas des sphères
1547 Décodage des caractéristiques
1550 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1551 :n_recur: niveau de récursivité
1554 :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1555 :rayon: rayon moyen entre les deux faces
1556 :epaisseur: épaisseur de l'interface entre les deux faces
1559 nom_fonction = __name__ + "/_cree_face_mediane_sphere_0"
1560 blabla = "Dans {} :".format(nom_fonction)
1563 if self._verbose_max:
1564 print_tab (n_recur, blabla)
1565 print_tab (n_recur, "face_1 : ", caract_face_1)
1566 print_tab (n_recur, "face_2 : ", caract_face_2)
1568 # Coordonnées du centre de la sphère
1569 coo_x = caract_face_1[2][1]
1570 coo_y = caract_face_1[2][2]
1571 coo_z = caract_face_1[2][3]
1573 rayon = (caract_face_2[2][4]+caract_face_1[2][4])/2.
1575 epaisseur = np.abs(caract_face_2[2][4]-caract_face_1[2][4])
1577 return coo_x, coo_y, coo_z, rayon, epaisseur
1579 #=========================== Fin de la méthode ==================================
1581 #=========================== Début de la méthode =================================
1583 def _cree_face_mediane_sphere_1 ( self, coo_x, coo_y, coo_z, rayon ):
1584 """Crée la face médiane entre deux autres - cas des sphères
1586 Création des objets de construction et de la face externe de la sphère support
1589 :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1590 :rayon: rayon moyen entre les deux faces
1593 :face: la face externe de la sphère support
1596 nom_fonction = __name__ + "/_cree_face_mediane_sphere_1"
1597 blabla = "Dans {} :\n".format(nom_fonction)
1599 # Les caractéristiques de la sphère à créer
1600 if self._verbose_max:
1602 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1603 texte += "Rayon : {}".format(rayon)
1606 # Création du point central
1607 centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1608 nom_centre = "{}_centre".format(self.nom_solide)
1609 exec_nom (centre,nom_centre)
1611 # Création d'un plan passant par ce centre et l'axe OX
1612 plan = model.addPlane(self.part_doc, model.selection("EDGE", "PartSet/OX"), model.selection("VERTEX", nom_centre), False)
1613 nom_plan = "{}_plan".format(self.nom_solide)
1614 exec_nom (plan,nom_plan)
1616 # Création de l'esquisse
1617 nom_par_1 = "{}_R".format(self.nom_solide)
1618 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon))
1620 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1622 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
1623 SketchPoint_1 = SketchProjection_1.createdFeature()
1625 ### Create SketchArc
1626 SketchArc_1 = sketch.addArc(coo_x, coo_y, coo_x-rayon, coo_y, coo_x+rayon, coo_y, False)
1627 sketch.setRadius(SketchArc_1.results()[1], nom_par_1)
1628 sketch.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
1630 ### Create SketchLine
1631 SketchLine_1 = sketch.addLine(coo_x-rayon, coo_y, coo_x+rayon, coo_y)
1632 nom_ligne = "{}_ligne".format(self.nom_solide)
1633 SketchLine_1.setName(nom_ligne)
1634 SketchLine_1.result().setName(nom_ligne)
1635 SketchLine_1.setAuxiliary(True)
1636 sketch.setHorizontal(SketchLine_1.result())
1637 sketch.setCoincident(SketchArc_1.startPoint(), SketchLine_1.startPoint())
1638 sketch.setCoincident(SketchArc_1.endPoint(), SketchLine_1.endPoint())
1639 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result())
1643 nom_sketch = "{}_esquisse".format(self.nom_solide)
1644 exec_nom (sketch,nom_sketch)
1646 # Création de la sphère complète
1647 sphere = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", "{}/{}".format(nom_sketch,nom_ligne)), 360, 0, "Edges")
1648 sphere.execute(True)
1650 nom_sphere = "{}_sphere".format(self.nom_solide)
1651 nommage (sphere, nom_sphere, (85, 0, 255))
1653 # Intersection de la face sphérique avec le solide initial
1654 face = self._creation_face_inter ( nom_sphere )
1658 #=========================== Fin de la méthode ==================================
1660 #=========================== Début de la méthode =================================
1662 def _cree_face_mediane_tore ( self, caract_face_1, caract_face_2, n_recur ):
1663 """Crée la face médiane entre deux autres - cas des tores
1666 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1667 :n_recur: niveau de récursivité
1670 :face: la face médiane
1673 nom_fonction = __name__ + "/_cree_face_mediane_tore"
1674 blabla = "Dans {} :".format(nom_fonction)
1677 if self._verbose_max:
1678 print_tab (n_recur, blabla)
1679 print_tab (n_recur, "face_1 : ", caract_face_1)
1680 print_tab (n_recur, "face_2 : ", caract_face_2)
1682 # Caractéristiques des tores
1683 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 = self._cree_face_mediane_tore_0 ( caract_face_1, caract_face_2, n_recur )
1685 # Contrôle de la validité de l'épaisseur (bidon)
1686 erreur = self._verif_epaisseur ( EP_MIN*10. )
1688 # Création de la face
1690 face = self._cree_face_mediane_tore_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 )
1696 #=========================== Fin de la méthode ==================================
1698 #=========================== Début de la méthode =================================
1700 def _cree_face_mediane_tore_0 ( self, caract_face_1, caract_face_2, n_recur ):
1701 """Crée la face médiane entre deux autres - cas des tores
1703 Décodage des caractéristiques
1706 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1707 :n_recur: niveau de récursivité
1710 :coo_x, coo_y, coo_z: coordonnées du centre du tore
1711 :axe_x, axe_y, axe_z: coordonnées de l'axe
1712 :rayon_1 : rayon principal
1713 :rayon_2 : rayon secondaire
1716 nom_fonction = __name__ + "/_cree_face_mediane_tore_0"
1717 blabla = "Dans {} :".format(nom_fonction)
1720 if self._verbose_max:
1721 print_tab (n_recur, blabla)
1722 print_tab (n_recur, "face_1 : ", caract_face_1)
1723 print_tab (n_recur, "face_2 : ", caract_face_2)
1725 # Coordonnées du centre du tore
1726 coo_x = caract_face_1[2][1]
1727 coo_y = caract_face_1[2][2]
1728 coo_z = caract_face_1[2][3]
1729 # Coordonnées de l'axe
1730 axe_x = caract_face_1[2][4]
1731 axe_y = caract_face_1[2][5]
1732 axe_z = caract_face_1[2][6]
1734 rayon_1 = caract_face_2[2][7]
1735 rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1737 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2
1739 #=========================== Fin de la méthode ==================================
1741 #=========================== Début de la méthode =================================
1743 def _cree_face_mediane_tore_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 ):
1744 """Crée la face médiane entre deux autres - cas des tores
1746 Création des objets de construction et de la face externe du tore support
1749 :coo_x, coo_y, coo_z: coordonnées du centre du tore
1750 :axe_x, axe_y, axe_z: coordonnées de l'axe
1751 :rayon_1 : rayon principal
1752 :rayon_2 : rayon secondaire
1755 :face: la face externe du tore support
1758 nom_fonction = __name__ + "/_cree_face_mediane_tore_1"
1759 blabla = "Dans {} :\n".format(nom_fonction)
1762 if self._verbose_max:
1764 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1765 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1766 texte += "Rayon principal : {}\n".format(rayon_1)
1767 texte += "Rayon secondaire : {}".format(rayon_2)
1770 # Création du point central
1771 centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1772 nom_centre = "{}_centre".format(self.nom_solide)
1773 exec_nom (centre,nom_centre)
1776 axe = model.addAxis(self.part_doc, axe_x, axe_y, axe_z)
1777 nom_axe = "{}_axe".format(self.nom_solide)
1778 exec_nom (axe,nom_axe)
1780 # Création d'un plan passant par ce centre et cet axe
1781 plan = model.addPlane(self.part_doc, model.selection("EDGE", nom_axe), model.selection("VERTEX", nom_centre), False)
1782 nom_plan = "{}_plan".format(self.nom_solide)
1783 exec_nom (plan,nom_plan)
1785 # Création de l'esquisse
1786 nom_par_1 = "{}_R_1".format(self.nom_solide)
1787 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1788 nom_par_2 = "{}_R_2".format(self.nom_solide)
1789 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1791 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1793 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
1794 SketchPoint_1 = SketchProjection_1.createdFeature()
1796 SketchProjection_2 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
1797 SketchLine_1 = SketchProjection_2.createdFeature()
1799 SketchPoint_2 = sketch.addPoint(rayon_1, 0.)
1800 sketch.setDistance(SketchPoint_1.result(), SketchPoint_2.coordinates(), nom_par_1, True)
1802 SketchLine_2 = sketch.addLine(0., 0., rayon_1, 0.)
1803 SketchLine_2.setAuxiliary(True)
1804 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.startPoint())
1805 sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_2.endPoint())
1806 sketch.setPerpendicular(SketchLine_1.result(), SketchLine_2.result())
1808 SketchCircle_1 = sketch.addCircle(0., 0., rayon_2)
1809 sketch.setCoincident(SketchPoint_2.result(), SketchCircle_1.center())
1810 sketch.setRadius(SketchCircle_1.results()[1], nom_par_2)
1814 nom_sketch = "{}_esquisse".format(self.nom_solide)
1815 exec_nom (sketch,nom_sketch)
1817 # Création du tore complet
1818 nom_tore = "{}_tore".format(self.nom_solide)
1819 self._cree_revolution ( nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_tore )
1821 # Intersection de la face torique avec le solide initial
1822 face = self._creation_face_inter ( nom_tore )
1826 #=========================== Fin de la méthode ==================================
1828 #=========================== Début de la méthode =================================
1830 def _cree_face_mediane_cone ( self, caract_face_1, caract_face_2, n_recur ):
1831 """Crée la face médiane entre deux autres - cas des cones
1834 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1835 :n_recur: niveau de récursivité
1838 :face: la face médiane
1841 nom_fonction = __name__ + "/_cree_face_mediane_cone"
1842 blabla = "Dans {} :".format(nom_fonction)
1845 if self._verbose_max:
1846 print_tab (n_recur, blabla)
1847 print_tab (n_recur, "face_1 : ", caract_face_1)
1848 print_tab (n_recur, "face_2 : ", caract_face_2)
1850 # Caractéristiques des cones
1851 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur = self._cree_face_mediane_cone_0 ( caract_face_1, caract_face_2, n_recur )
1853 # Contrôle de la validité de l'épaisseur (bidon)
1854 erreur = self._verif_epaisseur ( EP_MIN*10. )
1856 # Création de la face
1858 face = self._cree_face_mediane_cone_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur )
1864 #=========================== Fin de la méthode ==================================
1866 #=========================== Début de la méthode =================================
1868 def _cree_face_mediane_cone_0 ( self, caract_face_1, caract_face_2, n_recur ):
1869 """Crée la face médiane entre deux autres - cas des cones
1871 Décodage des caractéristiques
1874 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1875 :n_recur: niveau de récursivité
1878 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1879 :axe_x, axe_y, axe_z: coordonnées de l'axe
1880 :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1881 :hauteur: hauteur du cone
1884 nom_fonction = __name__ + "/_cree_face_mediane_cone_0"
1885 blabla = "Dans {} :".format(nom_fonction)
1888 if self._verbose_max:
1889 print_tab (n_recur, blabla)
1890 print_tab (n_recur, "face_1 : ", caract_face_1)
1891 print_tab (n_recur, "face_2 : ", caract_face_2)
1893 # Coordonnées du centre de la base
1894 coo_x = caract_face_1[2][1]
1895 coo_y = caract_face_1[2][2]
1896 coo_z = caract_face_1[2][3]
1897 # Coordonnées de l'axe
1898 axe_x = caract_face_1[2][4]
1899 axe_y = caract_face_1[2][5]
1900 axe_z = caract_face_1[2][6]
1902 rayon_1 = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1903 rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1905 hauteur = caract_face_1[2][9]
1908 if self._verbose_max:
1909 print_tab (n_recur, "coo_x : ", coo_x)
1910 print_tab (n_recur, "coo_y : ", coo_y)
1911 print_tab (n_recur, "coo_z : ", coo_z)
1912 print_tab (n_recur, "axe_x : ", axe_x)
1913 print_tab (n_recur, "axe_y : ", axe_y)
1914 print_tab (n_recur, "axe_z : ", axe_z)
1915 print_tab (n_recur, "rayon_1 : ", rayon_1)
1916 print_tab (n_recur, "rayon_2 : ", rayon_2)
1917 print_tab (n_recur, "hauteur : ", hauteur)
1919 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur
1921 #=========================== Fin de la méthode ==================================
1923 #=========================== Début de la méthode =================================
1925 def _cree_face_mediane_cone_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur ):
1926 """Crée la face médiane entre deux autres - cas des cones
1928 Création des objets de construction et de la face externe du cone support
1931 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1932 :axe_x, axe_y, axe_z: coordonnées de l'axe
1933 :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1934 :hauteur: hauteur du cone
1937 :face: la face externe du cone support
1939 nom_fonction = __name__ + "/_cree_face_mediane_cone_1"
1940 blabla = "Dans {} :\n".format(nom_fonction)
1943 if self._verbose_max:
1945 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1946 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1947 texte += "Rayons : {}, {}\n".format(rayon_1, rayon_2)
1948 texte += "Hauteur : {}".format(hauteur)
1951 # 1. Création du point central de la base, côté rayon_1
1952 centre_1 = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1953 nom_centre_1 = "{}_centre_1".format(self.nom_solide)
1954 exec_nom (centre_1,nom_centre_1)
1956 # 2. Création du point central, du côté de rayon_2
1957 centre_2 = model.addPoint(self.part_doc, coo_x+hauteur*axe_x, coo_y+hauteur*axe_y, coo_z+hauteur*axe_z)
1958 nom_centre_2 = "{}_centre_2".format(self.nom_solide)
1959 exec_nom (centre_2,nom_centre_2)
1961 # 3. Création de l'axe
1962 axe = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre_1), model.selection("VERTEX", nom_centre_2))
1963 nom_axe = "{}_axe".format(self.nom_solide)
1964 exec_nom (axe,nom_axe)
1966 # 4. Création d'un plan passant par le centre de la base et l'axe
1967 # 4.1. Création d'un vecteur perpendiculaire à l'axe
1969 v_perp = model.addAxis(self.part_doc, -coeff*axe_y, coeff*axe_x, 0.)
1970 nom_v_perp = "{}_v_perp".format(self.nom_solide)
1971 exec_nom (v_perp,nom_v_perp)
1972 # 4.2. Création du plan
1973 plan = model.addPlane(self.part_doc, model.selection("EDGE",nom_v_perp), model.selection("VERTEX", nom_centre_1), True)
1974 nom_plan = "{}_plan".format(self.nom_solide)
1975 exec_nom (plan,nom_plan)
1978 nom_par_1 = "{}_R_1".format(self.nom_solide)
1979 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1980 nom_par_2 = "{}_R_2".format(self.nom_solide)
1981 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1982 nom_par_3 = "{}_H".format(self.nom_solide)
1983 model.addParameter(self.part_doc, "{}".format(nom_par_3), "{}".format(hauteur))
1985 # 6. Création de l'esquisse
1987 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1989 # 6.1. Projection des centres et de l'axe
1990 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre_1), False)
1991 SketchPoint_1 = SketchProjection_1.createdFeature()
1992 sk_coo_x_1 = SketchAPI_Point(SketchPoint_1).coordinates().x()
1993 sk_coo_y_1 = SketchAPI_Point(SketchPoint_1).coordinates().y()
1995 SketchProjection_2 = sketch.addProjection(model.selection("VERTEX", nom_centre_2), False)
1996 SketchPoint_2 = SketchProjection_2.createdFeature()
1997 sk_coo_x_2 = SketchAPI_Point(SketchPoint_2).coordinates().x()
1998 sk_coo_y_2 = SketchAPI_Point(SketchPoint_2).coordinates().y()
2000 SketchProjection_3 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
2001 SketchLine_0 = SketchProjection_3.createdFeature()
2003 # 6.2. Lignes perpendiculaires à l'axe passant par les centres
2004 SketchLine_1 = sketch.addLine(sk_coo_x_1, sk_coo_y_1, sk_coo_x_1+rayon_1, sk_coo_y_1)
2005 SketchLine_1.setAuxiliary(True)
2006 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.startPoint())
2007 sketch.setPerpendicular(SketchLine_0.result(), SketchLine_1.result())
2008 sketch.setLength(SketchLine_1.result(), nom_par_1)
2010 SketchLine_2 = sketch.addLine(sk_coo_x_2, sk_coo_y_2, sk_coo_x_2+rayon_2, sk_coo_y_2)
2011 SketchLine_2.setAuxiliary(True)
2012 sketch.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_2.startPoint())
2013 sketch.setPerpendicular(SketchLine_0.result(), SketchLine_2.result())
2014 sketch.setLength(SketchLine_2.result(), nom_par_2)
2016 # 6.3. Ligne joignant les extrémités des précédentes et point milieu
2017 SketchLine_3 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
2018 sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_1.endPoint())
2019 sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_2.endPoint())
2020 SketchLine_3.setAuxiliary(True)
2021 SketchPoint_3 = sketch.addPoint(sk_coo_x_1, sk_coo_y_1)
2022 sketch.setMiddlePoint(SketchLine_3.result(), SketchPoint_3.coordinates())
2024 # 6.4. Ligne support de la future révolution
2025 SketchLine_4 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
2026 sketch.setMiddlePoint(SketchLine_4.result(), SketchPoint_3.coordinates())
2027 sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_4.result())
2028 sketch.setLength(SketchLine_4.result(), "1.2*{}".format(nom_par_3))
2032 nom_sketch = "{}_esquisse".format(self.nom_solide)
2033 exec_nom (sketch,nom_sketch)
2035 # Création du cone complet
2036 nom_cone = "{}_cone".format(self.nom_solide)
2037 self._cree_revolution ( nom_sketch, nom_centre_1, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_cone )
2039 # Intersection de la face conique avec le solide initial
2040 face = self._creation_face_inter ( nom_cone )
2044 #=========================== Fin de la méthode ==================================
2046 #=========================== Début de la méthode =================================
2048 def _cree_centre_axe_plan ( self, coo_c, vnor, prefixe, n_recur ):
2049 """Crée un centre, un axe, un plan
2054 :coo_c: coordonnées du centre de la base
2055 :vnor: coordonnées du vecteur normal
2056 :prefix: prefixe du nom des objets
2057 :n_recur: niveau de récursivité
2061 :normal: vecteur normal
2065 nom_fonction = __name__ + "/_cree_centre_axe_plan"
2066 blabla = "Dans {} :".format(nom_fonction)
2067 if self._verbose_max:
2068 print_tab (n_recur, blabla)
2069 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
2070 print_tab (n_recur, "Normale : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
2072 # Création du point central
2073 centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
2074 nom_centre = "{}_centre".format(prefixe)
2075 exec_nom (centre,nom_centre)
2077 # Création du vecteur normal
2078 v_norm = model.addAxis(self.part_doc, vnor[0], vnor[1], vnor[2])
2079 nom_vnorm = "{}_normale".format(prefixe)
2080 exec_nom (v_norm,nom_vnorm)
2082 # Création du plan perpendiculaire au vecteur normal
2083 plan = model.addPlane(self.part_doc, model.selection("EDGE", v_norm.name()), model.selection("VERTEX", centre.name()), True)
2084 nom_plan = "{}_plan".format(prefixe)
2085 exec_nom (plan,nom_plan)
2087 #print ("fin de {}".format(nom_fonction))
2089 return centre, v_norm, plan
2091 #=========================== Fin de la méthode ==================================
2093 #=========================== Début de la méthode =================================
2095 def _calcul_lg_caract ( self, objet, n_recur ):
2096 """Crée une longueur caractéristique de l'objet
2099 :objet: l'objet à traiter
2100 :n_recur: niveau de récursivité
2103 :l_caract: longueur caractéristique de l'objet
2106 nom_fonction = __name__ + "/_calcul_lg_caract"
2107 blabla = "Dans {} :".format(nom_fonction)
2109 if self._verbose_max:
2110 print_tab (n_recur, blabla)
2112 properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
2113 l_caract = properties[0]
2115 if self._verbose_max:
2116 print_tab (n_recur, "Longueur caractéristique : ", l_caract)
2120 #=========================== Fin de la méthode ==================================
2122 #=========================== Début de la méthode =================================
2124 def _cree_revolution ( self, nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_objet ):
2125 """Crée un volume de révolution
2128 :nom_sketch: nom de l'esquisse à révolutionner
2129 :nom_centre: nom du point associé au centre du volume de révolution
2130 :coo_x, coo_y, coo_z: coordonnées du centre du tore
2131 :axe_x, axe_y, axe_z: coordonnées de l'axe
2132 :rayon_1 : rayon principal
2133 :rayon_2 : rayon secondaire
2134 :nom_objet: nom de l'objet 2D créé
2137 nom_fonction = __name__ + "/_cree_revolution"
2138 blabla = "Dans {} :\n".format(nom_fonction)
2140 if self._verbose_max:
2142 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
2143 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
2146 # Création d'un point décalé par rapport au point central
2147 point = model.addPoint(self.part_doc, coo_x+axe_x, coo_y+axe_y, coo_z+axe_z)
2148 nom_point = "{}_point".format(self.nom_solide)
2149 exec_nom (point,nom_point)
2151 # Création de l'axe de la rotation
2152 axe_r = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("VERTEX", nom_point))
2153 nom_axe_r = "{}_axe_r".format(self.nom_solide)
2154 exec_nom (axe_r,nom_axe_r)
2156 # Création de l'objet complet
2157 objet = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", nom_axe_r), 360, 0, "Edges")
2160 nommage (objet, nom_objet, (85, 0, 255))
2162 #=========================== Fin de la méthode ==================================
2164 #=========================== Début de la méthode =================================
2166 def _creation_face_inter ( self, nom_objet ):
2167 """Crée la face par intersection entre l'objet initial et une face complète
2169 . Repère la face principale de l'objet support
2170 . Réalise l'intersection avec le solide initial
2173 :nom_objet: nom de l'objet 2D créé
2176 :face: la face externe de l'objet support intersecté avec le solide initial
2179 nom_fonction = __name__ + "/_creation_face_inter"
2180 blabla = "Dans {} :\n".format(nom_fonction)
2182 if self._verbose_max:
2185 face = model.addCommon(self.part_doc, [model.selection("SOLID", self.nom_solide_aux), model.selection("FACE", nom_objet)], keepSubResults = True)
2190 #=========================== Fin de la méthode ==================================
2192 #=========================== Début de la méthode =================================
2194 def face_mediane_solide (self, solide, n_recur=0):
2195 """Calcul de la face médiane pour un solide
2198 :solide: solide SHAPER à traiter
2199 :n_recur: niveau de récursivité
2202 :erreur: code d'erreur
2203 :message: message d'erreur
2206 nom_fonction = __name__ + "/face_mediane_solide"
2207 blabla = "Dans {} :".format(nom_fonction)
2209 if self._verbose_max:
2210 print_tab (n_recur, blabla, saut_av=True)
2212 print_tab (n_recur, "Traitement du solide ", solide.name())
2221 # 2. Calcul des caractéristiques géométriques des faces
2223 tb_caract = self._calcul_caract_faces ( solide, n_recur )
2225 # 3. Tri des faces en fonction de leurs caractéristiques géométriques
2227 erreur, message, caract_face_1, caract_face_2 = self._tri_faces ( tb_caract, n_recur )
2231 # 4. Création de la face médiane
2233 erreur, face = self._cree_face_mediane ( solide, caract_face_1, caract_face_2, n_recur )
2234 if ( erreur or ( face is None ) ):
2237 # 6. Exportation step
2239 if self._export_step:
2240 fichier = os.path.join(self.rep_step, "{}.stp".format(face.result().name()))
2241 export = model.exportToFile(self.part_doc, fichier, [model.selection(face.result().shapeType(), face.result().name())])
2242 export.execute(True)
2249 if ( erreur and self._verbose_max ):
2250 print (blabla, message)
2252 return erreur, message
2254 #=========================== Fin de la méthode ==================================
2256 #=========================== Début de la méthode =================================
2258 def _traitement_objet (self, solide, n_recur=0):
2259 """Traitement d'un objet
2262 :solide: solide SHAPER à traiter
2263 :n_recur: niveau de récursivité
2266 :erreur: code d'erreur
2267 :message: message d'erreur
2270 nom_fonction = __name__ + "/_traitement_objet"
2271 blabla = "Dans {} :".format(nom_fonction)
2273 if self._verbose_max:
2274 print_tab (n_recur, blabla, saut_av=True)
2275 texte = "solide = {} ".format(solide.name())
2276 print_tab (n_recur, texte, solide)
2278 # 1. En cas d'exportation step, répertoire de travail associé à l'éventuel fichier de départ
2279 # Attention à ne pas recréer le répertoire à chaque fois
2280 if self._export_step:
2282 if self.rep_step is None:
2284 if self._verbose_max:
2285 print_tab (n_recur, "Préparation de l'export STEP")
2287 if self.ficcao is None:
2288 self.rep_step = tempfile.mkdtemp(prefix="{}_".format(self.objet_principal.name()))
2290 self.rep_step = os.path.join(os.path.dirname(self.ficcao),"{}_M".format(self.objet_principal.name()))
2291 if os.path.isdir(self.rep_step):
2292 l_aux = os.listdir(self.rep_step)
2293 for nomfic in l_aux:
2294 os.remove(os.path.join(self.rep_step,nomfic))
2296 os.mkdir(self.rep_step)
2298 if self._verbose_max:
2299 print_tab (n_recur, "Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
2301 # 2. Calcul réel de la face médiane
2303 erreur, message = self.face_mediane_solide (solide, n_recur)
2305 return erreur, message
2307 #=========================== Fin de la méthode ==================================
2309 #=========================== Début de la méthode =================================
2311 def surf_fic_cao (self, ficcao, nom_objet=None):
2312 """Calcule la surface médiane pour un objet dans un fichier passé en argument
2315 :ficcao: fichier de l'objet à traiter
2316 :nom_objet: un nom à donner à l'objet à traiter
2319 :erreur: code d'erreur
2320 :message: message d'erreur
2323 nom_fonction = __name__ + "/surf_fic_cao"
2324 blabla = "Dans {} :".format(nom_fonction)
2326 if self._verbose_max:
2336 if self.affiche_aide_globale:
2339 # 1. Définition de la pièce
2341 self.part_doc = model.activeDocument()
2342 if ( self.part_doc.kind() == "PartSet" ):
2343 part = model.addPart(self.part_doc)
2344 self.part_doc = part.document()
2346 # 2. Import de la CAO
2348 self.ficcao = ficcao
2349 print ("Traitement du fichier {}".format(ficcao))
2351 erreur, message, objet = import_cao (self.part_doc, ficcao, nom_objet, self._verbose_max)
2355 # 3. Calcul des surfaces
2357 erreur, message = self.surf_objet_shaper ( objet )
2366 if ( erreur and self._verbose_max ):
2367 print (blabla, message)
2369 return erreur, message
2371 #=========================== Fin de la méthode ==================================
2373 #=========================== Début de la méthode =================================
2375 def surf_objet_shaper (self, objet):
2376 """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2379 :objet: objet à traiter
2382 :erreur: code d'erreur
2383 :message: message d'erreur
2386 nom_fonction = __name__ + "/surf_objet_shaper"
2387 blabla = "Dans {} :".format(nom_fonction)
2389 if self._verbose_max:
2397 if self.affiche_aide_globale:
2400 # 1. Acquisition de la liste des noms des sous-objets solides
2402 self.d_statut_so = dict()
2403 self.l_noms_so = list()
2404 self.l_faces_m = list()
2406 _ = self._nom_sous_objets (objet, True)
2407 if self._verbose_max:
2408 print ("Noms des sous-objets : {}".format(self.l_noms_so))
2410 # 2. Les faces médianes
2412 erreur, message = self._surf_objet_shaper_0 ( objet )
2416 # 3. Gestion des faces créées
2418 self._surf_objet_shaper_1 ( )
2420 # 4. Futur message pour le résultat
2422 if ( self._export_step and not erreur ):
2423 message = "Les fichiers des CAO des surfaces sont dans le répertoire {}".format(self.rep_step)
2427 return erreur, message
2429 #=========================== Fin de la méthode ==================================
2431 #=========================== Début de la méthode =================================
2433 def _surf_objet_shaper_0 (self, objet, n_recur=0):
2434 """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2437 :objet: objet à traiter
2438 :n_recur: niveau de récursivité
2441 :erreur: code d'erreur
2442 :message: message d'erreur
2445 nom_fonction = __name__ + "/_surf_objet_shaper_0"
2446 blabla = "Dans {} :".format(nom_fonction)
2448 if self._verbose_max:
2449 print_tab (n_recur, blabla)
2450 print_tab (n_recur, "n_recur = ", n_recur)
2457 # 1. Au premier passage, il faut récupérer la pièce SHAPER et garder la référence au résultat principal
2459 if ( n_recur == 0 ):
2460 self.part_doc = model.activeDocument()
2461 objet_0 = objet.result()
2462 self.objet_principal = objet_0
2463 objet_bis = objet.defaultResult().shape()
2464 if self._verbose_max:
2465 print_tab (0, "Examen de l'objet initial ", objet.result().name(), saut_av=True)
2466 print_tab (0, "Type python : ", type(objet))
2467 print_tab (0, "Type {} / {} ; volume = ".format(objet_bis.shapeType(),objet_bis.shapeTypeStr()), GeomAlgoAPI_ShapeTools.volume(objet_bis))
2470 if self._verbose_max:
2471 print_tab (n_recur, "Examen de l'objet ", objet.name(), saut_av=True)
2472 print_tab (n_recur, "Type python : ", type(objet))
2473 print_tab (n_recur, "shapeType : ", objet.shapeType())
2475 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
2477 nb_sub_results = objet_0.numberOfSubs()
2479 if self._verbose_max:
2480 print_tab (n_recur, "Examen de l'objet '{}' de type ".format(objet_0.name()), objet_0.shapeType(), saut_av=True)
2481 print_tab (n_recur, "objet.result().numberOfSubs() : ", nb_sub_results)
2483 for n_sobj in range(nb_sub_results):
2485 # 2.1. Exploration récursive de l'arborescence
2487 erreur, message = self._surf_objet_shaper_0 ( objet_0.subResult(n_sobj), n_recur+1 )
2494 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
2496 if ( objet_0.shapeType() == "SOLID" ):
2497 erreur, message = self.surf_solide_shaper ( objet_0, n_recur )
2501 # 3. Futur message pour le résultat
2503 if self._export_step:
2504 message = "Les fichiers STEP des surfaces sont dans le répertoire {}".format(self.rep_step)
2508 return erreur, message
2510 #=========================== Fin de la méthode ==================================
2512 #=========================== Début de la méthode =================================
2514 def _surf_objet_shaper_1 (self, n_recur=0):
2515 """Gestion des surfaces médianes créées
2518 :n_recur: niveau de récursivité
2521 :erreur: code d'erreur
2522 :message: message d'erreur
2525 nom_fonction = __name__ + "/_surf_objet_shaper_1"
2526 blabla = "Dans {} :\n".format(nom_fonction)
2528 if self._verbose_max:
2529 print_tab (n_recur, blabla)
2531 # 1. Informations sur les faces à problème
2533 if self.faces_pb_nb:
2534 if ( self.faces_pb_nb == 1 ):
2535 texte = "1 face pose"
2537 texte = "{} faces posent".format(self.faces_pb_nb)
2538 print_tab (n_recur, "{} problème.".format(texte), self.faces_pb_msg, saut_av=True)
2540 # 2. Si plus d'une face a été créée
2541 if ( len(self.l_faces_m) > 1 ):
2543 # 2.1. Partition du paquet de faces
2545 if self._verbose_max:
2546 print_tab (n_recur, "Partitionnnement des faces créées.")
2548 # 2.1.1. Pour une raison mystérieuse, il faut commencer par les faces entières, puis mettre les sous-faces éventuelles
2550 for (face,_) in self.l_faces_m:
2551 if not face.result().numberOfSubs():
2552 d_faces[face.name()] = [face.name()]
2553 for (face,_) in self.l_faces_m:
2554 nb_sub_results = face.result().numberOfSubs()
2557 for n_sobj in range(nb_sub_results):
2558 laux.append(face.result().subResult(n_sobj).name())
2559 d_faces[face.name()] = laux
2562 for _, laux in d_faces.items():
2563 for s_face_n in laux:
2564 l_objets.append(model.selection("FACE", s_face_n))
2566 Partition_1 = model.addPartition(self.part_doc, l_objets, keepSubResults = True)
2567 nom = "{}_M".format(self.objet_principal.name())
2568 exec_nom (Partition_1,nom)
2571 for face_n, laux in d_faces.items():
2572 Partition_1.result().subResult(iaux).setName("{}".format(face_n))
2573 if ( len(laux) > 1 ):
2574 for jaux, s_face_n in enumerate(laux):
2575 Partition_1.result().subResult(iaux).subResult(jaux).setName("{}_M".format(s_face_n))
2577 self._couleur_objet (Partition_1, n_recur, coul_r=0, coul_g=170, coul_b=0)
2579 # 2.2. Récupération des faces individuelles
2581 if self._verbose_max:
2582 print_tab (n_recur, "Récupération des faces individuelles.")
2585 for iaux, (face,_) in enumerate(self.l_faces_m):
2586 l_objets.append(face.result())
2588 Recover_1 = model.addRecover(self.part_doc, Partition_1, l_objets)
2589 for iaux, (face,_) in enumerate(self.l_faces_m):
2590 Recover_1.results()[iaux].setName("{}".format(face.name()))
2591 Recover_1.results()[iaux].setColor(0, 170, 0)
2592 nb_sub_results = Recover_1.results()[iaux].numberOfSubs()
2593 for n_sobj in range(nb_sub_results):
2594 Recover_1.results()[iaux].subResult(n_sobj).setName("{}_{}".format(face.name(),n_sobj))
2595 Recover_1.results()[iaux].subResult(n_sobj).setColor(0, 170, 0)
2597 # 2.3. Mise en dossier
2599 if self._verbose_max:
2600 print_tab (n_recur, "Mise en dossier.")
2602 for (face,fonction_0) in self.l_faces_m:
2603 dossier = model.addFolder(self.part_doc, fonction_0, face)
2604 dossier.execute(True)
2605 dossier.setName(face.name()[:-2])
2606 dossier = model.addFolder(self.part_doc, Partition_1, Recover_1)
2607 dossier.execute(True)
2608 dossier.setName(self.objet_principal.name())
2610 #=========================== Fin de la méthode ==================================
2612 #=========================== Début de la méthode =================================
2614 def surf_solide_shaper (self, solide, n_recur):
2615 """Calcule les surfaces médianes pour un solide SHAPER solide passé en argument
2618 :solide: solide SHAPER à traiter
2619 :n_recur: numéro de la récurrence
2622 :erreur: code d'erreur
2623 :message: message d'erreur
2626 nom_fonction = __name__ + "/surf_solide_shaper"
2627 blabla = "Dans {} :".format(nom_fonction)
2629 if self._verbose_max:
2630 print_tab (n_recur, blabla, saut_av=True)
2637 self.nom_solide = solide.name()
2638 if self._verbose_max:
2639 print_tab (n_recur, "solide : ", self.nom_solide)
2641 # 1. Isolement du solide
2642 solide_aux, recover = self._isole_solide ( solide, n_recur )
2644 # 2. Traitement de l'objet correspondant
2645 erreur, message = self._traitement_objet ( solide_aux, n_recur=n_recur )
2647 if ( erreur and self._verbose_max ):
2648 print (blabla, message)
2650 # 3. Neutralisation des erreurs dues à l'épaisseur
2651 if ( erreur in (-2,-1,2) ):
2657 # 4. Mise en forme de l'objet principal récupéré
2658 if ( recover is not None ):
2659 _ = self._nom_sous_objets (recover, False)
2663 return erreur, message
2665 #=========================== Fin de la méthode ==================================
2667 #========================== Fin de la classe ====================================
2669 #==================================================================================
2671 #==================================================================================
2673 if __name__ == "__main__" :
2675 HOME_SH_SM_EXCHANGE = os.environ["HOME_SH_SM_EXCHANGE"]
2677 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "Solid_7.step"))
2678 L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Objet_1.stp"))
2679 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval_007.stp"))
2680 ##L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval.stp"))
2681 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2.step"))
2682 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_22.step"))
2683 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_5.step"))
2684 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Observatoire.stp"))
2686 for FIC_CAO in L_FIC_CAO:
2691 #L_OPTIONS.append("-h")
2692 #L_OPTIONS.append("-v")
2693 L_OPTIONS.append("-vmax")
2694 L_OPTIONS.append("-export_step")
2696 # 2. Lancement de la classe
2698 #print ("L_OPTIONS :", L_OPTIONS)
2700 SURFACE_MEDIANE = SurfaceMediane(L_OPTIONS)
2701 if SURFACE_MEDIANE.affiche_aide_globale:
2702 sys.stdout.write(SURFACE_MEDIANE.__doc__+"\n")
2705 PARTSET = model.moduleDocument()
2706 _ = model.addPart(PARTSET)
2707 ERREUR, MESSAGE_ERREUR = SURFACE_MEDIANE.surf_fic_cao(FIC_CAO)
2709 MESSAGE_ERREUR += "\n Code d'erreur : %d\n" % ERREUR
2710 sys.stderr.write(MESSAGE_ERREUR)