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.18"
41 #========================= Les imports - Début ===================================
52 from SketchAPI import *
53 from salome.shaper import model
54 from salome.shaper import geom
56 from GeomAlgoAPI import *
60 #========================== Les imports - Fin ====================================
63 D_FMT["stp"] = ["stp", "step"]
64 D_FMT["igs"] = ["igs", "iges"]
65 for CLE in ("brep", "xao"):
68 # statut = 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
87 # Transparence des solides traités correctement
90 # Limite basse de l'épaisseur pour pouvoir faire les intersections
93 #========================= Début de la fonction ==================================
95 def decode_cao (fmt_cao):
96 """Décode le format de la cao
99 :fmt_cao: format du fichier, step, iges, etc.
101 :fmt_cao_0: format décodé
106 fmt_cao_low = fmt_cao.lower()
108 for cle, l_aux in D_FMT.items():
109 if ( fmt_cao_low in l_aux ):
115 #========================= Fin de la fonction ===================================
117 #========================= Début de la fonction ==================================
119 def import_cao (part_doc, ficcao, nom_objet=None, verbose=False):
120 """Importation d'une cao
124 :ficcao: le fichier de la CAO
125 :nom_objet: nom à donner à l'objet lu, éventuellement
127 :objet: l'objet importé dans SHAPER
130 nom_fonction = __name__ + "/import_cao"
131 blabla = "Dans {} :\n".format(nom_fonction)
132 message_0 = "Fichier : {}\n".format(ficcao)
134 message = blabla + message_0
135 message += "nom_objet : {}".format(nom_objet)
143 laux = ficcao.split(".")
144 fmt_cao_0 = decode_cao (laux[-1])
146 if ( fmt_cao_0 not in ("stp", "brep", "igs", "xao") ):
147 message += "Le format de CAO est inconnu"
151 message += "Le fichier de CAO n'a pas été décodé correctement."
154 elif not os.path.isfile(ficcao):
155 message += "Le fichier de CAO est inconnu."
161 objet = model.addImport(part_doc, ficcao)
162 exec_nom (objet, nom_objet)
166 texte = "Objet : '{}'\n".format(objet.result().name())
167 texte += "De type : '{}'".format(objet.result().shapeType())
170 return erreur, message, objet
172 #========================= Fin de la fonction ===================================
174 #========================= Début de la fonction ==================================
176 def couleur_objet (objet, n_recur=0, coul_r=1, coul_g=0, coul_b=0, verbose=False):
177 """Appliquer une couleur à un objet et à ses sous_objets
180 :objet: objet à traiter
181 :n_recur: niveau de récursivité
182 :coul_r,coul_g,coul_b: code RGB de la couleur à appliquer
185 :rang: rang du sous-objet
188 nom_fonction = __name__ + "/couleur_objet"
189 blabla = "Dans {} :".format(nom_fonction)
193 print ("n_recur = {}".format(n_recur))
194 print_tab(n_recur, "objet : ", objet.name())
195 print_tab(n_recur, "RGB = ({},{},{})".format(coul_r,coul_g,coul_b))
197 # 1. Au premier passage, il faut garder la référence au résultat principal
200 objet_0 = objet.result()
204 #print (dir(objet_0))
206 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
208 nb_sub_results = objet_0.numberOfSubs()
211 print_tab(n_recur, "Examen de l'objet",objet_0.name())
212 texte = "Formé de {} sous-objets".format(nb_sub_results)
213 print_tab(n_recur, texte)
215 for n_sobj in range(nb_sub_results):
217 # 2.1. Exploration récursive de l'arborescence
219 couleur_objet ( objet_0.subResult(n_sobj), n_recur+1, coul_r, coul_g, coul_b, verbose )
221 # 2.2. Cet objet n'a pas de sous-objets : on le colore
223 print_tab(n_recur, "Couleur affectée à l'objet ",objet_0.name())
224 #objet_0.setColor (int(coul_r),int(coul_g),int(coul_b))
226 #print ("sortie de {}".format(nom_fonction))
228 #========================= Fin de la fonction ===================================
230 #========================= Début de la fonction ==================================
232 def print_tab (nb_tab, message, argu=None, saut_av=False, saut_ap=False):
233 """Imprime avec des tabulations
236 :nb_tab: nombre de tabulations à appliquer
237 :message: message principal
238 :argu: argument du format
239 :saut_av: saut de ligne avant le texte
240 :saut_ap: saut de ligne après le texte
248 for _ in range(nb_tab):
252 if ( argu is not None ):
253 texte += "{}".format(argu)
260 #========================= Fin de la fonction ===================================
262 #========================= Début de la fonction ==================================
264 def nommage (objet, nom, couleur=None):
265 """Nomme un objet et son résultat
268 :objet: objet à traiter
269 :nom: nom à attribuer
270 :couleur: éventuellement couleur
274 objet.result().setName(nom)
276 if ( couleur is not None ):
277 objet.result().setColor(couleur[0], couleur[1], couleur[2])
279 #========================= Fin de la fonction ===================================
281 #========================= Début de la fonction ==================================
283 def exec_nom (fonction, nom=None, couleur=None):
284 """Exécute la fonction puis éventuellement la nomme et nomme son résultat ; Couleur éventuelle
286 Attention : il faut commencer par exécuter la fonction sinon l enommage n'est pas cohérent en mode macro. Mystère...
289 :fonction: fonction à traiter
290 :nom: nom à attribuer éventuellement
291 :couleur: éventuellement couleur
294 fonction.execute(True)
296 if ( nom is not None ):
297 nommage (fonction, nom, couleur)
299 #========================= Fin de la fonction ===================================
302 #=================================== La classe ===================================
304 class SurfaceMediane (object):
306 """Calcul des surfaces médianes de solides minces
308 L'objectif de ce programme est de créer les surfaces médianes, encore appelées fibres neutres, pour \
309 une structure qui est un solide ou un assemblage de solides (compound).
310 Pour réaliser l'opération, trois façons de faire :
312 1. On lance le script en précisant le fichier à analyser dans la zone d'auto-test.
314 2. Si on part d'un script qui manipule un fichier au format CAO, on crée une instance de la classe SurfaceMediane \
315 puis on appelle la méthode surf_fic_cao avec ce fichier en argument.
317 3. Si on part d'un script qui crée un objet SHAPER, on crée une instance de la classe SurfaceMediane \
318 puis on appelle la méthode surf_objet_shaper avec cet objet en argument.
321 Le programme crée les surfaces sous réserve que pour le solide envisagé, il a réussi à trouver deux faces \
322 de taille identique et supérieure aux tailles des autres faces du solide. \
323 Cela fonctionne pour des surfaces planes ou de forme canonique.
324 Il crée alors une surface au milieu de ces deux grandes faces. \
325 Cette face est coloriée en vert, le solide est en vert et transparent.
327 On sait traiter les faces :
334 Si la création n'a pas eu lieu, un message est émis et les solides sont mis en couleur :
335 . Rouge : le solide n'est pas assez mince.
336 . Bleu : le solide est trop mince, vis-à-vis de la précision de SHAPER.
337 . Orange : la forme de la face n'est pas reconnue.
345 . Exportation finale dans un fichier step. Par défaut, pas d'export.
346 -export_step/-no_export_step
349 surf_fic_cao --> import_cao
350 --> surf_objet_shaper (récursif) --> _nom_sous_objets
351 --> _surf_objet_shaper_0
352 --> surf_solide_shaper --> _isole_solide --> _isole_solide_a
354 --> _traitement_objet --> face_mediane_solide --> _faces_du_solide
356 --> _cree_face_mediane
358 _cree_face_mediane --> _cree_face_mediane_plane
359 --> _cree_face_mediane_cylindre
360 --> _cree_face_mediane_sphere
361 --> _cree_face_mediane_tore
362 --> _cree_face_mediane_cone
363 --> _cree_face_mediane_0
372 affiche_aide_globale = 0
379 nom_solide_aux = None
385 objet_principal = None
386 # Pour chaque sous-objet dans l'ordre de l'arborescence : nom
388 # Statut de chaque sous-objet connu par son nom :
389 # 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
391 # Liste des faces médianes créées et des fonctions initiales
393 # La fonction initiale
399 #=========================== Début de la méthode =================================
401 def __init__ ( self, liste_option ):
403 """Le constructeur de la classe SurfaceMediane
405 Décodage des arguments
406 On cherche ici les arguments généraux : aide, verbeux
409 for option in liste_option :
412 if isinstance(option,str):
413 saux = option.upper()
415 if saux in ( "-H", "-HELP" ):
416 self.affiche_aide_globale = 1
419 elif saux == "-VMAX" :
421 self._verbose_max = 1
422 elif saux == "-EXPORT_STEP":
423 self._export_step = True
424 elif saux == "-NO_EXPORT_STEP":
425 self._export_step = False
427 #=========================== Fin de la méthode ==================================
429 #=========================== Début de la méthode =================================
432 """A la suppression de l'instance de classe"""
433 if self._verbose_max:
434 print ("Suppression de l'instance de la classe.")
436 #=========================== Fin de la méthode ==================================
438 #=========================== Début de la méthode =================================
440 def _nom_sous_objets (self, objet, lecture, n_recur=0, rang=0):
441 """Gère les noms des sous_objets solides
444 :objet: objet à traiter
445 :lecture: vrai pour lire les noms, faux pour les attribuer
446 :n_recur: niveau de récursivité
447 :rang: rang du sous-objet
450 :rang: rang du sous-objet
453 nom_fonction = __name__ + "/_nom_sous_objets"
454 blabla = "Dans {} :\n".format(nom_fonction)
456 if self._verbose_max:
458 for _ in range(n_recur):
460 texte = "\n{}{}".format(prefixe,blabla)
461 texte += "{}n_recur = {}".format(prefixe,n_recur)
462 texte += "\n{}lecture = {}".format(prefixe,lecture)
465 # 1. Au premier passage, il faut garder la référence au résultat principal
468 objet_0 = objet.result()
469 if self._verbose_max:
470 print ("d_statut_so = {}".format(self.d_statut_so))
474 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
476 nb_sub_results = objet_0.numberOfSubs()
478 if self._verbose_max:
479 texte = "{}Examen de l'objet '{}' ".format(prefixe,objet_0.name())
480 texte += "de type '{}'".format(objet_0.shapeType())
481 texte += "\n{}objet.result().numberOfSubs() : {}".format(prefixe,nb_sub_results)
484 for n_sobj in range(nb_sub_results):
486 # 2.1. Exploration récursive de l'arborescence
488 rang = self._nom_sous_objets ( objet_0.subResult(n_sobj), lecture, n_recur+1, rang )
490 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
492 if ( objet_0.shapeType() == "SOLID" ):
493 # A la lecture, on enregistre le nom
496 self.l_noms_so.append(nom)
497 self.d_statut_so[nom] = 0
498 # A la récupération, on redonne le nom et on affecte une couleur dépendant de l'état
500 nom = self.l_noms_so[rang]
502 etat = self.d_statut_so[nom]
503 objet_0.setColor (D_COLOR_R[etat],D_COLOR_G[etat],D_COLOR_B[etat])
505 objet_0.setTransparency (TRANSPARENCE)
510 #=========================== Fin de la méthode ==================================
512 #=========================== Début de la méthode =================================
514 def _isole_solide ( self, solide, n_recur ):
515 """Isole le solide de son arboresence
518 :solide: le solide à traiter
519 :n_recur: numéro de la récurrence
522 :objet: le solide isolé
523 :recover: la fonction de récupération
526 nom_fonction = __name__ + "/_isole_solide"
527 blabla = "Dans {} :".format(nom_fonction)
528 if self._verbose_max:
529 print_tab (n_recur, blabla)
530 texte = "Pour le solide '{}' ".format(solide.name())
531 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
532 print_tab (n_recur, texte)
534 if ( solide.name() != self.objet_principal.name() ):
535 objet, recover = self._isole_solide_a ( solide, n_recur )
538 objet, recover = self._isole_solide_b ( solide, n_recur )
540 if self._verbose_max:
541 print_tab (n_recur, "objet final : ", objet.name())
542 print_tab (n_recur, "fonction_0 : {}".format(self.fonction_0))
543 print_tab (n_recur, "recover : {}".format(recover))
545 return objet, recover
547 #=========================== Fin de la méthode ==================================
549 #=========================== Début de la méthode =================================
551 def _isole_solide_a ( self, solide, n_recur ):
552 """Isole le solide de son arboresence
555 :solide: le solide à traiter
556 :n_recur: numéro de la récurrence
559 :objet: le solide isolé
560 :recover: la fonction de récupération
563 nom_fonction = __name__ + "/_isole_solide_a"
564 blabla = "Dans {} :".format(nom_fonction)
565 if self._verbose_max:
566 print_tab (n_recur, blabla)
567 texte = "Pour le solide '{}' ".format(solide.name())
568 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
569 print_tab (n_recur, texte)
571 if self._verbose_max:
572 print_tab (n_recur, ". Extraction du solide '{}'".format(self.objet_principal.name()))
574 # 1. Extraction du solide
575 remove_subshapes = model.addRemoveSubShapes(self.part_doc, model.selection("COMPOUND", self.objet_principal.name()))
576 exec_nom (remove_subshapes)
577 #print ('remove_subshapes = model.addRemoveSubShapes(part_doc, model.selection("COMPOUND", "{}"))'.format(self.objet_principal.name()))
578 remove_subshapes.setSubShapesToKeep([model.selection("SOLID", solide.name())])
579 #print ('remove_subshapes.setSubShapesToKeep([model.selection("SOLID", "{}")])'.format(solide.name()))
581 self.nom_solide_aux = "{}_S".format(solide.name())
582 if self._verbose_max:
583 print_tab (n_recur, "\tAttribution à remove_subshapes.result() du nom '{}'".format(self.nom_solide_aux))
584 exec_nom (remove_subshapes,self.nom_solide_aux)
586 self.fonction_0 = remove_subshapes
588 # 2. Récupération de l'objet principal
589 recover = model.addRecover(self.part_doc, remove_subshapes, [self.objet_principal])
590 if self._verbose_max:
591 print_tab (n_recur, "\tAttribution à recover du nom '{}'".format(self.objet_principal.name()))
592 exec_nom (recover,self.objet_principal.name())
594 return remove_subshapes.result(), recover
596 #=========================== Fin de la méthode ==================================
598 #=========================== Début de la méthode =================================
600 def _isole_solide_b ( self, solide, n_recur ):
601 """Isole le solide de son arboresence
604 :solide: le solide à traiter
605 :n_recur: numéro de la récurrence
608 :objet: le solide isolé
609 :recover: la fonction de récupération
612 nom_fonction = __name__ + "/_isole_solide_b"
613 blabla = "Dans {} :".format(nom_fonction)
614 if self._verbose_max:
615 print_tab (n_recur, blabla)
616 texte = "Pour le solide '{}' ".format(solide.name())
617 texte += "de l'objet principal '{}'".format(self.objet_principal.name())
618 print_tab (n_recur, texte)
620 if self._verbose_max:
621 print_tab (n_recur, ". Mise en place du solide")
623 self.nom_solide_aux = self.objet_principal.name()
624 self.fonction_0 = None
628 #=========================== Fin de la méthode ==================================
630 #=========================== Début de la méthode =================================
632 def _faces_du_solide ( self, solide, n_recur=0 ):
633 """Détermine les faces d'un solide
636 :solide: solide SHAPER à traiter
637 :n_recur: niveau de récursivité
640 :l_faces_car: pour chaque face du solide (surface,caractéristiques)
643 nom_fonction = __name__ + "/_faces_du_solide"
644 blabla = "Dans {} :".format(nom_fonction)
645 if self._verbose_max:
646 print_tab (n_recur, blabla, saut_av=True)
650 if self._verbose_max:
651 print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
652 print_tab (n_recur, ".. shapeType : ", solide.shapeType())
655 #print_tab (n_recur, "volume = ", GeomAlgoAPI_ShapeTools.volume(solide.shape()))
656 # 1. Repérage des faces
657 objResult = solide.resultSubShapePair()[0]
659 exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
661 l_faces.append(exp.current().face())
666 for iface, face in enumerate(l_faces):
667 surf = GeomAlgoAPI_ShapeTools.area(face)
668 caract = geom.shapeInfo(face)
669 if self._verbose_max:
670 print_tab (n_recur, "\tFace n°{} ; ".format(iface), "surface = {}, caractéristiques = {}".format(surf,caract))
671 l_faces_car.append((surf,caract))
675 #=========================== Fin de la méthode ==================================
677 #=========================== Début de la méthode =================================
679 def _calcul_caract_faces ( self, solide, n_recur ):
680 """Calcule les caractéristiques géométriques des faces du solide
683 :solide: solide SHAPER à traiter
684 :n_recur: niveau de récursivité
687 :tb_caract: tableau des caractéristiques géométriques des faces
690 nom_fonction = __name__ + "/_calcul_caract_faces"
691 blabla = "Dans {} :".format(nom_fonction)
692 if self._verbose_max:
693 print_tab (n_recur, blabla, saut_av=True)
694 print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
695 print_tab (n_recur, ".. shapeType : ", solide.shapeType())
697 # 1. Repérage des faces
698 objResult = solide.resultSubShapePair()[0]
700 exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
702 l_faces.append(exp.current().face())
705 # 2. Caractéristiques
706 nb_faces = len(l_faces)
707 tb_caract = np.zeros((nb_faces,3), dtype = 'object')
708 for iaux, face in enumerate(l_faces):
709 surf = GeomAlgoAPI_ShapeTools.area(face)
710 caract = geom.shapeInfo(face)
711 if self._verbose_max:
712 print_tab (n_recur, "\tFace n°{} ; ".format(iaux), "surface = {}, caractéristiques = {}".format(surf,caract))
714 tb_caract [iaux][0] = face
715 tb_caract [iaux][1] = surf
716 tb_caract [iaux][2] = caract
718 #if self._verbose_max:
719 #for iaux in range(nb_faces):
720 #print ("\t. tb_caract : {} {}".format(surf,tb_caract[iaux][2]))
724 #=========================== Fin de la méthode ==================================
726 #=========================== Début de la méthode =================================
728 def _tri_faces ( self, tb_caract, n_recur ):
729 """Trie les faces en fonction de leurs surfaces
732 :tb_caract: tableau des caractéristiques géométriques des faces
733 :n_recur: niveau de récursivité
736 :tb_caract_1[-1], tb_caract_1[-2]: les caractéristiques des 2 faces les plus grandes
742 nom_fonction = __name__ + "/_tri_faces"
743 blabla = "Dans {} :".format(nom_fonction)
745 # 1. Tri du tableau en fonction des surfaces
746 if self._verbose_max:
747 print_tab (n_recur, blabla)
748 print_tab (n_recur, "tb_caract brut : ", tb_caract)
749 tb_caract_1 = sorted(tb_caract, key=lambda colonnes: colonnes[1])
750 if self._verbose_max:
751 print_tab (n_recur, "tb_caract trié :", tb_caract_1)
753 if self._verbose_max:
754 texte = "\tSurface de la plus grande face : {}, de caractéristiques {}\n".format(tb_caract_1[-1][1],tb_caract_1[-1][2])
755 texte += "\tSurface de la face suivante : {}, de caractéristiques {}".format(tb_caract_1[-2][1],tb_caract_1[-2][2])
758 # 2. La surface suivante doit être différente, sinon ce n'est pas un solide mince
759 if ( len(tb_caract) > 2 ):
761 if self._verbose_max:
762 texte += "\tSurface de la 3ème face suivante : {}, de caractéristiques {}".format(tb_caract_1[-3][1],tb_caract_1[-3][2])
764 ecart = np.abs((tb_caract_1[-1][1]-tb_caract_1[-3][1])/tb_caract_1[-1][1])
765 if ( ecart < self._epsilon ):
766 message = "\nSolide '{}'\n".format(self.nom_solide)
767 message += ". Surface de la plus grande face : {}\n".format(tb_caract_1[-1][1])
768 message += ". Surface de la 1ère face suivante : {}\n".format(tb_caract_1[-2][1])
769 message += ". Surface de la 2ème face suivante : {}\n".format(tb_caract_1[-3][1])
770 if self._verbose_max:
771 message += ". Ecart relatif :{:4.1f}%\n".format(ecart*100.)
772 message += "L'écart est trop faible par rapport à la limite de {}%.\n".format(self._epsilon*100.)
773 message += "==> Impossible de créer la face médiane car le solide n'est pas assez mince.\n"
775 self.d_statut_so[self.nom_solide] = -1
776 self.faces_pb_nb += 1
777 self.faces_pb_msg += message
779 return erreur, message, tb_caract_1[-1], tb_caract_1[-2]
781 #=========================== Fin de la méthode ==================================
783 #=========================== Début de la méthode =================================
785 def _verif_epaisseur ( self, epaisseur ):
786 """Contrôle de la validité de l'épaisseur
789 :epaisseur: épaisseur du solide
792 nom_fonction = __name__ + "/_verif_epaisseur"
793 blabla = "Dans {} :\n".format(nom_fonction)
795 if self._verbose_max:
797 texte += ". Epaisseur du solide : {}\n".format(epaisseur)
798 texte += ". EP_MIN : {}".format(EP_MIN)
801 if ( epaisseur <= EP_MIN ):
802 message = "\nSolide '{}'\n".format(self.nom_solide)
803 message += ". Epaisseur : {}\n".format(epaisseur)
804 message += "L'épaisseur est trop faible par rapport à la limite de {}.\n".format(EP_MIN)
805 message += "==> Impossible de créer la face médiane car le solide est trop mince.\n"
807 self.d_statut_so[self.nom_solide] = 2
808 self.faces_pb_nb += 1
809 self.faces_pb_msg += message
813 #print ("erreur = {}".format(erreur))
817 #=========================== Fin de la méthode ==================================
819 #=========================== Début de la méthode =================================
821 def _cree_face_mediane ( self, solide, caract_face_1, caract_face_2, n_recur ):
822 """Crée la face médiane entre deux autres
825 :solide: solide SHAPER à traiter
826 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
827 :n_recur: niveau de récursivité
830 :face: la face médiane créée
833 nom_fonction = __name__ + "/_cree_face_mediane"
834 blabla = "Dans {} :".format(nom_fonction)
836 if self._verbose_max:
837 print_tab (n_recur, blabla)
838 print_tab (n_recur, "face_1 : " ,caract_face_1)
839 print_tab (n_recur, "face_2 : " ,caract_face_2)
844 # 1. Forme de la face
845 forme = caract_face_1[2][0]
847 # 2. Traitement selon la forme de la face
849 if forme in ( "Disk" , "Plane", "Rectangle"):
850 erreur, face = self._cree_face_mediane_plane ( solide, caract_face_1, caract_face_2, n_recur )
852 # 2.2. Face cylindrique
853 elif ( forme == "Cylinder" ):
854 erreur, face = self._cree_face_mediane_cylindre ( solide, caract_face_1, caract_face_2, n_recur )
856 # 2.3. Face sphérique
857 elif ( forme == "Sphere" ):
858 erreur, face = self._cree_face_mediane_sphere ( caract_face_1, caract_face_2, n_recur )
861 elif ( forme == "Torus" ):
862 erreur, face = self._cree_face_mediane_tore ( caract_face_1, caract_face_2, n_recur )
865 elif ( forme == "Cone" ):
866 erreur, face = self._cree_face_mediane_cone ( caract_face_1, caract_face_2, n_recur )
868 # 2.N. Face de forme inconnue
870 message = "\nSolide '{}'\n".format(self.nom_solide)
871 message += "sa face la plus grande est de forme : {}\n".format(forme)
872 message += "==> Impossible de créer la face médiane.\n"
874 self.d_statut_so[self.nom_solide] = -2
875 self.faces_pb_nb += 1
876 self.faces_pb_msg += message
878 # 3. Gestion de la face produite
881 self._cree_face_mediane_0 ( face, n_recur )
883 if self._verbose_max:
884 print_tab (n_recur, "Sortie de "+blabla)
888 #=========================== Fin de la méthode ==================================
890 #=========================== Début de la méthode =================================
892 def _cree_face_mediane_0 ( self, face, n_recur ):
893 """Gestion de la face médiane créée entre deux autres
896 :face: la face médiane créée
897 :n_recur: niveau de récursivité
900 nom_fonction = __name__ + "/_cree_face_mediane_0"
901 blabla = "Dans {} :".format(nom_fonction)
903 if self._verbose_max:
904 print_tab (n_recur, blabla)
907 nom_face = self.nom_solide+"_M"
908 if self._verbose_max:
909 print_tab (n_recur,"Nom de la face créée : ", nom_face)
910 #if ( self.nom_solide_aux != self.objet_principal.name() ):
912 nommage (face, nom_face)
914 # 2. Mémorisation de la face et de la fonction initiale
915 self.l_faces_m.append((face, self.fonction_0))
917 # 3. Couleur verte pour la face
918 couleur_objet (face, coul_r=0, coul_g=170, coul_b=0, verbose=self._verbose_max)
920 # 4. Changement de statut pour le solide
921 self.d_statut_so[self.nom_solide] = 1
923 if self._verbose_max:
924 print_tab (n_recur, "Sortie de _cree_face_mediane_0")
926 #=========================== Fin de la méthode ==================================
928 #=========================== Début de la méthode =================================
930 def _cree_face_mediane_plane ( self, solide, caract_face_1, caract_face_2, n_recur ):
931 """Crée la face médiane entre deux autres - cas des surfaces planes
934 :solide: l'objet solide à traiter
935 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
936 :n_recur: niveau de récursivité
939 :face: la face médiane
942 nom_fonction = __name__ + "/_cree_face_mediane_plane"
943 blabla = "Dans {} :".format(nom_fonction)
944 if self._verbose_max:
945 print_tab (n_recur, blabla)
947 # Caractéristiques des surfaces
948 coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2 = self._cree_face_mediane_plane_0 ( solide, caract_face_1, caract_face_2, n_recur )
950 # Contrôle de la validité de l'épaisseur
951 erreur = self._verif_epaisseur ( d_face_1_2 )
953 # Création de la face
955 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 )
961 #=========================== Fin de la méthode ==================================
963 #=========================== Début de la méthode =================================
965 def _cree_face_mediane_plane_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
966 """Crée la face médiane entre deux autres - cas des surfaces planes
968 Décodage des caractéristiques
971 :solide: l'objet solide à traiter
972 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
973 :n_recur: niveau de récursivité
976 :coo_x, coo_y, coo_z: coordonnées du centre de la base
977 :vnor_x, vnor_y, vnor_z: coordonnées du vecteur normal
978 :taille: estimation de la taille de la future face
979 :d_face_1_2: la distance entre les deux faces
982 nom_fonction = __name__ + "/_cree_face_mediane_plane_0"
983 blabla = "Dans {} :".format(nom_fonction)
985 if self._verbose_max:
986 print_tab (n_recur, blabla)
987 print_tab (n_recur, "caract_face_1 : ", caract_face_1)
988 print_tab (n_recur, "caract_face_2 : ", caract_face_2)
990 # 1. Caractéristiques de la base
991 # Coordonnées du centre de la base
992 coo_x = caract_face_1[2][1]
993 coo_y = caract_face_1[2][2]
994 coo_z = caract_face_1[2][3]
995 # Coordonnées du vecteur normal
996 vnor_x = caract_face_1[2][4]
997 vnor_y = caract_face_1[2][5]
998 vnor_z = caract_face_1[2][6]
999 # taille : une longueur caractéristique pour être certain de tout prendre
1000 l_diag = self._calcul_lg_caract ( solide, n_recur )
1002 if self._verbose_max:
1003 print_tab (n_recur, "Taille englobante : ",taille)
1005 # 2. Distance entre les deux faces
1006 face_1 = caract_face_1[0]
1007 face_2 = caract_face_2[0]
1008 d_face_1_2 = GeomAlgoAPI_ShapeTools.minimalDistance(face_1, face_2)
1009 if self._verbose_max:
1010 print_tab (n_recur, "Distance entre les deux faces = ", d_face_1_2)
1012 return coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2
1014 #=========================== Fin de la méthode ==================================
1016 #=========================== Début de la méthode =================================
1018 def _cree_face_mediane_plane_1 ( self, solide, coo_c, vnor, taille, d_face_1_2, n_recur ):
1019 """Crée la face médiane entre deux autres - cas des surfaces planes
1021 Création des objets de construction et de la face médiane
1024 :solide: l'objet solide à traiter
1025 :coo_c: coordonnées du centre de la base
1026 :vnor: coordonnées du vecteur normal
1027 :taille: estimation de la taille de la future face
1028 :d_face_1_2: la distance entre les deux faces
1029 :n_recur: niveau de récursivité
1032 :face: la face médiane
1035 nom_fonction = __name__ + "/_cree_face_mediane_plane_1"
1036 blabla = "Dans {} :".format(nom_fonction)
1037 if self._verbose_max:
1038 print_tab (n_recur, blabla)
1039 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1040 print_tab (n_recur, "Normale : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
1041 print_tab (n_recur, "Taille : ", taille)
1042 print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1045 _, v_norm, plan = self._cree_centre_axe_plan ( coo_c, vnor, self.nom_solide, n_recur )
1047 # 2. Création de l'esquisse
1048 sketch = self._cree_face_mediane_plane_1_a ( plan, taille, n_recur )
1051 face = self._cree_face_mediane_plane_1_b ( solide, sketch, v_norm, d_face_1_2, n_recur )
1053 #print ("fin de {}".format(nom_fonction))
1057 #=========================== Fin de la méthode ==================================
1059 #=========================== Début de la méthode =================================
1061 def _cree_face_mediane_plane_1_a ( self, plan, taille, n_recur ):
1062 """Crée la face médiane entre deux autres - cas des surfaces planes - l'esquisse
1066 :taille: estimation de la taille de la future face
1067 :n_recur: niveau de récursivité
1073 nom_fonction = __name__ + "/_cree_face_mediane_plane_1_a"
1074 blabla = "Dans {} :".format(nom_fonction)
1075 if self._verbose_max:
1076 print_tab (n_recur, blabla)
1077 print_tab (n_recur, "Plan : {}".format(plan.name()))
1078 print_tab (n_recur, "taille : {}".format(taille))
1080 sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
1081 sketch.execute(True)
1083 ### Create SketchLine
1084 SketchLine_1 = sketch.addLine(-taille/2., taille/2., taille/2., taille/2.)
1085 SketchLine_1.execute(True)
1087 ### Create SketchLine
1088 SketchLine_2 = sketch.addLine(taille/2., taille/2., taille/2., -taille/2.)
1089 SketchLine_2.execute(True)
1091 ### Create SketchLine
1092 SketchLine_3 = sketch.addLine(taille/2., -taille/2., -taille/2., -taille/2.)
1093 SketchLine_3.execute(True)
1095 ### Create SketchLine
1096 SketchLine_4 = sketch.addLine(-taille/2., -taille/2., -taille/2., taille/2.)
1097 SketchLine_4.execute(True)
1101 nom_sketch = "{}_esquisse".format(self.nom_solide)
1102 exec_nom (sketch,nom_sketch)
1104 #print ("fin de {}".format(nom_fonction))
1108 #=========================== Fin de la méthode ==================================
1110 #=========================== Début de la méthode =================================
1112 def _cree_face_mediane_plane_1_b ( self, solide, sketch, v_norm, d_face_1_2, n_recur ):
1113 """Crée la face médiane entre deux autres - cas des surfaces planes
1115 Création de la face médiane
1118 :solide: l'objet solide à traiter
1120 :v_norm: vecteur normal
1121 :d_face_1_2: la distance entre les deux faces
1122 :n_recur: niveau de récursivité
1125 :face: la face médiane
1128 nom_fonction = __name__ + "/_cree_face_mediane_plane_1_b"
1129 blabla = "Dans {} :".format(nom_fonction)
1130 if self._verbose_max:
1131 print_tab (n_recur, blabla)
1132 print_tab (n_recur, "Esquisse : ", sketch.name())
1133 print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
1135 # 1. Copie du solide pour gérer les intersections
1136 #Copy_1 = model.addCopy(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(self.nom_solide_aux))], 1)
1137 Copy_1 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", self.nom_solide_aux)], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
1138 nom = "{}_Copy_1".format(self.nom_solide_aux)
1139 exec_nom (Copy_1,nom)
1140 if self._verbose_max:
1141 print_tab (n_recur, "Après addMultiTranslation Copy_1 de nom ", nom)
1142 nom_solide = Copy_1.result().name()
1145 Recover_1 = model.addRecover(self.part_doc, Copy_1, [solide])
1146 nom = "{}_Recover_1".format(self.nom_solide_aux)
1147 exec_nom (Recover_1,nom)
1148 if self._verbose_max:
1149 print_tab (n_recur, "Après addRecover Recover_1 de nom ", nom)
1151 # 2. Création d'une face ; on la translate d'une demi-épaisseur.
1152 for iaux in range(2):
1154 # 2.1. Création d'une face à partir du sketch et translation perpendiculaire au plan de la face
1155 # On essaie les 2 côtés alternativement car on ne sait pas lequel sera le bon
1157 d_trans = -0.5*d_face_1_2*float(2*iaux-1)
1159 face = self._cree_face_mediane_plane_2 ( sketch.name(), v_norm.name(), nom_solide, d_trans, iaux, n_recur )
1161 # 2.2. Si on est du bon côté, alors on intersecte la face avec le solide et c'est bon
1163 face = self._cree_face_mediane_plane_11 ( face, Recover_1, n_recur )
1166 # 2.3. Si l'intersection est vide, on crée une nouvelle copie du solide avant de tester l'autre côté
1168 if self._verbose_max:
1169 print_tab (n_recur, "L'intersection est vide. On essaie l'autre côté")
1171 ### Create LinearCopy
1172 #Copy_2 = model.addCopy(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(self.nom_solide_aux))], 1)
1173 Copy_2 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", Recover_1.result().name())], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
1174 nom = "{}_Copy_2".format(self.nom_solide_aux)
1175 exec_nom (Copy_2,nom)
1176 if self._verbose_max:
1177 print_tab (n_recur, "Après addMultiTranslation Copy_2 de nom ", nom)
1178 nom_solide = Copy_2.result().name()
1180 #print ("fin de {}".format(nom_fonction))
1184 #=========================== Fin de la méthode ==================================
1186 #=========================== Début de la méthode =================================
1188 def _cree_face_mediane_plane_11 ( self, face, Recover_1, n_recur ):
1189 """Crée la face médiane entre deux autres - cas des surfaces planes
1191 Création des objets de construction et de la face médiane
1194 :face: la face médiane
1195 :Recover_1: la récupératiuon du solide
1196 :n_recur: niveau de récursivité
1199 :face: la face médiane
1202 nom_fonction = __name__ + "/_cree_face_mediane_plane_11"
1203 blabla = "Dans {} :".format(nom_fonction)
1204 if self._verbose_max:
1205 print_tab (n_recur, blabla)
1206 print_tab (n_recur, "face : ", face.name())
1208 # Si on traite un objet solide unique, on le récupère
1209 if ( self.nom_solide_aux == self.objet_principal.name() ):
1210 if self._verbose_max:
1211 print_tab (n_recur, "On traite un objet solide unique ==> on le récupère.")
1212 Recover_2 = model.addRecover(self.part_doc, face, [Recover_1.result()])
1213 nom = "{}_Recover_2".format(self.nom_solide_aux)
1214 exec_nom (Recover_2,nom)
1216 nb_inter = face.result().numberOfSubs()
1217 if self._verbose_max:
1218 print_tab (n_recur, "Nombre d'intersections : ", nb_inter)
1221 face = self._cree_face_mediane_plane_3 ( face )
1225 #=========================== Fin de la méthode ==================================
1227 #=========================== Début de la méthode =================================
1229 def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, d_trans, icpt, n_recur ):
1230 """Crée la face médiane entre deux autres - cas des surfaces planes
1232 Intersection de la face avec le solide
1235 :nom_sketch: nom de l'esquisse
1236 :nom_normal: nom du vecteur normal
1237 :nom_solide: nom du solide à intersecter
1238 :d_trans: la distance de translation
1239 :icpt: numéro de la tentative
1242 :face: la face médiane
1245 nom_fonction = __name__ + "/_cree_face_mediane_plane_2"
1246 blabla = "Dans {} :".format(nom_fonction)
1247 if self._verbose_max:
1248 print_tab (n_recur, blabla)
1249 print_tab (n_recur, "nom_sketch : ", nom_sketch)
1250 print_tab (n_recur, "nom_normal : ", nom_normal)
1251 print_tab (n_recur, "nom_solide : ", nom_solide)
1252 print_tab (n_recur, "d_trans : ", d_trans)
1254 # Création d'une face
1255 Face_1 = model.addFace(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(nom_sketch))])
1256 nom = "{}_Face_1_{}".format(self.nom_solide_aux,icpt)
1257 exec_nom (Face_1,nom)
1258 if self._verbose_max:
1259 print_tab (n_recur, "Après addFace pour Face_1 de nom ", nom)
1262 Translation_1 = model.addTranslation(self.part_doc, [model.selection("FACE", Face_1.result().name())], axis = model.selection("EDGE", nom_normal), distance = d_trans, keepSubResults = True)
1263 nom = "{}_trans_{}".format(self.nom_solide_aux,icpt)
1264 exec_nom (Translation_1,nom)
1265 if self._verbose_max:
1266 print_tab (n_recur, "Après addTranslation pour Translation_1 de nom ", nom)
1267 Translation_1.result().setColor(85, 0, 255)
1269 # Intersection de cette face avec le solide initial
1270 face = self._creation_face_inter ( Translation_1.result().name(), nom_solide )
1274 #=========================== Fin de la méthode ==================================
1276 #=========================== Début de la méthode =================================
1278 def _cree_face_mediane_plane_3 ( self, face ):
1279 """Crée la face médiane entre deux autres - cas des surfaces planes
1281 Fusion des 2 intersections
1284 :face: la face médiane composée de plusieurs intersections
1287 :face_m: la face médiane
1290 nom_fonction = __name__ + "/_cree_face_mediane_plane_3"
1291 blabla = "Dans {} :\n".format(nom_fonction)
1292 if self._verbose_max:
1296 # Nommage des sous-objets
1298 for iaux in range(face.result().numberOfSubs()):
1299 nom = "{}_common_{}".format(self.nom_solide_aux,iaux)
1300 face.result().subResult(iaux).setName(nom)
1301 l_fuse.append(model.selection("FACE", '{}'.format(nom)))
1304 if self._verbose_max:
1305 print ("Fusion de {} faces.".format(len(l_fuse)))
1306 face_m = model.addFuse(self.part_doc, l_fuse, keepSubResults = True)
1307 face_m.execute(True)
1311 #=========================== Fin de la méthode ==================================
1313 #=========================== Début de la méthode =================================
1315 def _cree_face_mediane_cylindre ( self, solide, caract_face_1, caract_face_2, n_recur ):
1316 """Crée la face médiane entre deux autres - cas des cylindres
1319 :solide: solide SHAPER à traiter
1320 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1321 :n_recur: niveau de récursivité
1324 :face: la face médiane
1327 nom_fonction = __name__ + "/_cree_face_mediane_cylindre"
1328 blabla = "Dans {} :".format(nom_fonction)
1331 if self._verbose_max:
1332 print_tab (n_recur, blabla)
1333 print_tab (n_recur, "face_1 : ", caract_face_1)
1334 print_tab (n_recur, "face_2 : ", caract_face_2)
1336 # Caractéristiques des cylindres
1337 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur = self._cree_face_mediane_cylindre_0 ( solide, caract_face_1, caract_face_2, n_recur )
1339 # Contrôle de la validité de l'épaisseur
1340 erreur = self._verif_epaisseur ( epaisseur )
1342 # Création de la face, de couleur bleue si problème
1344 face = self._cree_face_mediane_cylindre_1 ( (coo_x, coo_y, coo_z), (axe_x, axe_y, axe_z), rayon, hauteur, n_recur )
1346 couleur_objet (solide, n_recur, coul_r=0, coul_g=0, coul_b=255, verbose=self._verbose_max)
1351 #=========================== Fin de la méthode ==================================
1353 #=========================== Début de la méthode =================================
1355 def _cree_face_mediane_cylindre_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
1356 """Crée la face médiane entre deux autres - cas des cylindres
1358 Décodage des caractéristiques
1361 :solide: l'objet solide à traiter
1362 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1363 :n_recur: niveau de récursivité
1366 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1367 :axe_x, axe_y, axe_z: coordonnées de l'axe
1368 :rayon: rayon moyen entre les deux faces
1369 :hauteur: hauteur du cylindre
1370 :epaisseur: épaisseur de l'interface entre les deux faces
1373 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_0"
1374 blabla = "Dans {} :".format(nom_fonction)
1376 if self._verbose_max:
1377 print_tab (n_recur, blabla)
1378 print_tab (n_recur, "face_1 : ", caract_face_1)
1379 print_tab (n_recur, "face_2 : ", caract_face_2)
1381 # Coordonnées du centre de la base
1382 coo_x = caract_face_1[2][1]
1383 coo_y = caract_face_1[2][2]
1384 coo_z = caract_face_1[2][3]
1385 # Coordonnées de l'axe
1386 axe_x = caract_face_1[2][4]
1387 axe_y = caract_face_1[2][5]
1388 axe_z = caract_face_1[2][6]
1390 rayon = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1391 # Hauteur : une longueur caractéristique pour être certain de tout prendre
1392 l_diag = self._calcul_lg_caract ( solide, n_recur )
1393 hauteur = 10.*l_diag
1394 if self._verbose_max:
1395 print_tab (n_recur, "Hauteur englobante : ", hauteur)
1397 epaisseur = np.abs(caract_face_2[2][7]-caract_face_1[2][7])
1399 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur
1401 #=========================== Fin de la méthode ==================================
1403 #=========================== Début de la méthode =================================
1405 def _cree_face_mediane_cylindre_1 ( self, coo_c, v_axe, rayon, hauteur, n_recur ):
1406 """Crée la face médiane entre deux autres - cas des cylindres
1408 Création des objets temporaires et de la face externe du cylindre support
1411 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1412 :axe_x, axe_y, axe_z: coordonnées de l'axe
1413 :rayon: rayon moyen entre les deux faces
1414 :hauteur: hauteur du cylindre
1415 :n_recur: niveau de récursivité
1418 :face: la face médiane
1420 nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1"
1421 blabla = "Dans {} :\n".format(nom_fonction)
1423 # Les caractéristiques du cylindre à créer
1424 if self._verbose_max:
1425 print_tab (n_recur, blabla)
1426 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
1427 print_tab (n_recur, "Axe : ({}, {}, {})".format(v_axe[0], v_axe[1], v_axe[2]))
1428 print_tab (n_recur, "Rayon : ", rayon)
1429 print_tab (n_recur, "Hauteur : ", hauteur)
1431 # Création du point central
1432 centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
1433 nom_centre = "{}_centre".format(self.nom_solide)
1434 exec_nom (centre,nom_centre)
1435 if self.fonction_0 is None:
1436 self.fonction_0 = centre
1438 # Création du vecteur axial
1439 axe = model.addAxis(self.part_doc, v_axe[0], v_axe[1], v_axe[2])
1440 nom_axe = "{}_vecteur".format(self.nom_solide)
1441 exec_nom (axe,nom_axe)
1443 # Création du cylindre en volume, de rayon médian
1444 Cylinder_1 = model.addCylinder(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("EDGE", nom_axe), rayon, hauteur)
1445 nom = "{}_Cylinder_1".format(self.nom_solide)
1446 exec_nom (Cylinder_1,nom)
1448 # Le groupe de la surface
1449 Group_1 = model.addGroup(self.part_doc, "Faces", [model.selection("FACE", "{}/Face_1".format(nom))])
1450 nom = "{}_Group_1".format(self.nom_solide)
1451 exec_nom (Group_1,nom)
1453 # Création du cylindre en surface
1454 cylindre = model.addGroupShape(self.part_doc, [model.selection("COMPOUND", nom)])
1455 nom = "{}_cylindre".format(self.nom_solide)
1456 exec_nom (cylindre, nom, (85, 0, 255))
1459 Translation_1 = model.addTranslation(self.part_doc, [model.selection("COMPOUND", nom)], axis = model.selection("EDGE", nom_axe), distance = -0.5*hauteur, keepSubResults = True)
1460 nom = "{}_Translation_1".format(self.nom_solide)
1461 exec_nom (Translation_1,nom)
1463 # Intersection de la face cylindrique avec le solide initial
1464 face = self._creation_face_inter ( nom )
1468 #=========================== Fin de la méthode ==================================
1470 #=========================== Début de la méthode =================================
1472 def _cree_face_mediane_sphere ( self, caract_face_1, caract_face_2, n_recur ):
1473 """Crée la face médiane entre deux autres - cas des sphères
1476 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1477 :n_recur: niveau de récursivité
1480 :face: la face médiane
1483 nom_fonction = __name__ + "/_cree_face_mediane_sphere"
1484 blabla = "Dans {} :".format(nom_fonction)
1487 if self._verbose_max:
1488 print_tab (n_recur, blabla)
1489 print_tab (n_recur, "face_1 : ", caract_face_1)
1490 print_tab (n_recur, "face_2 : ", caract_face_2)
1492 # Caractéristiques des sphères
1493 coo_x, coo_y, coo_z, rayon, epaisseur = self._cree_face_mediane_sphere_0 ( caract_face_1, caract_face_2, n_recur )
1495 # Contrôle de la validité de l'épaisseur
1496 erreur = self._verif_epaisseur ( epaisseur )
1498 # Création de la face
1500 face = self._cree_face_mediane_sphere_1 ( coo_x, coo_y, coo_z, rayon )
1506 #=========================== Fin de la méthode ==================================
1508 #=========================== Début de la méthode =================================
1510 def _cree_face_mediane_sphere_0 ( self, caract_face_1, caract_face_2, n_recur ):
1511 """Crée la face médiane entre deux autres - cas des sphères
1513 Décodage des caractéristiques
1516 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1517 :n_recur: niveau de récursivité
1520 :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1521 :rayon: rayon moyen entre les deux faces
1522 :epaisseur: épaisseur de l'interface entre les deux faces
1525 nom_fonction = __name__ + "/_cree_face_mediane_sphere_0"
1526 blabla = "Dans {} :".format(nom_fonction)
1529 if self._verbose_max:
1530 print_tab (n_recur, blabla)
1531 print_tab (n_recur, "face_1 : ", caract_face_1)
1532 print_tab (n_recur, "face_2 : ", caract_face_2)
1534 # Coordonnées du centre de la sphère
1535 coo_x = caract_face_1[2][1]
1536 coo_y = caract_face_1[2][2]
1537 coo_z = caract_face_1[2][3]
1539 rayon = (caract_face_2[2][4]+caract_face_1[2][4])/2.
1541 epaisseur = np.abs(caract_face_2[2][4]-caract_face_1[2][4])
1543 return coo_x, coo_y, coo_z, rayon, epaisseur
1545 #=========================== Fin de la méthode ==================================
1547 #=========================== Début de la méthode =================================
1549 def _cree_face_mediane_sphere_1 ( self, coo_x, coo_y, coo_z, rayon ):
1550 """Crée la face médiane entre deux autres - cas des sphères
1552 Création des objets de construction et de la face externe de la sphère support
1555 :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
1556 :rayon: rayon moyen entre les deux faces
1559 :face: la face externe de la sphère support
1562 nom_fonction = __name__ + "/_cree_face_mediane_sphere_1"
1563 blabla = "Dans {} :\n".format(nom_fonction)
1565 # Les caractéristiques de la sphère à créer
1566 if self._verbose_max:
1568 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1569 texte += "Rayon : {}".format(rayon)
1572 # Création du point central
1573 centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1574 nom_centre = "{}_centre".format(self.nom_solide)
1575 exec_nom (centre,nom_centre)
1576 if self.fonction_0 is None:
1577 self.fonction_0 = centre
1579 # Création de la sphère en volume, de rayon médian
1580 Sphere_1 = model.addSphere(self.part_doc, model.selection("VERTEX", nom_centre), rayon)
1581 nom = "{}_Sphere_1".format(self.nom_solide)
1582 exec_nom (Sphere_1,nom)
1584 # Le groupe de la surface
1585 Group_1 = model.addGroup(self.part_doc, "Faces", [model.selection("FACE", "{}/Face_1".format(nom))])
1586 nom = "{}_Group_1".format(self.nom_solide)
1587 exec_nom (Group_1,nom)
1589 # Création de la sphère en surface
1590 sphere = model.addGroupShape(self.part_doc, [model.selection("COMPOUND", nom)])
1592 nom = "{}_sphere".format(self.nom_solide)
1593 exec_nom (sphere, nom, (85, 0, 255))
1595 # Intersection de la face sphérique avec le solide initial
1596 face = self._creation_face_inter ( nom )
1600 #=========================== Fin de la méthode ==================================
1602 #=========================== Début de la méthode =================================
1604 def _cree_face_mediane_tore ( self, caract_face_1, caract_face_2, n_recur ):
1605 """Crée la face médiane entre deux autres - cas des tores
1608 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1609 :n_recur: niveau de récursivité
1612 :face: la face médiane
1615 nom_fonction = __name__ + "/_cree_face_mediane_tore"
1616 blabla = "Dans {} :".format(nom_fonction)
1619 if self._verbose_max:
1620 print_tab (n_recur, blabla)
1621 print_tab (n_recur, "face_1 : ", caract_face_1)
1622 print_tab (n_recur, "face_2 : ", caract_face_2)
1624 # Caractéristiques des tores
1625 coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 = self._cree_face_mediane_tore_0 ( caract_face_1, caract_face_2, n_recur )
1627 # Contrôle de la validité de l'épaisseur (bidon)
1628 erreur = self._verif_epaisseur ( EP_MIN*10. )
1630 # Création de la face
1632 face = self._cree_face_mediane_tore_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 )
1638 #=========================== Fin de la méthode ==================================
1640 #=========================== Début de la méthode =================================
1642 def _cree_face_mediane_tore_0 ( self, caract_face_1, caract_face_2, n_recur ):
1643 """Crée la face médiane entre deux autres - cas des tores
1645 Décodage des caractéristiques
1648 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1649 :n_recur: niveau de récursivité
1652 :coo_x, coo_y, coo_z: coordonnées du centre du tore
1653 :axe_x, axe_y, axe_z: coordonnées de l'axe
1654 :rayon_1 : rayon principal
1655 :rayon_2 : rayon secondaire
1658 nom_fonction = __name__ + "/_cree_face_mediane_tore_0"
1659 blabla = "Dans {} :".format(nom_fonction)
1662 if self._verbose_max:
1663 print_tab (n_recur, blabla)
1664 print_tab (n_recur, "face_1 : ", caract_face_1)
1665 print_tab (n_recur, "face_2 : ", caract_face_2)
1667 # Coordonnées du centre du tore
1668 coo_x = caract_face_1[2][1]
1669 coo_y = caract_face_1[2][2]
1670 coo_z = caract_face_1[2][3]
1671 # Coordonnées de l'axe
1672 axe_x = caract_face_1[2][4]
1673 axe_y = caract_face_1[2][5]
1674 axe_z = caract_face_1[2][6]
1676 rayon_1 = caract_face_2[2][7]
1677 rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1679 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2
1681 #=========================== Fin de la méthode ==================================
1683 #=========================== Début de la méthode =================================
1685 def _cree_face_mediane_tore_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 ):
1686 """Crée la face médiane entre deux autres - cas des tores
1688 Création des objets de construction et de la face externe du tore support
1691 :coo_x, coo_y, coo_z: coordonnées du centre du tore
1692 :axe_x, axe_y, axe_z: coordonnées de l'axe
1693 :rayon_1 : rayon principal
1694 :rayon_2 : rayon secondaire
1697 :face: la face externe du tore support
1700 nom_fonction = __name__ + "/_cree_face_mediane_tore_1"
1701 blabla = "Dans {} :\n".format(nom_fonction)
1704 if self._verbose_max:
1706 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1707 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1708 texte += "Rayon principal : {}\n".format(rayon_1)
1709 texte += "Rayon secondaire : {}".format(rayon_2)
1712 # Création du point central
1713 centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1714 nom_centre = "{}_centre".format(self.nom_solide)
1715 exec_nom (centre,nom_centre)
1718 axe = model.addAxis(self.part_doc, axe_x, axe_y, axe_z)
1719 nom_axe = "{}_axe".format(self.nom_solide)
1720 exec_nom (axe,nom_axe)
1722 # Création d'un plan passant par ce centre et cet axe
1723 plan = model.addPlane(self.part_doc, model.selection("EDGE", nom_axe), model.selection("VERTEX", nom_centre), False)
1724 nom_plan = "{}_plan".format(self.nom_solide)
1725 exec_nom (plan,nom_plan)
1727 # Création de l'esquisse
1728 nom_par_1 = "{}_R_1".format(self.nom_solide)
1729 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1730 nom_par_2 = "{}_R_2".format(self.nom_solide)
1731 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1733 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1734 sketch.execute(True)
1736 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
1737 SketchProjection_1.execute(True)
1738 SketchPoint_1 = SketchProjection_1.createdFeature()
1739 SketchPoint_1.execute(True)
1741 SketchProjection_2 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
1742 SketchProjection_2.execute(True)
1743 SketchLine_1 = SketchProjection_2.createdFeature()
1744 SketchLine_1.execute(True)
1746 SketchPoint_2 = sketch.addPoint(rayon_1, 0.)
1747 SketchPoint_2.execute(True)
1748 sketch.setDistance(SketchPoint_1.result(), SketchPoint_2.coordinates(), nom_par_1, True)
1750 SketchLine_2 = sketch.addLine(0., 0., rayon_1, 0.)
1751 SketchLine_2.execute(True)
1752 SketchLine_2.setAuxiliary(True)
1753 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.startPoint())
1754 sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_2.endPoint())
1755 sketch.setPerpendicular(SketchLine_1.result(), SketchLine_2.result())
1757 SketchCircle_1 = sketch.addCircle(0., 0., rayon_2)
1758 SketchCircle_1.execute(True)
1759 sketch.setCoincident(SketchPoint_2.result(), SketchCircle_1.center())
1760 sketch.setRadius(SketchCircle_1.results()[1], nom_par_2)
1764 nom_sketch = "{}_esquisse".format(self.nom_solide)
1765 exec_nom (sketch,nom_sketch)
1767 # Création du tore complet
1768 nom_tore = "{}_tore".format(self.nom_solide)
1769 self._cree_revolution ( nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_tore )
1771 # Intersection de la face torique avec le solide initial
1772 face = self._creation_face_inter ( nom_tore )
1776 #=========================== Fin de la méthode ==================================
1778 #=========================== Début de la méthode =================================
1780 def _cree_face_mediane_cone ( self, caract_face_1, caract_face_2, n_recur ):
1781 """Crée la face médiane entre deux autres - cas des cones
1784 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1785 :n_recur: niveau de récursivité
1788 :face: la face médiane
1791 nom_fonction = __name__ + "/_cree_face_mediane_cone"
1792 blabla = "Dans {} :".format(nom_fonction)
1795 if self._verbose_max:
1796 print_tab (n_recur, blabla)
1797 print_tab (n_recur, "face_1 : ", caract_face_1)
1798 print_tab (n_recur, "face_2 : ", caract_face_2)
1800 # Caractéristiques des cones
1801 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 )
1803 # Contrôle de la validité de l'épaisseur (bidon)
1804 erreur = self._verif_epaisseur ( EP_MIN*10. )
1806 # Création de la face
1808 face = self._cree_face_mediane_cone_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur )
1814 #=========================== Fin de la méthode ==================================
1816 #=========================== Début de la méthode =================================
1818 def _cree_face_mediane_cone_0 ( self, caract_face_1, caract_face_2, n_recur ):
1819 """Crée la face médiane entre deux autres - cas des cones
1821 Décodage des caractéristiques
1824 :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
1825 :n_recur: niveau de récursivité
1828 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1829 :axe_x, axe_y, axe_z: coordonnées de l'axe
1830 :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1831 :hauteur: hauteur du cone
1834 nom_fonction = __name__ + "/_cree_face_mediane_cone_0"
1835 blabla = "Dans {} :".format(nom_fonction)
1838 if self._verbose_max:
1839 print_tab (n_recur, blabla)
1840 print_tab (n_recur, "face_1 : ", caract_face_1)
1841 print_tab (n_recur, "face_2 : ", caract_face_2)
1843 # Coordonnées du centre de la base
1844 coo_x = caract_face_1[2][1]
1845 coo_y = caract_face_1[2][2]
1846 coo_z = caract_face_1[2][3]
1847 # Coordonnées de l'axe
1848 axe_x = caract_face_1[2][4]
1849 axe_y = caract_face_1[2][5]
1850 axe_z = caract_face_1[2][6]
1852 rayon_1 = (caract_face_2[2][7]+caract_face_1[2][7])/2.
1853 rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
1855 hauteur = caract_face_1[2][9]
1858 if self._verbose_max:
1859 print_tab (n_recur, "coo_x : ", coo_x)
1860 print_tab (n_recur, "coo_y : ", coo_y)
1861 print_tab (n_recur, "coo_z : ", coo_z)
1862 print_tab (n_recur, "axe_x : ", axe_x)
1863 print_tab (n_recur, "axe_y : ", axe_y)
1864 print_tab (n_recur, "axe_z : ", axe_z)
1865 print_tab (n_recur, "rayon_1 : ", rayon_1)
1866 print_tab (n_recur, "rayon_2 : ", rayon_2)
1867 print_tab (n_recur, "hauteur : ", hauteur)
1869 return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur
1871 #=========================== Fin de la méthode ==================================
1873 #=========================== Début de la méthode =================================
1875 def _cree_face_mediane_cone_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur ):
1876 """Crée la face médiane entre deux autres - cas des cones
1878 Création des objets de construction et de la face externe du cone support
1881 :coo_x, coo_y, coo_z: coordonnées du centre de la base
1882 :axe_x, axe_y, axe_z: coordonnées de l'axe
1883 :rayon_1, rayon_2: rayons moyens du côté de la base et à l'opposé
1884 :hauteur: hauteur du cone
1887 :face: la face externe du cone support
1889 nom_fonction = __name__ + "/_cree_face_mediane_cone_1"
1890 blabla = "Dans {} :\n".format(nom_fonction)
1893 if self._verbose_max:
1895 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
1896 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
1897 texte += "Rayons : {}, {}\n".format(rayon_1, rayon_2)
1898 texte += "Hauteur : {}".format(hauteur)
1901 # 1. Création du point central de la base, côté rayon_1
1902 centre_1 = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
1903 nom_centre_1 = "{}_centre_1".format(self.nom_solide)
1904 exec_nom (centre_1,nom_centre_1)
1906 # 2. Création du point central, du côté de rayon_2
1907 centre_2 = model.addPoint(self.part_doc, coo_x+hauteur*axe_x, coo_y+hauteur*axe_y, coo_z+hauteur*axe_z)
1908 nom_centre_2 = "{}_centre_2".format(self.nom_solide)
1909 exec_nom (centre_2,nom_centre_2)
1911 # 3. Création de l'axe
1912 axe = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre_1), model.selection("VERTEX", nom_centre_2))
1913 nom_axe = "{}_axe".format(self.nom_solide)
1914 exec_nom (axe,nom_axe)
1916 # 4. Création d'un plan passant par le centre de la base et l'axe
1917 # 4.1. Création d'un vecteur perpendiculaire à l'axe
1919 v_perp = model.addAxis(self.part_doc, -coeff*axe_y, coeff*axe_x, 0.)
1920 nom_v_perp = "{}_v_perp".format(self.nom_solide)
1921 exec_nom (v_perp,nom_v_perp)
1922 # 4.2. Création du plan
1923 plan = model.addPlane(self.part_doc, model.selection("EDGE",nom_v_perp), model.selection("VERTEX", nom_centre_1), True)
1924 nom_plan = "{}_plan".format(self.nom_solide)
1925 exec_nom (plan,nom_plan)
1928 nom_par_1 = "{}_R_1".format(self.nom_solide)
1929 model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
1930 nom_par_2 = "{}_R_2".format(self.nom_solide)
1931 model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
1932 nom_par_3 = "{}_H".format(self.nom_solide)
1933 model.addParameter(self.part_doc, "{}".format(nom_par_3), "{}".format(hauteur))
1935 # 6. Création de l'esquisse
1937 sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
1938 sketch.execute(True)
1940 # 6.1. Projection des centres et de l'axe
1941 SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre_1), False)
1942 SketchProjection_1.execute(True)
1943 SketchPoint_1 = SketchProjection_1.createdFeature()
1944 SketchPoint_1.execute(True)
1945 sk_coo_x_1 = SketchAPI_Point(SketchPoint_1).coordinates().x()
1946 sk_coo_y_1 = SketchAPI_Point(SketchPoint_1).coordinates().y()
1948 SketchProjection_2 = sketch.addProjection(model.selection("VERTEX", nom_centre_2), False)
1949 SketchProjection_2.execute(True)
1950 SketchPoint_2 = SketchProjection_2.createdFeature()
1951 SketchPoint_2.execute(True)
1952 sk_coo_x_2 = SketchAPI_Point(SketchPoint_2).coordinates().x()
1953 sk_coo_y_2 = SketchAPI_Point(SketchPoint_2).coordinates().y()
1955 SketchProjection_3 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
1956 SketchProjection_3.execute(True)
1957 SketchLine_0 = SketchProjection_3.createdFeature()
1958 SketchLine_0.execute(True)
1960 # 6.2. Lignes perpendiculaires à l'axe passant par les centres
1961 SketchLine_1 = sketch.addLine(sk_coo_x_1, sk_coo_y_1, sk_coo_x_1+rayon_1, sk_coo_y_1)
1962 SketchLine_1.execute(True)
1963 SketchLine_1.setAuxiliary(True)
1964 sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.startPoint())
1965 sketch.setPerpendicular(SketchLine_0.result(), SketchLine_1.result())
1966 sketch.setLength(SketchLine_1.result(), nom_par_1)
1968 SketchLine_2 = sketch.addLine(sk_coo_x_2, sk_coo_y_2, sk_coo_x_2+rayon_2, sk_coo_y_2)
1969 SketchLine_2.execute(True)
1970 SketchLine_2.setAuxiliary(True)
1971 sketch.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_2.startPoint())
1972 sketch.setPerpendicular(SketchLine_0.result(), SketchLine_2.result())
1973 sketch.setLength(SketchLine_2.result(), nom_par_2)
1975 # 6.3. Ligne joignant les extrémités des précédentes et point milieu
1976 SketchLine_3 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
1977 SketchLine_3.execute(True)
1978 sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_1.endPoint())
1979 sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_2.endPoint())
1980 SketchLine_3.setAuxiliary(True)
1981 SketchPoint_3 = sketch.addPoint(sk_coo_x_1, sk_coo_y_1)
1982 SketchPoint_3.execute(True)
1983 sketch.setMiddlePoint(SketchLine_3.result(), SketchPoint_3.coordinates())
1985 # 6.4. Ligne support de la future révolution
1986 SketchLine_4 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
1987 SketchLine_4.execute(True)
1988 sketch.setMiddlePoint(SketchLine_4.result(), SketchPoint_3.coordinates())
1989 sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_4.result())
1990 sketch.setLength(SketchLine_4.result(), "1.2*{}".format(nom_par_3))
1994 nom_sketch = "{}_esquisse".format(self.nom_solide)
1995 exec_nom (sketch,nom_sketch)
1997 # Création du cone complet
1998 nom_cone = "{}_cone".format(self.nom_solide)
1999 self._cree_revolution ( nom_sketch, nom_centre_1, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_cone )
2001 # Intersection de la face conique avec le solide initial
2002 face = self._creation_face_inter ( nom_cone )
2006 #=========================== Fin de la méthode ==================================
2008 #=========================== Début de la méthode =================================
2010 def _cree_centre_axe_plan ( self, coo_c, vect, prefixe, n_recur ):
2011 """Crée un centre, un axe, un plan
2014 :coo_c: coordonnées du centre de la base
2015 :vect: coordonnées du vecteur
2016 :prefix: prefixe du nom des objets
2017 :n_recur: niveau de récursivité
2021 :normal: vecteur normal
2025 nom_fonction = __name__ + "/_cree_centre_axe_plan"
2026 blabla = "Dans {} :".format(nom_fonction)
2027 if self._verbose_max:
2028 print_tab (n_recur, blabla)
2029 print_tab (n_recur, "Centre : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
2030 print_tab (n_recur, "Normale : ({}, {}, {})".format(vect[0], vect[1], vect[2]))
2032 # Création du point central
2033 centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
2034 nom_centre = "{}_centre".format(prefixe)
2035 exec_nom (centre,nom_centre)
2036 if self.fonction_0 is None:
2037 self.fonction_0 = centre
2039 # Création du vecteur
2040 vecteur = model.addAxis(self.part_doc, vect[0], vect[1], vect[2])
2041 nom_vect = "{}_vecteur".format(prefixe)
2042 exec_nom (vecteur,nom_vect)
2044 # Création du plan perpendiculaire au vecteur normal
2045 plan = model.addPlane(self.part_doc, model.selection("EDGE", vecteur.name()), model.selection("VERTEX", centre.name()), True)
2046 nom_plan = "{}_plan".format(prefixe)
2047 exec_nom (plan,nom_plan)
2049 #print ("fin de {}".format(nom_fonction))
2051 return centre, vecteur, plan
2053 #=========================== Fin de la méthode ==================================
2055 #=========================== Début de la méthode =================================
2057 def _calcul_lg_caract ( self, objet, n_recur ):
2058 """Crée une longueur caractéristique de l'objet
2061 :objet: l'objet à traiter
2062 :n_recur: niveau de récursivité
2065 :l_caract: longueur caractéristique de l'objet
2068 nom_fonction = __name__ + "/_calcul_lg_caract"
2069 blabla = "Dans {} :".format(nom_fonction)
2071 if self._verbose_max:
2072 print_tab (n_recur, blabla)
2074 properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
2075 l_caract = properties[0]
2077 if self._verbose_max:
2078 print_tab (n_recur, "Longueur caractéristique : ", l_caract)
2082 #=========================== Fin de la méthode ==================================
2084 #=========================== Début de la méthode =================================
2086 def _cree_revolution ( self, nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_objet ):
2087 """Crée un volume de révolution
2090 :nom_sketch: nom de l'esquisse à révolutionner
2091 :nom_centre: nom du point associé au centre du volume de révolution
2092 :coo_x, coo_y, coo_z: coordonnées du centre du tore
2093 :axe_x, axe_y, axe_z: coordonnées de l'axe
2094 :rayon_1 : rayon principal
2095 :rayon_2 : rayon secondaire
2096 :nom_objet: nom de l'objet 2D créé
2099 nom_fonction = __name__ + "/_cree_revolution"
2100 blabla = "Dans {} :\n".format(nom_fonction)
2102 if self._verbose_max:
2104 texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
2105 texte += "Axe : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
2108 # Création d'un point décalé par rapport au point central
2109 point = model.addPoint(self.part_doc, coo_x+axe_x, coo_y+axe_y, coo_z+axe_z)
2110 nom_point = "{}_point".format(self.nom_solide)
2111 exec_nom (point,nom_point)
2113 # Création de l'axe de la rotation
2114 axe_r = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("VERTEX", nom_point))
2115 nom_axe_r = "{}_axe_r".format(self.nom_solide)
2116 exec_nom (axe_r,nom_axe_r)
2118 # Création de l'objet complet
2119 objet = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", nom_axe_r), 360, 0, "Edges")
2120 exec_nom (objet, nom_objet, (85, 0, 255))
2122 #=========================== Fin de la méthode ==================================
2124 #=========================== Début de la méthode =================================
2126 def _creation_face_inter ( self, nom_objet, nom_solide=None ):
2127 """Crée la face par intersection entre l'objet initial et une face complète
2129 . Repère la face principale de l'objet support
2130 . Réalise l'intersection avec le solide initial
2133 :nom_objet: nom de l'objet 2D créé
2134 :nom_solide: nom du solide initial ; si None, on prend self.nom_solide_aux
2137 :face: la face externe de l'objet support intersecté avec le solide initial
2140 nom_fonction = __name__ + "/_creation_face_inter"
2141 blabla = "Dans {} :\n".format(nom_fonction)
2143 if self._verbose_max:
2146 if nom_solide is None:
2147 nom_solide = self.nom_solide_aux
2149 face = model.addCommon(self.part_doc, [model.selection("SOLID", nom_solide), model.selection("FACE", nom_objet)], keepSubResults = True)
2154 #=========================== Fin de la méthode ==================================
2156 #=========================== Début de la méthode =================================
2158 def face_mediane_solide (self, solide, n_recur=0):
2159 """Calcul de la face médiane pour un solide
2162 :solide: solide SHAPER à traiter
2163 :n_recur: niveau de récursivité
2166 :erreur: code d'erreur
2167 :message: message d'erreur
2170 nom_fonction = __name__ + "/face_mediane_solide"
2171 blabla = "Dans {} :".format(nom_fonction)
2173 if self._verbose_max:
2174 print_tab (n_recur, blabla, saut_av=True)
2176 print_tab (n_recur, "Traitement du solide ", solide.name())
2185 # 2. Calcul des caractéristiques géométriques des faces
2187 tb_caract = self._calcul_caract_faces ( solide, n_recur )
2189 # 3. Tri des faces en fonction de leurs caractéristiques géométriques
2191 erreur, message, caract_face_1, caract_face_2 = self._tri_faces ( tb_caract, n_recur )
2195 # 4. Création de la face médiane
2197 erreur, face = self._cree_face_mediane ( solide, caract_face_1, caract_face_2, n_recur )
2198 if ( erreur or ( face is None ) ):
2201 # 6. Exportation step
2203 if self._export_step:
2204 fichier = os.path.join(self.rep_step, "{}.stp".format(face.result().name()))
2205 export = model.exportToFile(self.part_doc, fichier, [model.selection(face.result().shapeType(), face.result().name())])
2206 export.execute(True)
2213 if ( erreur and self._verbose_max ):
2214 print (blabla, message)
2216 return erreur, message
2218 #=========================== Fin de la méthode ==================================
2220 #=========================== Début de la méthode =================================
2222 def _traitement_objet (self, solide, n_recur=0):
2223 """Traitement d'un objet
2226 :solide: solide SHAPER à traiter
2227 :n_recur: niveau de récursivité
2230 :erreur: code d'erreur
2231 :message: message d'erreur
2234 nom_fonction = __name__ + "/_traitement_objet"
2235 blabla = "Dans {} :".format(nom_fonction)
2237 if self._verbose_max:
2238 print_tab (n_recur, blabla, saut_av=True)
2239 texte = "solide = {} ".format(solide.name())
2240 print_tab (n_recur, texte, solide)
2242 # 1. En cas d'exportation step, répertoire de travail associé à l'éventuel fichier de départ
2243 # Attention à ne pas recréer le répertoire à chaque fois
2244 if self._export_step:
2246 if self.rep_step is None:
2248 if self._verbose_max:
2249 print_tab (n_recur, "Préparation de l'export STEP")
2251 if self.ficcao is None:
2252 self.rep_step = tempfile.mkdtemp(prefix="{}_".format(self.objet_principal.name()))
2254 self.rep_step = os.path.join(os.path.dirname(self.ficcao),"{}_M".format(self.objet_principal.name()))
2255 if os.path.isdir(self.rep_step):
2256 l_aux = os.listdir(self.rep_step)
2257 for nomfic in l_aux:
2258 os.remove(os.path.join(self.rep_step,nomfic))
2260 os.mkdir(self.rep_step)
2262 if self._verbose_max:
2263 print_tab (n_recur, "Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
2265 # 2. Calcul réel de la face médiane
2267 erreur, message = self.face_mediane_solide (solide, n_recur)
2269 return erreur, message
2271 #=========================== Fin de la méthode ==================================
2273 #=========================== Début de la méthode =================================
2275 def surf_fic_cao (self, ficcao, nom_objet=None):
2276 """Calcule la surface médiane pour un objet dans un fichier passé en argument
2279 :ficcao: fichier de l'objet à traiter
2280 :nom_objet: un nom à donner à l'objet à traiter
2283 :erreur: code d'erreur
2284 :message: message d'erreur
2287 nom_fonction = __name__ + "/surf_fic_cao"
2288 blabla = "Dans {} :".format(nom_fonction)
2290 if self._verbose_max:
2300 if self.affiche_aide_globale:
2303 # 1. Définition de la pièce
2305 self.part_doc = model.activeDocument()
2306 if ( self.part_doc.kind() == "PartSet" ):
2307 part = model.addPart(self.part_doc)
2308 self.part_doc = part.document()
2310 # 2. Import de la CAO
2312 self.ficcao = ficcao
2313 print ("Traitement du fichier {}".format(ficcao))
2315 erreur, message, objet = import_cao (self.part_doc, ficcao, nom_objet, self._verbose_max)
2319 # 3. Calcul des surfaces
2321 erreur, message = self.surf_objet_shaper ( objet )
2328 if ( erreur and self._verbose_max ):
2329 print (blabla, message)
2331 return erreur, message
2333 #=========================== Fin de la méthode ==================================
2335 #=========================== Début de la méthode =================================
2337 def surf_objet_shaper (self, objet):
2338 """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2341 :objet: objet à traiter
2344 :erreur: code d'erreur
2345 :message: message d'erreur
2348 nom_fonction = __name__ + "/surf_objet_shaper"
2349 blabla = "Dans {} :".format(nom_fonction)
2351 if self._verbose_max:
2359 if self.affiche_aide_globale:
2362 # 1. Acquisition de la liste des noms des sous-objets solides
2364 self.d_statut_so = dict()
2365 self.l_noms_so = list()
2366 self.l_faces_m = list()
2368 _ = self._nom_sous_objets (objet, True)
2369 if self._verbose_max:
2370 print ("Noms des sous-objets : {}".format(self.l_noms_so))
2372 # 2. Les faces médianes
2374 erreur, message = self._surf_objet_shaper_0 ( objet )
2378 # 3. Gestion des faces créées
2380 self._surf_objet_shaper_1 ( )
2382 # 4. Futur message pour le résultat
2384 if ( self._export_step and not erreur ):
2385 message = "Les fichiers des CAO des surfaces sont dans le répertoire {}".format(self.rep_step)
2389 return erreur, message
2391 #=========================== Fin de la méthode ==================================
2393 #=========================== Début de la méthode =================================
2395 def _surf_objet_shaper_0 (self, objet, n_recur=0):
2396 """Calcule les surfaces médianes pour un objet SHAPER passé en argument
2399 :objet: objet à traiter
2400 :n_recur: niveau de récursivité
2403 :erreur: code d'erreur
2404 :message: message d'erreur
2407 nom_fonction = __name__ + "/_surf_objet_shaper_0"
2408 blabla = "Dans {} :".format(nom_fonction)
2410 if self._verbose_max:
2411 print_tab (n_recur, blabla)
2412 print_tab (n_recur, "n_recur = ", n_recur)
2419 # 1. Au premier passage, il faut récupérer la pièce SHAPER et garder la référence au résultat principal
2421 if ( n_recur == 0 ):
2422 self.part_doc = model.activeDocument()
2423 objet_0 = objet.result()
2424 self.objet_principal = objet_0
2425 objet_bis = objet.defaultResult().shape()
2426 if self._verbose_max:
2427 print_tab (0, "Examen de l'objet initial ", objet.result().name(), saut_av=True)
2428 print_tab (0, "Type python : ", type(objet))
2429 print_tab (0, "Type {} / {} ; volume = ".format(objet_bis.shapeType(),objet_bis.shapeTypeStr()), GeomAlgoAPI_ShapeTools.volume(objet_bis))
2432 if self._verbose_max:
2433 print_tab (n_recur, "Examen de l'objet ", objet.name(), saut_av=True)
2434 print_tab (n_recur, "Type python : ", type(objet))
2435 print_tab (n_recur, "shapeType : ", objet.shapeType())
2437 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
2439 nb_sub_results = objet_0.numberOfSubs()
2441 if self._verbose_max:
2442 print_tab (n_recur, "Examen de l'objet '{}' de type ".format(objet_0.name()), objet_0.shapeType(), saut_av=True)
2443 print_tab (n_recur, "objet.result().numberOfSubs() : ", nb_sub_results)
2445 for n_sobj in range(nb_sub_results):
2447 # 2.1. Exploration récursive de l'arborescence
2449 erreur, message = self._surf_objet_shaper_0 ( objet_0.subResult(n_sobj), n_recur+1 )
2456 # 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
2458 if ( objet_0.shapeType() == "SOLID" ):
2459 erreur, message = self.surf_solide_shaper ( objet_0, n_recur )
2463 # 3. Futur message pour le résultat
2465 if self._export_step:
2466 message = "Les fichiers STEP des surfaces sont dans le répertoire {}".format(self.rep_step)
2470 return erreur, message
2472 #=========================== Fin de la méthode ==================================
2474 #=========================== Début de la méthode =================================
2476 def _surf_objet_shaper_1 (self, n_recur=0):
2477 """Gestion des surfaces médianes créées
2480 :n_recur: niveau de récursivité
2483 :erreur: code d'erreur
2484 :message: message d'erreur
2487 nom_fonction = __name__ + "/_surf_objet_shaper_1"
2488 blabla = "Dans {} :\n".format(nom_fonction)
2490 if self._verbose_max:
2491 print_tab (n_recur, blabla)
2493 # 1. Informations sur les faces à problème
2495 if self.faces_pb_nb:
2496 if ( self.faces_pb_nb == 1 ):
2497 texte = "1 face pose"
2499 texte = "{} faces posent".format(self.faces_pb_nb)
2500 print_tab (n_recur, "{} problème.".format(texte), self.faces_pb_msg, saut_av=True)
2502 # 2. Si plus d'une face a été créée
2503 if ( len(self.l_faces_m) > 1 ):
2505 # 2.1. Partition du paquet de faces
2507 if self._verbose_max:
2508 print_tab (n_recur, "Partitionnnement des faces créées.")
2510 # 2.1.1. Pour une raison mystérieuse, il faut commencer par les faces entières, puis mettre les sous-faces éventuelles
2512 for (face,_) in self.l_faces_m:
2513 if not face.result().numberOfSubs():
2514 d_faces[face.name()] = [face.name()]
2515 for (face,_) in self.l_faces_m:
2516 nb_sub_results = face.result().numberOfSubs()
2519 for n_sobj in range(nb_sub_results):
2520 laux.append(face.result().subResult(n_sobj).name())
2521 d_faces[face.name()] = laux
2524 for _, laux in d_faces.items():
2525 for s_face_n in laux:
2526 l_objets.append(model.selection("FACE", s_face_n))
2528 Partition_1 = model.addPartition(self.part_doc, l_objets, keepSubResults = True)
2529 nom = "{}_M".format(self.objet_principal.name())
2530 exec_nom (Partition_1,nom)
2533 for face_n, laux in d_faces.items():
2534 Partition_1.result().subResult(iaux).setName("{}".format(face_n))
2535 if ( len(laux) > 1 ):
2536 for jaux, s_face_n in enumerate(laux):
2537 Partition_1.result().subResult(iaux).subResult(jaux).setName("{}_M".format(s_face_n))
2539 couleur_objet (Partition_1, n_recur, coul_r=0, coul_g=170, coul_b=0, verbose=self._verbose_max)
2541 # 2.2. Récupération des faces individuelles
2543 if self._verbose_max:
2544 print_tab (n_recur, "Récupération des faces individuelles.")
2547 for iaux, (face,_) in enumerate(self.l_faces_m):
2548 l_objets.append(face.result())
2550 Recover_1 = model.addRecover(self.part_doc, Partition_1, l_objets)
2551 for iaux, (face,_) in enumerate(self.l_faces_m):
2552 Recover_1.results()[iaux].setName("{}".format(face.name()))
2553 Recover_1.results()[iaux].setColor(0, 170, 0)
2554 nb_sub_results = Recover_1.results()[iaux].numberOfSubs()
2555 for n_sobj in range(nb_sub_results):
2556 Recover_1.results()[iaux].subResult(n_sobj).setName("{}_{}".format(face.name(),n_sobj))
2557 Recover_1.results()[iaux].subResult(n_sobj).setColor(0, 170, 0)
2559 # 3. Mise en dossier
2561 if self._verbose_max:
2562 print_tab (n_recur, "Mise en dossier.")
2564 for (face,fonction_0) in self.l_faces_m:
2565 nom = face.name()[:-2]
2566 if self._verbose_max:
2567 print ( "Dossier {} de {} à {}".format(nom,fonction_0.name(),face.name()))
2568 dossier = model.addFolder(self.part_doc, fonction_0, face)
2569 #dossier.execute(True)
2570 dossier.setName(nom)
2572 if ( len(self.l_faces_m) > 1 ):
2574 nom = self.objet_principal.name()
2575 if self._verbose_max:
2576 print ( "Dossier {} de {} à {}".format(nom,Partition_1.name(),Recover_1.name()))
2577 dossier = model.addFolder(self.part_doc, Partition_1, Recover_1)
2578 #dossier.execute(True)
2579 dossier.setName(nom)
2581 #=========================== Fin de la méthode ==================================
2583 #=========================== Début de la méthode =================================
2585 def surf_solide_shaper (self, solide, n_recur):
2586 """Calcule les surfaces médianes pour un solide SHAPER solide passé en argument
2589 :solide: solide SHAPER à traiter
2590 :n_recur: numéro de la récurrence
2593 :erreur: code d'erreur
2594 :message: message d'erreur
2597 nom_fonction = __name__ + "/surf_solide_shaper"
2598 blabla = "Dans {} :".format(nom_fonction)
2600 if self._verbose_max:
2601 print_tab (n_recur, blabla, saut_av=True)
2608 self.nom_solide = solide.name()
2609 if self._verbose_max:
2610 print_tab (n_recur, "solide : ", self.nom_solide)
2612 # 1. Isolement du solide
2613 solide_aux, recover = self._isole_solide ( solide, n_recur )
2615 # 2. Traitement de l'objet correspondant
2616 erreur, message = self._traitement_objet ( solide_aux, n_recur=n_recur )
2618 if ( erreur and self._verbose_max ):
2619 print (blabla, message)
2621 # 3. Neutralisation des erreurs dues à l'épaisseur
2622 if ( erreur in (-2,-1,2) ):
2628 # 4. Mise en forme de l'objet principal récupéré
2629 if ( recover is not None ):
2630 _ = self._nom_sous_objets (recover, False)
2634 return erreur, message
2636 #=========================== Fin de la méthode ==================================
2638 #========================== Fin de la classe ====================================
2640 #==================================================================================
2642 #==================================================================================
2644 if __name__ == "__main__" :
2646 HOME_SH_SM_EXCHANGE = os.environ["HOME_SH_SM_EXCHANGE"]
2648 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "Solid_7.step"))
2649 L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Objet_1.stp"))
2650 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval_007.stp"))
2651 ##L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval.stp"))
2652 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2.step"))
2653 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_22.step"))
2654 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_5.step"))
2655 #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Observatoire.stp"))
2657 for FIC_CAO in L_FIC_CAO:
2662 #L_OPTIONS.append("-h")
2663 #L_OPTIONS.append("-v")
2664 L_OPTIONS.append("-vmax")
2665 L_OPTIONS.append("-export_step")
2667 # 2. Lancement de la classe
2669 #print ("L_OPTIONS :", L_OPTIONS)
2671 SURFACE_MEDIANE = SurfaceMediane(L_OPTIONS)
2672 if SURFACE_MEDIANE.affiche_aide_globale:
2673 sys.stdout.write(SURFACE_MEDIANE.__doc__+"\n")
2676 PARTSET = model.moduleDocument()
2677 _ = model.addPart(PARTSET)
2678 ERREUR, MESSAGE_ERREUR = SURFACE_MEDIANE.surf_fic_cao(FIC_CAO)
2680 MESSAGE_ERREUR += "\n Code d'erreur : %d\n" % ERREUR
2681 sys.stderr.write(MESSAGE_ERREUR)