Salome HOME
ménage
[modules/shaper.git] / src / PythonAddons / macros / midSurface / surfaceMediane.py
index c309e6c26e2c8fcc4ea3151db8b9528eab5d6583..8fe2b50f4242ba87232253617641d6d69c48c016 100755 (executable)
@@ -36,7 +36,7 @@ guillaume.schweitzer@blastsolutions.io
 Gérald NICOLAS
 """
 
-__revision__ = "V10.55"
+__revision__ = "V11.03"
 
 #========================= Les imports - Début ===================================
 
@@ -52,11 +52,10 @@ salome.salome_init()
 import SALOMEDS
 from SketchAPI import *
 from salome.shaper import model
+from salome.shaper import geom
 from GeomAPI import *
 from GeomAlgoAPI import *
 
-from salome.geom import geomBuilder
-
 import numpy as np
 
 #========================== Les imports - Fin ====================================
@@ -101,7 +100,7 @@ Entrées :
   :fmt_cao: format du fichier, step, iges, etc.
 Sorties :
   :fmt_cao_0: format décodé
-  """
+"""
 
   fmt_cao_0 = ""
 
@@ -127,16 +126,16 @@ Entrées :
   :nom_objet: nom à donner à l'objet lu, éventuellement
 Sorties :
   :objet: l'objet importé dans SHAPER
-  """
+"""
 
   nom_fonction = __name__ + "/import_cao"
-  blabla = "\nDans {} :\n".format(nom_fonction)
+  blabla = "Dans {} :\n".format(nom_fonction)
   message_0 = "Fichier : {}\n".format(ficcao)
   if verbose:
     message = blabla + message_0
     message += "nom_objet : {}".format(nom_objet)
     print (message)
-    message = message_0
+  message = message_0
 
   erreur = 0
 
@@ -187,7 +186,7 @@ Entrées :
   :argu: argument du format
   :saut_av: saut de ligne avant le texte
   :saut_ap: saut de ligne après le texte
-  """
+"""
 
   texte = ""
 
@@ -205,6 +204,26 @@ Entrées :
     texte += "\n"
 
   print (texte)
+
+#=========================  Fin de la fonction ===================================
+
+#========================= Début de la fonction ==================================
+
+def nommage (objet, nom, couleur=None):
+  """Nomme un objet et son résultat
+
+Entrées :
+  :objet: objet à traiter
+  :nom: nom à attribuer
+  :couleur: éventuellement couleur
+"""
+
+  objet.setName(nom)
+  objet.result().setName(nom)
+
+  if ( couleur is not None ):
+    objet.result().setColor(couleur[0], couleur[1], couleur[2])
+
 #=========================  Fin de la fonction ===================================
 
 
@@ -270,7 +289,7 @@ _cree_face_mediane --> _cree_face_mediane_plane
                    --> _cree_face_mediane_cone
                    --> _cree_face_mediane_0
 
-  """
+"""
 
 # A. La base
 
@@ -291,7 +310,6 @@ _cree_face_mediane --> _cree_face_mediane_plane
   ficcao = None
   rep_step = None
   objet_principal = None
-  objet_geom = None
   # Pour chaque sous-objet dans l'ordre de l'arborescence : nom
   l_noms_so = list()
   # Statut de chaque sous-objet connu par son nom :
@@ -470,8 +488,6 @@ Sorties :
 
     #print ("sortie de {}".format(nom_fonction))
 
-    return
-
 #===========================  Fin de la méthode ==================================
 
 #=========================== Début de la méthode =================================
@@ -489,9 +505,9 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_isole_solide"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       texte = "Pour le solide '{}' ".format(solide.name())
       texte += "de l'objet principal '{}'".format(self.objet_principal.name())
       print_tab (n_recur, texte)
@@ -504,8 +520,8 @@ Sorties :
 
     if self._verbose_max:
       print_tab (n_recur, "objet final : ", objet.name())
-      print_tab (n_recur, "fonction_0 : ", self.fonction_0)
-      print_tab (n_recur, "recover : ", recover)
+      print_tab (n_recur, "fonction_0 : {}".format(self.fonction_0))
+      print_tab (n_recur, "recover : {}".format(recover))
 
     return objet, recover
 
@@ -526,9 +542,9 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_isole_solide_a"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       texte = "Pour le solide '{}' ".format(solide.name())
       texte += "de l'objet principal '{}'".format(self.objet_principal.name())
       print_tab (n_recur, texte)
@@ -572,9 +588,9 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_isole_solide_b"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       texte = "Pour le solide '{}' ".format(solide.name())
       texte += "de l'objet principal '{}'".format(self.objet_principal.name())
       print_tab (n_recur, texte)
@@ -591,97 +607,95 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _faces_du_solide ( self, geompy, objet_geom, solide, n_recur=0 ):
+  def _faces_du_solide ( self, solide, n_recur=0 ):
     """Détermine les faces d'un solide
 
 Entrées :
-  :geompy: environnement de GEOM
-  :objet_geom: l'objet solide à traiter au format GEOM
   :solide: solide SHAPER à traiter
   :n_recur: niveau de récursivité
 
 Sorties :
-  :l_faces_geom: liste des faces du solide au format GEOM
-  :l_faces: liste des faces du solide
+  :l_faces_car: pour chaque face du solide (surface,caractéristiques)
 """
 
     nom_fonction = __name__ + "/_faces_du_solide"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla, saut_av=True)
 
-    erreur = 0
-    message = ""
-    l_faces_geom = list()
     l_faces = list()
 
-    while ( not erreur ):
+    if self._verbose_max:
+      print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
+      print_tab (n_recur, ".. shapeType : ", solide.shapeType())
 
-      if self._verbose_max:
-        print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
-        longueur, aire, volume = geompy.BasicProperties(objet_geom)
-        texte = "{}".format(geompy.WhatIs(objet_geom))
-        texte += ". longueur, aire, volume : {}, {}, {}".format(longueur,aire,volume)
-        print (texte)
-
-# Liste des faces qui composent le solide
-      l_faces_geom = geompy.ExtractShapes(objet_geom, geompy.ShapeType["FACE"], True)
-      #if self._verbose_max:
-        #print ("Liste des {} faces qui composent le solide :".format(len(l_faces_geom)))
-        #for iaux, face in enumerate(l_faces_geom):
-          #print ("Face n° {} :\n {}".format(iaux,geompy.WhatIs(face)))
-
-      print_tab (n_recur, "Type python : ", type(solide))
-      print_tab (n_recur, "Type ", solide.shapeType())
-      #print ("Type {}".format(solide.shapeTypeStr()))
-      #print ("volume = {}".format(GeomAlgoAPI_ShapeTools.volume(solide)))
-      l_faces = list()
-      #exp = GeomAPI_ShapeExplorer(solide, GeomAPI_Shape.FACE)
-      #while exp.more():
-        #l_faces.append(exp.current().face())
-        #exp.next()
+    #print (dir(solide))
+    #print_tab (n_recur, "volume = ", GeomAlgoAPI_ShapeTools.volume(solide.shape()))
+# 1. Repérage des faces
+    objResult = solide.resultSubShapePair()[0]
+    l_faces = list()
+    exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
+    while exp.more():
+      l_faces.append(exp.current().face())
+      exp.next()
 
-      break
+# 2. Calcul
+    l_faces_car = list()
+    for iface, face in enumerate(l_faces):
+      surf = GeomAlgoAPI_ShapeTools.area(face)
+      caract = geom.shapeInfo(face)
+      if self._verbose_max:
+        print_tab (n_recur, "\tFace n°{} ; ".format(iface), "surface = {}, caractéristiques = {}".format(surf,caract))
+      l_faces_car.append((surf,caract))
 
-    return erreur, message, l_faces_geom, l_faces
+    return l_faces_car
 
 #===========================  Fin de la méthode ==================================
 
 #=========================== Début de la méthode =================================
 
-  def _calcul_caract_faces ( self, geompy, l_faces ):
-    """Calcule les caractéristiques géométriques des faces
+  def _calcul_caract_faces ( self, solide, n_recur ):
+    """Calcule les caractéristiques géométriques des faces du solide
 
 Entrées :
-  :geompy: environnement de GEOM
-  :l_faces: liste des faces du solide
+  :solide: solide SHAPER à traiter
+  :n_recur: niveau de récursivité
 
 Sorties :
   :tb_caract: tableau des caractéristiques géométriques des faces
 """
 
     nom_fonction = __name__ + "/_calcul_caract_faces"
-    blabla = "\nDans {} :\n".format(nom_fonction)
-
-    nb_faces = len(l_faces)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla+"Nombre de faces : {}.".format(nb_faces))
+      print_tab (n_recur, blabla, saut_av=True)
+      print_tab (n_recur, ".. Traitement du solide ", self.nom_solide)
+      print_tab (n_recur, ".. shapeType : ", solide.shapeType())
 
+# 1. Repérage des faces
+    objResult = solide.resultSubShapePair()[0]
+    l_faces = list()
+    exp = GeomAPI_ShapeExplorer(objResult.shape(), GeomAPI_Shape.FACE)
+    while exp.more():
+      l_faces.append(exp.current().face())
+      exp.next()
+
+# 2. Caractéristiques
+    nb_faces = len(l_faces)
     tb_caract = np.zeros((nb_faces,3), dtype = 'object')
     for iaux, face in enumerate(l_faces):
-      _, aire, _ = geompy.BasicProperties(face)
-      #longueur, aire, volume = geompy.BasicProperties(face)
+      surf = GeomAlgoAPI_ShapeTools.area(face)
+      caract = geom.shapeInfo(face)
       if self._verbose_max:
-        texte = "\t. Face numéro {}".format(iaux)
-        #texte += "\n\t. longueur, aire, volume : {}, {}, {}".format(longueur,aire,volume)
-        texte += ", surface : {}".format(aire)
-        print (texte)
+        print_tab (n_recur, "\tFace n°{} ; ".format(iaux), "surface = {}, caractéristiques = {}".format(surf,caract))
 
       tb_caract [iaux][0] = face
-      tb_caract [iaux][1] = aire
-      tb_caract [iaux][2] = geompy.KindOfShape(face)
-      if self._verbose_max:
-        print ("\t. tb_caract : {} {}".format(aire,tb_caract[iaux][2]))
+      tb_caract [iaux][1] = surf
+      tb_caract [iaux][2] = caract
+
+    #if self._verbose_max:
+      #for iaux in range(nb_faces):
+        #print ("\t. tb_caract : {} {}".format(surf,tb_caract[iaux][2]))
 
     return tb_caract
 
@@ -689,11 +703,12 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _tri_faces ( self, tb_caract ):
+  def _tri_faces ( self, tb_caract, n_recur ):
     """Trie les faces en fonction de leurs surfaces
 
 Entrées :
   :tb_caract: tableau des caractéristiques géométriques des faces
+  :n_recur: niveau de récursivité
 
 Sorties :
   :tb_caract_1[-1], tb_caract_1[-2]: les caractéristiques des 2 faces les plus grandes
@@ -703,14 +718,15 @@ Sorties :
     message = ""
 
     nom_fonction = __name__ + "/_tri_faces"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 # Tri du tableau en fonction des surfaces
     if self._verbose_max:
-      print (blabla+"tb_caract brut : {}".format(tb_caract))
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "tb_caract brut : ", tb_caract)
     tb_caract_1 = sorted(tb_caract, key=lambda colonnes: colonnes[1])
     if self._verbose_max:
-      print ("tb_caract trié : {}".format(tb_caract_1))
+      print_tab (n_recur, "tb_caract trié :", tb_caract_1)
 
     if self._verbose_max:
       texte  = "\tSurface de la plus grande face      : {}, de caractéristiques {}\n".format(tb_caract_1[-1][1],tb_caract_1[-1][2])
@@ -739,41 +755,6 @@ Sorties :
 
 #===========================  Fin de la méthode ==================================
 
-#=========================== Début de la méthode =================================
-
-  def _calcul_caract_aretes_face ( self, geompy, caract_face ):
-    """Détermine les caractéristiques des arêtes d'une face
-
-Entrées :
-  :geompy: environnement de GEOM
-  :caract_face: les caractéristiques de la face
-
-Sorties :
-  :caract_arete_face: les caractéristiques des arêtes de la face
-"""
-
-    nom_fonction = __name__ + "/_calcul_caract_aretes_face"
-    blabla = "\nDans {} :\n".format(nom_fonction)
-
-    if self._verbose_max:
-      texte = blabla
-      texte += "face : {}\n".format(caract_face)
-      print (texte)
-
-# Détermination des arêtes pour chaque face
-    face = caract_face[0]
-    l_aretes = geompy.ExtractShapes(face, geompy.ShapeType["EDGE"], True)
-    caract_arete_face = list()
-    for arete in l_aretes:
-      caract_arete_face.append(geompy.KindOfShape(arete))
-
-    if self._verbose_max:
-      print ("Aretes de la face : {}".format(caract_arete_face))
-
-    return caract_arete_face
-
-#===========================  Fin de la méthode ==================================
-
 #=========================== Début de la méthode =================================
 
   def _verif_epaisseur ( self, epaisseur ):
@@ -784,7 +765,7 @@ Entrées :
 """
 
     nom_fonction = __name__ + "/_verif_epaisseur"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
     if self._verbose_max:
       texte = blabla
@@ -804,6 +785,7 @@ Entrées :
 
     else:
       erreur = 0
+    #print ("erreur = {}".format(erreur))
 
     return erreur
 
@@ -811,12 +793,11 @@ Entrées :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane ( self, solide, geompy, caract_face_1, caract_face_2, n_recur ):
+  def _cree_face_mediane ( self, solide, caract_face_1, caract_face_2, n_recur ):
     """Crée la face médiane entre deux autres
 
 Entrées :
   :solide: solide SHAPER à traiter
-  :geompy: environnement de GEOM
   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
   :n_recur: niveau de récursivité
 
@@ -825,10 +806,10 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : " ,caract_face_1)
       print_tab (n_recur, "face_2 : " ,caract_face_2)
 
@@ -837,29 +818,27 @@ Sorties :
 
 # 1. Forme de la face
     forme = caract_face_1[2][0]
-    if self._verbose_max:
-      print ("forme = {}".format(forme) )
 
 # 2. Traitement selon la forme de la face
 # 2.1. Face plane
-    if forme in ( geompy.kind.DISK_CIRCLE, geompy.kind.DISK_ELLIPSE, geompy.kind.POLYGON, geompy.kind.PLANE, geompy.kind.PLANAR ):
-      erreur, face = self._cree_face_mediane_plane ( geompy, solide, caract_face_1, caract_face_2, n_recur )
+    if forme in ( "Disk" , "Plane", "Rectangle"):
+      erreur, face = self._cree_face_mediane_plane ( solide, caract_face_1, caract_face_2, n_recur )
 
 # 2.2. Face cylindrique
-    elif forme == geompy.kind.CYLINDER2D:
+    elif ( forme == "Cylinder" ):
       erreur, face = self._cree_face_mediane_cylindre ( solide, caract_face_1, caract_face_2, n_recur )
 
 # 2.3. Face sphérique
-    elif forme == geompy.kind.SPHERE2D:
+    elif ( forme == "Sphere" ):
       erreur, face = self._cree_face_mediane_sphere ( caract_face_1, caract_face_2, n_recur )
 
 # 2.4. Face torique
-    elif forme == geompy.kind.TORUS2D:
+    elif ( forme == "Torus" ):
       erreur, face = self._cree_face_mediane_tore ( caract_face_1, caract_face_2, n_recur )
 
 # 2.5. Face conique
-    elif forme == geompy.kind.CONE2D:
-      erreur, face = self._cree_face_mediane_cone ( geompy, caract_face_1, caract_face_2, n_recur )
+    elif ( forme == "Cone" ):
+      erreur, face = self._cree_face_mediane_cone ( caract_face_1, caract_face_2, n_recur )
 
 # 2.N. Face de forme inconnue
     else:
@@ -891,10 +870,10 @@ Entrées :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_0"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
 
 # 1. Nom de la face
     nom_face = self.nom_solide+"_M"
@@ -902,8 +881,7 @@ Entrées :
       print_tab (n_recur,"Nom de la face créée : ", nom_face)
     #if ( self.nom_solide_aux != self.objet_principal.name() ):
       #nom_face += "S"
-    face.setName(nom_face)
-    face.result().setName(nom_face)
+    nommage (face, nom_face)
 
 # 2. Mémorisation de la face et de la fonction initiale
     self.l_faces_m.append((face, self.fonction_0))
@@ -914,17 +892,14 @@ Entrées :
 # 4. Changement de statut pour le solide
     self.d_statut_so[self.nom_solide] = 1
 
-    return
-
 #===========================  Fin de la méthode ==================================
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_plane ( self, geompy, solide, caract_face_1, caract_face_2, n_recur ):
+  def _cree_face_mediane_plane ( self, solide, caract_face_1, caract_face_2, n_recur ):
     """Crée la face médiane entre deux autres - cas des surfaces planes
 
 Entrées :
-  :geompy: environnement de GEOM
   :solide: l'objet solide à traiter
   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
   :n_recur: niveau de récursivité
@@ -934,12 +909,12 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_plane"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
 
 #   Caractéristiques des surfaces
-    coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2 = self._cree_face_mediane_plane_0 ( geompy, solide, caract_face_1, caract_face_2, n_recur )
+    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 )
 
 #   Contrôle de la validité de l'épaisseur
     erreur = self._verif_epaisseur ( d_face_1_2 )
@@ -956,13 +931,12 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_plane_0 ( self, geompy, solide, caract_face_1, caract_face_2, n_recur ):
+  def _cree_face_mediane_plane_0 ( self, solide, caract_face_1, caract_face_2, n_recur ):
     """Crée la face médiane entre deux autres - cas des surfaces planes
 
 Décodage des caractéristiques
 
 Entrées :
-  :geompy: environnement de GEOM
   :solide: l'objet solide à traiter
   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
   :n_recur: niveau de récursivité
@@ -975,12 +949,12 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_plane_0"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
-      print_tab (n_recur, "face_1 : ", caract_face_1)
-      print_tab (n_recur, "face_2 : ", caract_face_2)
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "caract_face_1 : ", caract_face_1)
+      print_tab (n_recur, "caract_face_2 : ", caract_face_2)
 
 # 1. Caractéristiques de la base
 #   Coordonnées du centre de la base
@@ -991,8 +965,8 @@ Sorties :
     vnor_x = caract_face_1[2][4]
     vnor_y = caract_face_1[2][5]
     vnor_z = caract_face_1[2][6]
-#   taille : la diagonale de la boîte englobante permet d'être certain de tout prendre
-    l_diag = self._calcul_boite_englobante ( solide, n_recur )
+#   taille : une longueur caractéristique pour être certain de tout prendre
+    l_diag = self._calcul_lg_caract ( solide, n_recur )
     taille = 10.*l_diag
     if self._verbose_max:
       print_tab (n_recur, "Taille englobante : ",taille)
@@ -1000,7 +974,7 @@ Sorties :
 # 2. Distance entre les deux faces
     face_1 = caract_face_1[0]
     face_2 = caract_face_2[0]
-    d_face_1_2 = geompy.MinDistance(face_1, face_2)
+    d_face_1_2 = GeomAlgoAPI_ShapeTools.minimalDistance(face_1, face_2)
     if self._verbose_max:
       print_tab (n_recur, "Distance entre les deux faces = ", d_face_1_2)
 
@@ -1028,59 +1002,27 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_plane_1"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "Centre   : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
       print_tab (n_recur, "Normale  : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
       print_tab (n_recur, "Taille   : ", taille)
       print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
 
-#   Création de paramètres
+# 1. Objets préalables
     nom_par_1 = "{}_taille".format(self.nom_solide)
     model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(taille))
 
-#   Création du point central
-    centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
-    nom_centre = "{}_centre".format(self.nom_solide)
-    centre.result().setName(nom_centre)
-
-#   Création du vecteur normal
-    v_norm = model.addAxis(self.part_doc, vnor[0], vnor[1], vnor[2])
-    nom_normal = "{}_normale".format(self.nom_solide)
-    v_norm.result().setName(nom_normal)
-
-#   Création du plan perpendiculaire au vecteur normal
-    plan = model.addPlane(self.part_doc, model.selection("EDGE", nom_normal), model.selection("VERTEX", nom_centre), True)
-    nom_plan = "{}_plan".format(self.nom_solide)
-    plan.result().setName(nom_plan)
-
-#   Création de l'esquisse
-    sketch = self._cree_face_mediane_plane_1a ( nom_plan, nom_centre, nom_par_1, taille, n_recur )
-
-    ### Create LinearCopy
-    LinearCopy_1 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", self.nom_solide_aux)], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
-    LinearCopy_1.result().subResult(0).setName("{}_0".format(self.nom_solide_aux))
-
-    ### Create Recover
-    Recover_1 = model.addRecover(self.part_doc, LinearCopy_1, [solide])
-    Recover_1.result().setName("{}_1".format(self.nom_solide_aux))
+    centre, v_norm, plan = self._cree_centre_axe_plan ( coo_c, vnor, self.nom_solide, n_recur )
 
-    # Création d'une face ; on la translate d'une demi-épaisseur.
-    for iaux in range(2):
+# 2. Création de l'esquisse
+    sketch = self._cree_face_mediane_plane_1_a ( plan, centre, nom_par_1, taille, n_recur )
 
-      distance = -0.5*d_face_1_2*float(2*iaux-1)
-      nom_solide = "{}_{}".format(self.nom_solide_aux,iaux)
-      face = self._cree_face_mediane_plane_2 ( sketch.name(), nom_normal, nom_solide, distance, iaux )
+# 3. La face
+    face = self._cree_face_mediane_plane_1_b ( solide, sketch, v_norm, d_face_1_2, n_recur )
 
-      if face.results():
-        face = self._cree_face_mediane_plane_11 ( face, Recover_1, n_recur )
-        break
-      # Si l'intersection est vide, on la translate dans l'autre sens
-      else:
-        if self._verbose_max:
-          print_tab (n_recur, "L'intersection est vide.")
-        face = None
+    #print ("fin de {}".format(nom_fonction))
 
     return face
 
@@ -1088,12 +1030,12 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_plane_1a ( self, nom_plan, nom_centre, nom_par_1, taille, n_recur ):
+  def _cree_face_mediane_plane_1_a ( self, plan, centre, nom_par_1, taille, n_recur ):
     """Crée la face médiane entre deux autres - cas des surfaces planes - l'esquisse
 
 Entrées :
-  :nom_plan: nom du plan
-  :nom_centre: nom du centre
+  :plan: plan
+  :centre: centre
   :nom_par_1: nom du paramètre
   :taille: estimation de la taille de la future face
   :n_recur: niveau de récursivité
@@ -1102,65 +1044,124 @@ Sorties :
   :sketch: l'esquisse
 """
 
-    nom_fonction = __name__ + "/_cree_face_mediane_plane_1a"
-    blabla = "\nDans {} :".format(nom_fonction)
+    nom_fonction = __name__ + "/_cree_face_mediane_plane_1_a"
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
-      print_tab (n_recur, "Plan      : {}".format(nom_plan))
-      print_tab (n_recur, "Centre    : {}".format(nom_centre))
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "Plan      : {}".format(plan.name()))
+      print_tab (n_recur, "Centre    : {}".format(centre.name()))
       print_tab (n_recur, "Paramètre : {}".format(nom_par_1))
+      print_tab (n_recur, "taille    : {}".format(taille))
 
-    sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
-
-    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
-    SketchPoint_1 = SketchProjection_1.createdFeature()
+    sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
 
     ### Create SketchLine
     SketchLine_1 = sketch.addLine(-taille/2., taille/2., taille/2., taille/2.)
+    sketch.setHorizontal(SketchLine_1.result())
 
     ### Create SketchLine
     SketchLine_2 = sketch.addLine(taille/2., taille/2., taille/2., -taille/2.)
+    sketch.setVertical(SketchLine_2.result())
+    sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
 
     ### Create SketchLine
     SketchLine_3 = sketch.addLine(taille/2., -taille/2., -taille/2., -taille/2.)
+    sketch.setHorizontal(SketchLine_3.result())
+    sketch.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+    sketch.setLength(SketchLine_3.result(), nom_par_1)
 
     ### Create SketchLine
     SketchLine_4 = sketch.addLine(-taille/2., -taille/2., -taille/2., taille/2.)
+    sketch.setVertical(SketchLine_4.result())
     sketch.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
-    sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
-    sketch.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
     sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+    sketch.setEqual(SketchLine_3.result(), SketchLine_4.result())
+
+    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", centre.name()), False)
+    SketchPoint_1 = SketchProjection_1.createdFeature()
 
     ### Create SketchLine
     SketchLine_5 = sketch.addLine(-taille/2., taille/2., taille/2., -taille/2.)
     SketchLine_5.setAuxiliary(True)
+    sketch.setCoincident(SketchLine_1.startPoint(), SketchLine_5.startPoint())
+    sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_5.endPoint())
+    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_5.result())
 
     ### Create SketchLine
     SketchLine_6 = sketch.addLine(taille/2., taille/2., -taille/2., -taille/2.)
     SketchLine_6.setAuxiliary(True)
-    sketch.setCoincident(SketchLine_1.startPoint(), SketchLine_5.startPoint())
     sketch.setCoincident(SketchLine_2.startPoint(), SketchLine_6.startPoint())
-    sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_5.endPoint())
     sketch.setCoincident(SketchLine_4.startPoint(), SketchLine_6.endPoint())
-    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_5.result())
     sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_6.result())
-    sketch.setHorizontal(SketchLine_1.result())
-    sketch.setVertical(SketchLine_2.result())
-    sketch.setHorizontal(SketchLine_3.result())
-    sketch.setVertical(SketchLine_4.result())
-    sketch.setLength(SketchLine_3.result(), nom_par_1)
-    sketch.setEqual(SketchLine_3.result(), SketchLine_4.result())
 
     model.do()
 
     nom_sketch = "{}_esquisse".format(self.nom_solide)
-    sketch.setName(nom_sketch)
-    sketch.result().setName(nom_sketch)
+    nommage (sketch, nom_sketch)
+
+    #print ("fin de {}".format(nom_fonction))
 
     return sketch
 
 #===========================  Fin de la méthode ==================================
 
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_plane_1_b ( self, solide, sketch, v_norm, d_face_1_2, n_recur ):
+    """Crée la face médiane entre deux autres - cas des surfaces planes
+
+Création de la face médiane
+
+Entrées :
+  :solide: l'objet solide à traiter
+  :sketch: l'esquisse
+  :v_norm: vecteur normal
+  :d_face_1_2: la distance entre les deux faces
+  :n_recur: niveau de récursivité
+
+Sorties :
+  :face: la face médiane
+"""
+
+    nom_fonction = __name__ + "/_cree_face_mediane_plane_1_b"
+    blabla = "Dans {} :".format(nom_fonction)
+    if self._verbose_max:
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "Esquisse : ", sketch.name())
+      print_tab (n_recur, "Distance entre les deux faces : ", d_face_1_2)
+
+    ### Create LinearCopy
+    LinearCopy_1 = model.addMultiTranslation(self.part_doc, [model.selection("SOLID", self.nom_solide_aux)], model.selection("EDGE", "PartSet/OX"), 0, 1, keepSubResults = True)
+    nom = "{}_0".format(self.nom_solide_aux)
+    nommage (LinearCopy_1, nom)
+
+    ### Create Recover
+    Recover_1 = model.addRecover(self.part_doc, LinearCopy_1, [solide])
+    nom = "{}_1".format(self.nom_solide_aux)
+    nommage (Recover_1, nom)
+
+    # Création d'une face ; on la translate d'une demi-épaisseur.
+    for iaux in range(2):
+
+      distance = -0.5*d_face_1_2*float(2*iaux-1)
+      nom_solide = "{}_{}".format(self.nom_solide_aux,iaux)
+      face = self._cree_face_mediane_plane_2 ( sketch.name(), v_norm.name(), nom_solide, distance, iaux, n_recur )
+
+      if face.results():
+        face = self._cree_face_mediane_plane_11 ( face, Recover_1, n_recur )
+        break
+      # Si l'intersection est vide, on la translate dans l'autre sens
+      else:
+        if self._verbose_max:
+          print_tab (n_recur, "L'intersection est vide.")
+        face = None
+
+    #print ("fin de {}".format(nom_fonction))
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
 #=========================== Début de la méthode =================================
 
   def _cree_face_mediane_plane_11 ( self, face, Recover_1, n_recur ):
@@ -1178,9 +1179,9 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_plane_11"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face : ", face.name())
 
     # Si on traite un objet solide unique, on le récupère
@@ -1203,7 +1204,7 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, distance, icpt=0 ):
+  def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, distance, icpt, n_recur ):
     """Crée la face médiane entre deux autres - cas des surfaces planes
 
 Intersection de la face avec le solide
@@ -1220,25 +1221,23 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_plane_2"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
     if self._verbose_max:
-      texte = blabla
-      texte += "nom_sketch   : {}\n".format(nom_sketch)
-      texte += "nom_normal   : {}\n".format(nom_normal)
-      texte += "nom_solide   : {}\n".format(nom_solide)
-      texte += "distance : {}".format(distance)
-      print (texte)
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "nom_sketch : ", nom_sketch)
+      print_tab (n_recur, "nom_normal : ", nom_normal)
+      print_tab (n_recur, "nom_solide : ", nom_solide)
+      print_tab (n_recur, "distance   : ", distance)
 
     # Création d'une face
     Face_1 = model.addFace(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(nom_sketch))])
     nom_face_1 = "{}_face_1_{}".format(self.nom_solide_aux,icpt)
-    Face_1.result().setName(nom_face_1)
+    nommage (Face_1, nom_face_1)
 
 #   On la translate
     Translation_1 = model.addTranslation(self.part_doc, [model.selection("FACE", nom_face_1)], axis = model.selection("EDGE", nom_normal), distance = distance, keepSubResults = True)
     nom_trans = "{}_trans_{}".format(self.nom_solide_aux,icpt)
-    Translation_1.setName(nom_trans)
-    Translation_1.result().setName(nom_trans)
+    nommage (Translation_1, nom_trans)
     Translation_1.result().setColor(85, 0, 255)
 
 #   Intersection de cette face avec le solide initial
@@ -1263,7 +1262,7 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_plane_3"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
     if self._verbose_max:
       texte = blabla
       print (texte)
@@ -1299,11 +1298,11 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_cylindre"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1315,7 +1314,7 @@ Sorties :
 
 #   Création de la face
     if not erreur:
-      face = self._cree_face_mediane_cylindre_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur )
+      face = self._cree_face_mediane_cylindre_1 ( (coo_x, coo_y, coo_z), (axe_x, axe_y, axe_z), rayon, hauteur, n_recur )
     else:
       self._couleur_objet (solide, n_recur, coul_r=0, coul_g=0, coul_b=255)
       face = None
@@ -1345,10 +1344,10 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_cylindre_0"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1362,8 +1361,8 @@ Sorties :
     axe_z = caract_face_1[2][6]
 #   Rayons
     rayon = (caract_face_2[2][7]+caract_face_1[2][7])/2.
-#   Hauteur : la diagonale de la boîte englobante permet d'être certain de tout prendre
-    l_diag = self._calcul_boite_englobante ( solide, n_recur )
+#   Hauteur : une longueur caractéristique pour être certain de tout prendre
+    l_diag = self._calcul_lg_caract ( solide, n_recur )
     hauteur = 10.*l_diag
     if self._verbose_max:
       print_tab (n_recur, "Hauteur englobante : ", hauteur)
@@ -1376,7 +1375,7 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_cylindre_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur ):
+  def _cree_face_mediane_cylindre_1 ( self, coo_c, v_axe, rayon, hauteur, n_recur ):
     """Crée la face médiane entre deux autres - cas des cylindres
 
 Création des objets temporaires et de la face externe du cylindre support
@@ -1386,62 +1385,112 @@ Entrées :
   :axe_x, axe_y, axe_z: coordonnées de l'axe
   :rayon: rayon moyen entre les deux faces
   :hauteur: hauteur du cylindre
+  :n_recur: niveau de récursivité
 
 Sorties :
   :face: la face médiane
 """
     nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
 #   Les caractéristiques du cylindre à créer
     if self._verbose_max:
-      texte = blabla
-      texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
-      texte += "Axe    : ({}, {}, {})\n".format(axe_x, axe_y, axe_z)
-      texte += "Rayon : {}\n".format(rayon)
-      texte += "Hauteur : {}".format(hauteur)
-      print (texte)
-
-#   Création du point central
-    centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
-    nom_centre = "{}_centre".format(self.nom_solide)
-    centre.result().setName(nom_centre)
-
-#   Création de l'axe
-    axe = model.addAxis(self.part_doc, axe_x, axe_y, axe_z)
-    nom_axe = "{}_axe".format(self.nom_solide)
-    axe.result().setName(nom_axe)
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "Centre  : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
+      print_tab (n_recur, "Axe     : ({}, {}, {})".format(v_axe[0], v_axe[1], v_axe[2]))
+      print_tab (n_recur, "Rayon   : ", rayon)
+      print_tab (n_recur, "Hauteur : ", hauteur)
 
-#   Création du plan perpendiculaire à l'axe
-    plan = model.addPlane(self.part_doc, model.selection("EDGE", nom_axe), model.selection("VERTEX", nom_centre), True)
-    nom_plan = "{}_plan".format(self.nom_solide)
-    plan.result().setName(nom_plan)
-
-#   Création de l'esquisse
+# 1. Objets préalables
     nom_par_1 = "{}_R".format(self.nom_solide)
     model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon))
     nom_par_2 = "{}_H".format(self.nom_solide)
     model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(hauteur))
 
-    sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
+    centre, _, plan = self._cree_centre_axe_plan ( coo_c, v_axe, self.nom_solide, n_recur )
 
-    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
+# 2. Création de l'esquisse
+    sketch = self._cree_face_mediane_cylindre_1_a ( plan, centre, rayon, nom_par_1, n_recur )
+
+# 3. La face
+    face = self._cree_face_mediane_cylindre_1_b ( sketch, nom_par_2, n_recur )
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cylindre_1_a ( self, plan, centre, rayon, nom_par_1, n_recur ):
+    """Crée la face médiane entre deux autres - cas des cylindres
+
+Création des objets temporaires et de la face externe du cylindre support
+
+Entrées :
+  :coo_x, coo_y, coo_z: coordonnées du centre de la base
+  :axe_x, axe_y, axe_z: coordonnées de l'axe
+  :rayon: rayon moyen entre les deux faces
+  :nom_par_1: nom_par_1
+  :n_recur: niveau de récursivité
+
+Sorties :
+  :face: la face médiane
+"""
+    nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1_a"
+    blabla = "Dans {} :\n".format(nom_fonction)
+
+#   Les caractéristiques du cylindre à créer
+    if self._verbose_max:
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "Plan      : {}".format(plan.name()))
+      print_tab (n_recur, "Centre    : {}".format(centre.name()))
+      print_tab (n_recur, "Rayon   : ", rayon)
+
+    sketch = model.addSketch(self.part_doc, model.selection("FACE", plan.name()))
+
+    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", centre.name()), False)
     SketchPoint_1 = SketchProjection_1.createdFeature()
 
     SketchCircle_1 = sketch.addCircle(0., 0., rayon)
     sketch.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
     sketch.setRadius(SketchCircle_1.results()[1], nom_par_1)
     model.do()
+
     nom_sketch = "{}_esquisse".format(self.nom_solide)
-    sketch.setName(nom_sketch)
-    sketch.result().setName(nom_sketch)
+    nommage (sketch, nom_sketch)
+
+    return sketch
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cylindre_1_b ( self, sketch, nom_par_2, n_recur ):
+    """Crée la face médiane entre deux autres - cas des cylindres
+
+Création des objets temporaires et de la face externe du cylindre support
+
+Entrées :
+  :sketch: l'esquisse
+  :n_recur: niveau de récursivité
+
+Sorties :
+  :face: la face médiane
+"""
+    nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1_b"
+    blabla = "Dans {} :\n".format(nom_fonction)
+
+#   Les caractéristiques du cylindre à créer
+    if self._verbose_max:
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "Esquisse : ", sketch.name())
+      print_tab (n_recur, "nom_par_2 : ", nom_par_2)
 
 #   Création du cylindre complet
-    cylindre = model.addExtrusion(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(nom_sketch))], model.selection(), nom_par_2, nom_par_2, "Edges")
+    cylindre = model.addExtrusion(self.part_doc, [model.selection("COMPOUND", "all-in-{}".format(sketch.name()))], model.selection(), nom_par_2, nom_par_2, "Edges")
+
     nom_cylindre = "{}_cylindre".format(self.nom_solide)
-    cylindre.setName(nom_cylindre)
-    cylindre.result().setName(nom_cylindre)
-    cylindre.result().setColor(85, 0, 255)
+    nommage (cylindre, nom_cylindre, (85, 0, 255))
 
 #   Intersection de la face cylindrique avec le solide initial
     face = self._creation_face_inter ( nom_cylindre )
@@ -1464,11 +1513,11 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_sphere"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1506,11 +1555,11 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_sphere_0"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1543,7 +1592,7 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_sphere_1"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
 #   Les caractéristiques de la sphère à créer
     if self._verbose_max:
@@ -1594,10 +1643,9 @@ Sorties :
 
 #   Création de la sphère complète
     sphere = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", "{}/{}".format(nom_sketch,nom_ligne)), 360, 0, "Edges")
+
     nom_sphere = "{}_sphere".format(self.nom_solide)
-    sphere.setName(nom_sphere)
-    sphere.result().setName(nom_sphere)
-    sphere.result().setColor(85, 0, 255)
+    nommage (sphere, nom_sphere, (85, 0, 255))
 
 #   Intersection de la face sphérique avec le solide initial
     face = self._creation_face_inter ( nom_sphere )
@@ -1620,11 +1668,11 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_tore"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1663,11 +1711,11 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_tore_0"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1705,7 +1753,7 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_tore_1"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
@@ -1776,11 +1824,10 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_cone ( self, geompy, caract_face_1, caract_face_2, n_recur ):
+  def _cree_face_mediane_cone ( self, caract_face_1, caract_face_2, n_recur ):
     """Crée la face médiane entre deux autres - cas des cones
 
 Entrées :
-  :geompy: environnement de GEOM
   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
   :n_recur: niveau de récursivité
 
@@ -1789,16 +1836,16 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_cone"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
 #   Caractéristiques des cones
-    coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur = self._cree_face_mediane_cone_0 ( geompy, caract_face_1, caract_face_2, n_recur )
+    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 )
 
 #   Contrôle de la validité de l'épaisseur (bidon)
     erreur = self._verif_epaisseur ( EP_MIN*10. )
@@ -1815,13 +1862,12 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _cree_face_mediane_cone_0 ( self, geompy, caract_face_1, caract_face_2, n_recur ):
+  def _cree_face_mediane_cone_0 ( self, caract_face_1, caract_face_2, n_recur ):
     """Crée la face médiane entre deux autres - cas des cones
 
 Décodage des caractéristiques
 
 Entrées :
-  :geompy: environnement de GEOM
   :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
   :n_recur: niveau de récursivité
 
@@ -1833,11 +1879,11 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_cree_face_mediane_cone_0"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
       print_tab (n_recur, "face_1 : ", caract_face_1)
       print_tab (n_recur, "face_2 : ", caract_face_2)
 
@@ -1850,30 +1896,23 @@ Sorties :
     axe_y = caract_face_1[2][5]
     axe_z = caract_face_1[2][6]
 #   Rayons
-#   Pour un cone complet, les caractéristiques fournies par GEOM sont correctes
-#   Mais s'il est découpé, malheureusement,bug dans GEOM et caract_face_2[2][8] est toujours nul !
-#   Alors on passe par le décodage des arêtes
-    #rayon_1 = (caract_face_2[2][7]+caract_face_1[2][7])/2.
-    #rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
-    caract_arete_face_1 = self._calcul_caract_aretes_face ( geompy, caract_face_1 )
-    caract_arete_face_2 = self._calcul_caract_aretes_face ( geompy, caract_face_2 )
-    rayon_1 = 0.
-    rayon_2 = 0.
-    for caract_aretes_face in [caract_arete_face_1,caract_arete_face_2]:
-      prem = True
-      for l_aux in caract_aretes_face:
-        if ( l_aux[0] in ( geompy.kind.CIRCLE, geompy.kind.ARC_CIRCLE ) ):
-          #print ("R =",l_aux[7])
-          if prem:
-            rayon_1 += l_aux[7]
-            prem = False
-          else:
-            rayon_2 += l_aux[7]
-    rayon_1 *= 0.5
-    rayon_2 *= 0.5
+    rayon_1 = (caract_face_2[2][7]+caract_face_1[2][7])/2.
+    rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
 #   Hauteur
     hauteur = caract_face_1[2][9]
 
+#   Bilan
+    if self._verbose_max:
+      print_tab (n_recur, "coo_x : ", coo_x)
+      print_tab (n_recur, "coo_y : ", coo_y)
+      print_tab (n_recur, "coo_z : ", coo_z)
+      print_tab (n_recur, "axe_x : ", axe_x)
+      print_tab (n_recur, "axe_y : ", axe_y)
+      print_tab (n_recur, "axe_z : ", axe_z)
+      print_tab (n_recur, "rayon_1 : ", rayon_1)
+      print_tab (n_recur, "rayon_2 : ", rayon_2)
+      print_tab (n_recur, "hauteur : ", hauteur)
+
     return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur
 
 #===========================  Fin de la méthode ==================================
@@ -1895,7 +1934,7 @@ Sorties :
   :face: la face externe du cone support
 """
     nom_fonction = __name__ + "/_cree_face_mediane_cone_1"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
 #   Les deux faces
     if self._verbose_max:
@@ -1906,22 +1945,33 @@ Sorties :
       texte += "Hauteur : {}".format(hauteur)
       print (texte)
 
-#   Création du point central
-    centre = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
-    nom_centre = "{}_centre".format(self.nom_solide)
-    centre.result().setName(nom_centre)
+#   1. Création du point central de la base, côté rayon_1
+    centre_1 = model.addPoint(self.part_doc, coo_x, coo_y, coo_z)
+    nom_centre_1 = "{}_centre_1".format(self.nom_solide)
+    centre_1.result().setName(nom_centre_1)
 
-#   Création de l'axe
-    axe = model.addAxis(self.part_doc, axe_x, axe_y, axe_z)
+#   2. Création du point central, du côté de rayon_2
+    centre_2 = model.addPoint(self.part_doc, coo_x+hauteur*axe_x, coo_y+hauteur*axe_y, coo_z+hauteur*axe_z)
+    nom_centre_2 = "{}_centre_2".format(self.nom_solide)
+    centre_2.result().setName(nom_centre_2)
+
+#   3. Création de l'axe
+    axe = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre_1), model.selection("VERTEX", nom_centre_2))
     nom_axe = "{}_axe".format(self.nom_solide)
     axe.result().setName(nom_axe)
 
-#   Création d'un plan passant par ce centre et cet axe
-    plan = model.addPlane(self.part_doc, model.selection("EDGE", nom_axe), model.selection("VERTEX", nom_centre), False)
+#   4. Création d'un plan passant par le centre de la base et l'axe
+#   4.1. Création d'un vecteur perpendiculaire à l'axe
+    coeff = 10.
+    v_perp = model.addAxis(self.part_doc, -coeff*axe_y, coeff*axe_x, 0.)
+    nom_v_perp = "{}_v_perp".format(self.nom_solide)
+    v_perp.result().setName(nom_v_perp)
+#   4.2. Création du plan
+    plan = model.addPlane(self.part_doc, model.selection("EDGE",nom_v_perp), model.selection("VERTEX", nom_centre_1), True)
     nom_plan = "{}_plan".format(self.nom_solide)
     plan.result().setName(nom_plan)
 
-#   Création de l'esquisse
+#   5. Paramétrage
     nom_par_1 = "{}_R_1".format(self.nom_solide)
     model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon_1))
     nom_par_2 = "{}_R_2".format(self.nom_solide)
@@ -1929,34 +1979,50 @@ Sorties :
     nom_par_3 = "{}_H".format(self.nom_solide)
     model.addParameter(self.part_doc, "{}".format(nom_par_3), "{}".format(hauteur))
 
+#   6. Création de l'esquisse
+
     sketch = model.addSketch(self.part_doc, model.selection("FACE", nom_plan))
 
-    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), False)
+#   6.1. Projection des centres et de l'axe
+    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre_1), False)
     SketchPoint_1 = SketchProjection_1.createdFeature()
+    sk_coo_x_1 = SketchAPI_Point(SketchPoint_1).coordinates().x()
+    sk_coo_y_1 = SketchAPI_Point(SketchPoint_1).coordinates().y()
 
-    SketchProjection_2 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
-    SketchLine_1 = SketchProjection_2.createdFeature()
-
-    SketchLine_2 = sketch.addLine(coo_x, coo_y, coo_x+rayon_1, coo_y+hauteur)
-    SketchLine_2.setAuxiliary(True)
-    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.startPoint())
-    sketch.setParallel(SketchLine_1.result(), SketchLine_2.result())
-    sketch.setLength(SketchLine_2.result(), nom_par_3)
+    SketchProjection_2 = sketch.addProjection(model.selection("VERTEX", nom_centre_2), False)
+    SketchPoint_2 = SketchProjection_2.createdFeature()
+    sk_coo_x_2 = SketchAPI_Point(SketchPoint_2).coordinates().x()
+    sk_coo_y_2 = SketchAPI_Point(SketchPoint_2).coordinates().y()
 
-    SketchLine_3 = sketch.addLine(coo_x+rayon_1, coo_y, coo_x+rayon_1, coo_y+hauteur)
-    sketch.setDistance(SketchLine_2.startPoint(), SketchLine_3.result(), nom_par_1, True)
-    sketch.setDistance(SketchLine_2.endPoint(), SketchLine_3.result(), nom_par_2, True)
-    sketch.setLength(SketchLine_3.result(), "2.5*{}".format(nom_par_3))
+    SketchProjection_3 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
+    SketchLine_0 = SketchProjection_3.createdFeature()
 
-    SketchPoint_2 = sketch.addPoint(coo_x, coo_y)
-    sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_3.result())
-    sketch.setMiddlePoint(SketchPoint_2.coordinates(), SketchLine_3.result())
+#   6.2. Lignes perpendiculaires à l'axe passant par les centres
+    SketchLine_1 = sketch.addLine(sk_coo_x_1, sk_coo_y_1, sk_coo_x_1+rayon_1, sk_coo_y_1)
+    SketchLine_1.setAuxiliary(True)
+    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.startPoint())
+    sketch.setPerpendicular(SketchLine_0.result(), SketchLine_1.result())
+    sketch.setLength(SketchLine_1.result(), nom_par_1)
 
-    SketchLine_4 = sketch.addLine(coo_x, coo_y, 1.2*coo_x, 1.2*coo_y)
-    SketchLine_4.setAuxiliary(True)
-    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.startPoint())
-    sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_4.endPoint())
-    sketch.setHorizontal(SketchLine_4.result())
+    SketchLine_2 = sketch.addLine(sk_coo_x_2, sk_coo_y_2, sk_coo_x_2+rayon_2, sk_coo_y_2)
+    SketchLine_2.setAuxiliary(True)
+    sketch.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_2.startPoint())
+    sketch.setPerpendicular(SketchLine_0.result(), SketchLine_2.result())
+    sketch.setLength(SketchLine_2.result(), nom_par_2)
+
+#   6.3. Ligne joignant les extrémités des précédentes et point milieu
+    SketchLine_3 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
+    sketch.setCoincident(SketchLine_3.startPoint(), SketchLine_1.endPoint())
+    sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_2.endPoint())
+    SketchLine_3.setAuxiliary(True)
+    SketchPoint_3 = sketch.addPoint(sk_coo_x_1, sk_coo_y_1)
+    sketch.setMiddlePoint(SketchLine_3.result(), SketchPoint_3.coordinates())
+
+#   6.4. Ligne support de la future révolution
+    SketchLine_4 = sketch.addLine(sk_coo_x_1+rayon_1, sk_coo_y_1, sk_coo_x_2+rayon_2, sk_coo_y_2)
+    sketch.setMiddlePoint(SketchLine_4.result(), SketchPoint_3.coordinates())
+    sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_4.result())
+    sketch.setLength(SketchLine_4.result(), "1.2*{}".format(nom_par_3))
 
     model.do()
     nom_sketch = "{}_esquisse".format(self.nom_solide)
@@ -1965,7 +2031,7 @@ Sorties :
 
 #   Création du cone complet
     nom_cone = "{}_cone".format(self.nom_solide)
-    self._cree_revolution ( nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_cone )
+    self._cree_revolution ( nom_sketch, nom_centre_1, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_cone )
 
 #   Intersection de la face conique avec le solide initial
     face = self._creation_face_inter ( nom_cone )
@@ -1974,54 +2040,137 @@ Sorties :
 
 #===========================  Fin de la méthode ==================================
 
+#=========================== Début de la méthode =================================
+
+  def _cree_centre_axe_plan ( self, coo_c, vnor, prefixe, n_recur ):
+    """Crée un centre, un axe, un plan
+
+Préparatifs
+
+Entrées :
+  :coo_c: coordonnées du centre de la base
+  :vnor: coordonnées du vecteur normal
+  :prefix: prefixe du nom des objets
+  :n_recur: niveau de récursivité
+
+Sorties :
+  :centre: centre
+  :normal: vecteur normal
+  :plan: plan
+"""
+
+    nom_fonction = __name__ + "/_cree_centre_axe_plan"
+    blabla = "Dans {} :".format(nom_fonction)
+    if self._verbose_max:
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "Centre   : ({}, {}, {})".format(coo_c[0], coo_c[1], coo_c[2]))
+      print_tab (n_recur, "Normale  : ({}, {}, {})".format(vnor[0], vnor[1], vnor[2]))
+
+#   Création du point central
+    centre = model.addPoint(self.part_doc, coo_c[0], coo_c[1], coo_c[2])
+    nom_centre = "{}_centre".format(prefixe)
+    nommage (centre, nom_centre)
+
+#   Création du vecteur normal
+    v_norm = model.addAxis(self.part_doc, vnor[0], vnor[1], vnor[2])
+    nom_vnorm = "{}_normale".format(prefixe)
+    nommage (v_norm, nom_vnorm)
+
+#   Création du plan perpendiculaire au vecteur normal
+    plan = model.addPlane(self.part_doc, model.selection("EDGE", v_norm.name()), model.selection("VERTEX", centre.name()), True)
+    nom_plan = "{}_plan".format(prefixe)
+    nommage (plan, nom_plan)
+
+    #print ("fin de {}".format(nom_fonction))
+
+    return centre, v_norm, plan
+
+#===========================  Fin de la méthode ==================================
+
 #=========================== Début de la méthode =================================
 
   def _calcul_boite_englobante ( self, objet, n_recur ):
     """Crée la hauteur englobant à coup sûr l'objet
 
+Remarque : pour une raison inconnue, le calcul de la boître englobante fait planter
+           en mode GUI. On controune l'obstacle enclculantr une lingueur caractéristique
+
 Entrées :
   :objet: l'objet à traiter
   :n_recur: niveau de récursivité
 
 Sorties :
-  :l_diag: longueur de la diagonale de la boîte englobante
+  :l_caract: longueur caractéristique ; longueur de la diagonale de la boîte englobante
 """
 
     nom_fonction = __name__ + "/_calcul_boite_englobante"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
 
 #   Hauteur : la diagonale de la boîte englobante permet d'être certain de tout prendre
-    if self._verbose_max:
-      print_tab (n_recur, "Création de la boite englobante pour l'objet ", objet.name())
-      print_tab (n_recur, "de type ", objet.shapeType())
-    #print ('bbox = model.getBoundingBox(self.part_doc, model.selection("{}", "{}"))'.format(objet.shapeType(),objet.name()))
-    bbox = model.getBoundingBox(self.part_doc, model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
-    bbox.execute(True)
+    #if self._verbose_max:
+      #print_tab (n_recur, "Création de la boite englobante pour l'objet ", objet.name())
+      #print_tab (n_recur, "de type ", objet.shapeType())
+    #bbox = model.getBoundingBox(self.part_doc, model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
+    #bbox.execute(True)
+
+    #bbox_nom = bbox.result().name()
+    #if self._verbose_max:
+      #print_tab (n_recur, "Boîte englobante : '{}' '{}'".format(bbox.name(), bbox_nom))
+
+    #saux_0 = "[{}/Back]".format(bbox_nom)
+    #saux_0 +="[{}/Left]".format(bbox_nom)
+    #saux_0 +="[{}/Bottom]".format(bbox_nom)
+    #saux_1 = "[{}/Front]".format(bbox_nom)
+    #saux_1 +="[{}/Right]".format(bbox_nom)
+    #saux_1 +="[{}/Top]".format(bbox_nom)
+    #if self._verbose_max:
+      #coo_min = model.getPointCoordinates(self.part_doc, model.selection("VERTEX", saux_0))
+      #coo_max = model.getPointCoordinates(self.part_doc, model.selection("VERTEX", saux_1))
+      #texte = "Xmin = {}, Xmax = {}\n".format(coo_min[0],coo_max[0])
+      #texte += "\tYmin = {}, Ymax = {}\n".format(coo_min[1],coo_max[1])
+      #texte += "\tZmin = {}, Zmax = {}".format(coo_min[2],coo_max[2])
+      #print_tab (n_recur, texte)
+
+    #l_caract = model.measureDistance(self.part_doc, model.selection("VERTEX", saux_0), model.selection("VERTEX", saux_1) )
+    properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
+    l_caract = properties[0]
+
+    if self._verbose_max:
+      print_tab (n_recur, "Longueur caractéristique : ", l_caract)
+
+    return l_caract
 
-    bbox_nom = bbox.name()
-    if self._verbose_max:
-      print_tab (n_recur, "Boîte englobante : '{}' '{}'".format(bbox.name(), bbox.result().name()))
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _calcul_lg_caract ( self, objet, n_recur ):
+    """Crée une longueur caractéristique de l'objet
+
+Entrées :
+  :objet: l'objet à traiter
+  :n_recur: niveau de récursivité
+
+Sorties :
+  :l_caract: longueur caractéristique de l'objet
+"""
+
+    nom_fonction = __name__ + "/_calcul_lg_caract"
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      coo_min = model.getPointCoordinates(self.part_doc, \
-      model.selection("VERTEX", "[{}_1/Back][{}_1/Left][{}_1/Bottom]".format(bbox_nom,bbox_nom,bbox_nom)))
-      coo_max = model.getPointCoordinates(self.part_doc, \
-      model.selection("VERTEX", "[{}_1/Front][{}_1/Right][{}_1/Top]".format(bbox_nom,bbox_nom,bbox_nom)))
-      texte = "Xmin = {}, Xmax = {}\n".format(coo_min[0],coo_max[0])
-      texte += "\tYmin = {}, Ymax = {}\n".format(coo_min[1],coo_max[1])
-      texte += "\tZmin = {}, Zmax = {}".format(coo_min[2],coo_max[2])
-      print_tab (n_recur, texte)
+      print_tab (n_recur, blabla)
+
+    properties = model.getGeometryCalculation(self.part_doc,model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
+    l_caract = properties[0]
 
-    l_diag = model.measureDistance(self.part_doc, \
-      model.selection("VERTEX", "[{}_1/Back][{}_1/Left][{}_1/Bottom]".format(bbox_nom,bbox_nom,bbox_nom)), \
-      model.selection("VERTEX", "[{}_1/Front][{}_1/Right][{}_1/Top]".format(bbox_nom,bbox_nom,bbox_nom)) )
     if self._verbose_max:
-      print_tab (n_recur, "Longueur de la diagonale : ", l_diag)
+      print_tab (n_recur, "Longueur caractéristique : ", l_caract)
 
-    return l_diag
+    return l_caract
 
 #===========================  Fin de la méthode ==================================
 
@@ -2041,7 +2190,7 @@ Entrées :
 """
 
     nom_fonction = __name__ + "/_cree_revolution"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
     if self._verbose_max:
       texte = blabla
@@ -2061,11 +2210,8 @@ Entrées :
 
 #   Création de l'objet complet
     objet = model.addRevolution(self.part_doc, [model.selection("COMPOUND", nom_sketch)], model.selection("EDGE", nom_axe_r), 360, 0, "Edges")
-    objet.setName(nom_objet)
-    objet.result().setName(nom_objet)
-    objet.result().setColor(85, 0, 255)
 
-    return
+    nommage (objet, nom_objet, (85, 0, 255))
 
 #===========================  Fin de la méthode ==================================
 
@@ -2085,7 +2231,7 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_creation_face_inter"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :\n".format(nom_fonction)
 
     if self._verbose_max:
       print (blabla)
@@ -2098,13 +2244,11 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def face_mediane_solide (self, solide, geompy, objet_geom, n_recur=0):
+  def face_mediane_solide (self, solide, n_recur=0):
     """Calcul de la face médiane pour un solide
 
 Entrées :
   :solide: solide SHAPER à traiter
-  :geompy: environnement de GEOM
-  :objet_geom: l'objet solide à traiter au format GEOM
   :n_recur: niveau de récursivité
 
 Sorties :
@@ -2113,10 +2257,10 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/face_mediane_solide"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla, saut_av=True)
     if self._verbose:
       print_tab (n_recur, "Traitement du solide ", solide.name())
 
@@ -2127,25 +2271,19 @@ Sorties :
 
     while not erreur :
 
-# 2. Explosion du solide en faces
-
-      erreur, message, l_faces_geom, l_faces = self._faces_du_solide ( geompy, objet_geom, solide, n_recur )
-      if erreur:
-        break
-
-# 3. Calcul des caractéristiques géométriques des faces
+# 2. Calcul des caractéristiques géométriques des faces
 
-      tb_caract = self._calcul_caract_faces ( geompy, l_faces_geom )
+      tb_caract = self._calcul_caract_faces ( solide, n_recur )
 
-# 4. Tri des faces en fonction de leurs caractéristiques géométriques
+# 3. Tri des faces en fonction de leurs caractéristiques géométriques
 
-      erreur, message, caract_face_1, caract_face_2 = self._tri_faces ( tb_caract )
+      erreur, message, caract_face_1, caract_face_2 = self._tri_faces ( tb_caract, n_recur )
       if erreur:
         break
 
-# 5. Création de la face médiane
+# 4. Création de la face médiane
 
-      erreur, face = self._cree_face_mediane ( solide, geompy, caract_face_1, caract_face_2, n_recur )
+      erreur, face = self._cree_face_mediane ( solide, caract_face_1, caract_face_2, n_recur )
       if erreur:
         break
 
@@ -2170,12 +2308,11 @@ Sorties :
 
 #=========================== Début de la méthode =================================
 
-  def _traitement_objet (self, solide=None, objet_geom=None, n_recur=0):
+  def _traitement_objet (self, solide, n_recur=0):
     """Traitement d'un objet
 
 Entrées :
   :solide: solide SHAPER à traiter
-  :objet_geom: l'objet GEOM équivalent
   :n_recur: niveau de récursivité
 
 Sorties :
@@ -2184,59 +2321,39 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_traitement_objet"
-    blabla = "\nDans {} :".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
-      print_tab (n_recur, "solide = " , solide)
-      print_tab (n_recur, "objet_geom = ", objet_geom)
-
-# 1. Préalables
-
-    erreur = 0
-    message = ""
+      print_tab (n_recur, blabla, saut_av=True)
+      texte = "solide = {} ".format(solide.name())
+      print_tab (n_recur, texte, solide)
 
-    while not erreur :
-
-# 2. L'aide
-
-      if self.affiche_aide_globale :
-        break
-
-# 3. Les imports pour salomé
-      geompy = geomBuilder.New()
-
-# 4. En cas d'exportation step, répertoire de travail associé à l'éventuel fichier de départ
+# 1. En cas d'exportation step, répertoire de travail associé à l'éventuel fichier de départ
 #    Attention à ne pas recréer le répertoire à chaque fois
-      if self._export_step:
+    if self._export_step:
+
+      if self.rep_step is None:
 
         if self._verbose_max:
           print_tab (n_recur, "Préparation de l'export STEP")
 
-        if self.rep_step is None:
-          if self.ficcao is None:
-            self.rep_step = tempfile.mkdtemp(prefix="{}_".format(self.objet_principal.name()))
+        if self.ficcao is None:
+          self.rep_step = tempfile.mkdtemp(prefix="{}_".format(self.objet_principal.name()))
+        else:
+          self.rep_step = os.path.join(os.path.dirname(self.ficcao),"{}_M".format(self.objet_principal.name()))
+          if os.path.isdir(self.rep_step):
+            l_aux = os.listdir(self.rep_step)
+            for nomfic in l_aux:
+              os.remove(os.path.join(self.rep_step,nomfic))
           else:
-            self.rep_step = os.path.join(os.path.dirname(self.ficcao),"{}_M".format(self.objet_principal.name()))
-            if os.path.isdir(self.rep_step):
-              l_aux = os.listdir(self.rep_step)
-              for nomfic in l_aux:
-                os.remove(os.path.join(self.rep_step,nomfic))
-            else:
-              os.mkdir(self.rep_step)
-        if self._verbose_max:
-          print_tab (n_recur, "Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
-
-# 5. Calcul réel de la face médiane
+            os.mkdir(self.rep_step)
 
-      if solide is None:
-        self.nom_solide = objet_geom.GetName()
+      if self._verbose_max:
+        print_tab (n_recur, "Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
 
-      erreur, message = self.face_mediane_solide (solide, geompy, objet_geom, n_recur)
-      if erreur:
-        break
+# 2. Calcul réel de la face médiane
 
-      break
+    erreur, message = self.face_mediane_solide (solide, n_recur)
 
     return erreur, message
 
@@ -2257,7 +2374,7 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/surf_fic_cao"
-    blabla = "\nDans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
       print (blabla)
@@ -2269,6 +2386,9 @@ Sorties :
 
     while not erreur :
 
+      if self.affiche_aide_globale:
+        break
+
 # 1. Définition de la pièce
 
       self.part_doc = model.activeDocument()
@@ -2322,28 +2442,40 @@ Sorties :
     if self._verbose_max:
       print (blabla)
 
+    erreur = 0
+    message = ""
+
+    while not erreur :
+
+      if self.affiche_aide_globale:
+        break
+
 # 1. Acquisition de la liste des noms des sous-objets solides
 
-    self.d_statut_so = dict()
-    self.l_noms_so = list()
-    self.l_faces_m = list()
+      self.d_statut_so = dict()
+      self.l_noms_so = list()
+      self.l_faces_m = list()
 
-    _ = self._nom_sous_objets (objet, True)
-    if self._verbose_max:
-      print ("Noms des sous-objets : {}".format(self.l_noms_so))
+      _ = self._nom_sous_objets (objet, True)
+      if self._verbose_max:
+        print ("Noms des sous-objets : {}".format(self.l_noms_so))
 
 # 2. Les faces médianes
 
-    erreur, message = self._surf_objet_shaper_0 ( objet )
+      erreur, message = self._surf_objet_shaper_0 ( objet )
+      if erreur:
+        break
 
 # 3. Gestion des faces créées
 
-    self._surf_objet_shaper_1 ( )
+      self._surf_objet_shaper_1 ( )
 
 # 4. Futur message pour le résultat
 
-    if ( self._export_step and not erreur ):
-      message = "Les fichiers des CAO des surfaces sont dans le répertoire {}".format(self.rep_step)
+      if ( self._export_step and not erreur ):
+        message = "Les fichiers des CAO des surfaces sont dans le répertoire {}".format(self.rep_step)
+
+      break
 
     return erreur, message
 
@@ -2364,37 +2496,41 @@ Sorties :
 """
 
     nom_fonction = __name__ + "/_surf_objet_shaper_0"
-    blabla = "Dans {} :\n".format(nom_fonction)
+    blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      prefixe = ""
-      for _ in range(n_recur):
-        prefixe += "\t"
-      texte = "\n{}{}".format(prefixe,blabla)
-      texte += "{}n_recur = {}".format(prefixe,n_recur)
-      print (texte)
+      print_tab (n_recur, blabla)
+      print_tab (n_recur, "n_recur = ", n_recur)
 
     erreur = 0
     message = ""
 
     while not erreur :
 
-# 1. Au premier passage, il faut récupérer la pièce et garder la référence au résultat principal
+# 1. Au premier passage, il faut récupérer la pièce SHAPER et garder la référence au résultat principal
 
       if ( n_recur == 0 ):
-        objet_0, l_faces = self._surf_objet_shaper_00 (objet)
+        self.part_doc = model.activeDocument()
+        objet_0 = objet.result()
+        self.objet_principal = objet_0
+        objet_bis = objet.defaultResult().shape()
+        if self._verbose_max:
+          print_tab (0, "Examen de l'objet initial ", objet.result().name(), saut_av=True)
+          print_tab (0, "Type python : ", type(objet))
+          print_tab (0, "Type {} / {} ; volume = ".format(objet_bis.shapeType(),objet_bis.shapeTypeStr()), GeomAlgoAPI_ShapeTools.volume(objet_bis))
       else:
         objet_0 = objet
-        print_tab (n_recur, "Examen de l'objet ", objet.name(), saut_av=True)
-        print_tab (n_recur, "Type python : ", type(objet))
-        print_tab (n_recur, "Type ", objet.shapeType())
+        if self._verbose_max:
+          print_tab (n_recur, "Examen de l'objet ", objet.name(), saut_av=True)
+          print_tab (n_recur, "Type python : ", type(objet))
+          print_tab (n_recur, "shapeType : ", objet.shapeType())
 
 # 2. On descend dans l'arborescence des sous-objets jusqu'à en trouver un qui n'en n'a pas
 
       nb_sub_results = objet_0.numberOfSubs()
 
       if self._verbose_max:
-        print_tab (n_recur, "Examen de l'objet '{}' de type ".format(objet_0.name()), objet_0.shapeType())
+        print_tab (n_recur, "Examen de l'objet '{}' de type ".format(objet_0.name()), objet_0.shapeType(), saut_av=True)
         print_tab (n_recur, "objet.result().numberOfSubs() : ", nb_sub_results)
 
       for n_sobj in range(nb_sub_results):
@@ -2426,57 +2562,6 @@ Sorties :
 
 #===========================  Fin de la méthode ==================================
 
-#=========================== Début de la méthode =================================
-
-  def _surf_objet_shaper_00 (self, objet):
-    """Liste les faces d'un objet SHAPER passé en argument
-
-Entrées :
-  :objet: objet à traiter
-
-Sorties :
-  :objet_0: le résultat associé à l'objet
-  :l_faces: liste des faces
-"""
-
-    nom_fonction = __name__ + "/_surf_objet_shaper_00"
-    blabla = "Dans {} :\n".format(nom_fonction)
-
-    if self._verbose_max:
-      print (blabla)
-
-    self.part_doc = model.activeDocument()
-    objet_0 = objet.result()
-    self.objet_principal = objet_0
-    objet_bis = objet.defaultResult().shape()
-    print_tab (0, "Examen de l'objet ", objet.result().name(), saut_av=True)
-    print_tab (0, "Type python : ", type(objet))
-    print_tab (0, "Type {} / {} ; volume = ".format(objet_bis.shapeType(),objet_bis.shapeTypeStr()), GeomAlgoAPI_ShapeTools.volume(objet_bis))
-    l_volumes = list()
-    exp = GeomAPI_ShapeExplorer(objet_bis, GeomAPI_Shape.SOLID)
-    while exp.more():
-      l_volumes.append(exp.current().solid())
-      exp.next()
-
-    for ivolume, volume in enumerate(l_volumes):
-      print_tab (1, "Type python : ", type(volume))
-      print_tab (1, "Volume n°{} ; volume = ".format(ivolume), GeomAlgoAPI_ShapeTools.volume(volume))
-      print_tab (1, "Type {} / ".format(volume.shapeType()), volume.shapeTypeStr())
-      #print ("\tInformations : {}".format(volume.shapeInfo()))
-
-      l_faces = list()
-      exp = GeomAPI_ShapeExplorer(volume, GeomAPI_Shape.FACE)
-      while exp.more():
-        l_faces.append(exp.current().face())
-        exp.next()
-
-      for iface, face in enumerate(l_faces):
-        print_tab (2, "Face n°{} ; surface = ".format(iface), GeomAlgoAPI_ShapeTools.area(face))
-
-    return objet_0, l_faces
-
-#===========================  Fin de la méthode ==================================
-
 #=========================== Début de la méthode =================================
 
   def _surf_objet_shaper_1 (self, n_recur=0):
@@ -2494,7 +2579,7 @@ Sorties :
     blabla = "Dans {} :\n".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla)
 
 # 1. Informations sur les faces à problème
 
@@ -2513,15 +2598,34 @@ Sorties :
       if self._verbose_max:
         print_tab (n_recur, "Partitionnnement des faces créées.")
 
-      l_objets = list()
+# 2.1.1. Pour une raison mystérieuse, il faut commencer par les faces entières, puis mettre les sous-faces éventuelles
+      d_faces = dict()
+      for (face,_) in self.l_faces_m:
+        if not face.result().numberOfSubs():
+          d_faces[face.name()] = [face.name()]
       for (face,_) in self.l_faces_m:
-        l_objets.append(model.selection("COMPOUND", "all-in-{}".format(face.name())))
+        nb_sub_results = face.result().numberOfSubs()
+        if nb_sub_results:
+          laux = list()
+          for n_sobj in range(nb_sub_results):
+            laux.append(face.result().subResult(n_sobj).name())
+          d_faces[face.name()] = laux
+
+      l_objets = list()
+      for _, laux in d_faces.items():
+        for s_face_n in laux:
+          l_objets.append(model.selection("FACE", s_face_n))
 
       Partition_1 = model.addPartition(self.part_doc, l_objets, keepSubResults = True)
 
       Partition_1.result().setName("{}_M".format(self.objet_principal.name()))
-      for iaux, (face,_) in enumerate(self.l_faces_m):
-        Partition_1.result().subResult(iaux).setName("{}".format(face.name()))
+      iaux = 0
+      for face_n, laux in d_faces.items():
+        Partition_1.result().subResult(iaux).setName("{}".format(face_n))
+        if ( len(laux) > 1 ):
+          for jaux, s_face_n in enumerate(laux):
+            Partition_1.result().subResult(iaux).subResult(jaux).setName("{}_M".format(s_face_n))
+        iaux += 1
       self._couleur_objet (Partition_1, n_recur, coul_r=0, coul_g=170, coul_b=0)
 
 # 2.2. Récupération des faces individuelles
@@ -2537,6 +2641,10 @@ Sorties :
       for iaux, (face,_) in enumerate(self.l_faces_m):
         Recover_1.results()[iaux].setName("{}".format(face.name()))
         Recover_1.results()[iaux].setColor(0, 170, 0)
+        nb_sub_results = Recover_1.results()[iaux].numberOfSubs()
+        for n_sobj in range(nb_sub_results):
+          Recover_1.results()[iaux].subResult(n_sobj).setName("{}_{}".format(face.name(),n_sobj))
+          Recover_1.results()[iaux].subResult(n_sobj).setColor(0, 170, 0)
 
 # 2.3. Mise en dossier
 
@@ -2546,8 +2654,8 @@ Sorties :
       for (face,fonction_0) in self.l_faces_m:
         dossier = model.addFolder(self.part_doc, fonction_0, face)
         dossier.setName(face.name()[:-2])
-
-    return
+      dossier = model.addFolder(self.part_doc, Partition_1, Recover_1)
+      dossier.setName(self.objet_principal.name())
 
 #===========================  Fin de la méthode ==================================
 
@@ -2569,7 +2677,7 @@ Sorties :
     blabla = "Dans {} :".format(nom_fonction)
 
     if self._verbose_max:
-      print (blabla)
+      print_tab (n_recur, blabla, saut_av=True)
 
     erreur = 0
     message = ""
@@ -2578,104 +2686,29 @@ Sorties :
 
       self.nom_solide = solide.name()
       if self._verbose_max:
-        print_tab (n_recur, "solide", self.nom_solide)
+        print_tab (n_recur, "solide : ", self.nom_solide)
 
 # 1. Isolement du solide
       solide_aux, recover = self._isole_solide ( solide, n_recur )
 
-# 2. Exportation dans un fichier step pour traitement dans GEOM
-
-      fichier = tempfile.mkstemp(suffix=".stp")[1]
-      if self._verbose_max:
-        print_tab (n_recur, "fichier = ", fichier)
-        print_tab (n_recur, "solide  = ", solide_aux.name())
-        print_tab (n_recur, "de type = ", solide_aux.shapeType())
-      export = model.exportToFile(self.part_doc, fichier, [model.selection(solide_aux.shapeType(), solide_aux.name())])
-      export.execute(True)
-      model.do()
-
-      taille = os.path.getsize(fichier)
-      if ( taille <= 0 ):
-        message = "Export de SHAPER vers GEOM impossible pour le solide '{}' de type '{}'\n".format(solide_aux.name(), solide_aux.shapeType())
-        message += "Le fichier {} est de taille {}".format(fichier,taille)
-        erreur = 2
-        break
-
-# 3. Importation dans GEOM
-      geompy = geomBuilder.New()
-      objet_geom = geompy.ImportSTEP(fichier, False, True)
-      os.remove(fichier)
-
-# 4. Traitement de l'objet correspondant
-      erreur, message = self._traitement_objet ( solide=solide_aux, objet_geom=objet_geom, n_recur=n_recur )
+# 2. Traitement de l'objet correspondant
+      erreur, message = self._traitement_objet ( solide_aux, n_recur=n_recur )
 
       if ( erreur and self._verbose_max ):
         print (blabla, message)
 
-# 5. Mise en forme de l'objet principal récupéré
-      if ( recover is not None ):
-        _ = self._nom_sous_objets (recover, False)
-
-# 6. Neutralisation des erreurs dues à l'épaisseur
+# 3. Neutralisation des erreurs dues à l'épaisseur
       if ( erreur in (-2,-1,2) ):
         erreur = 0
         message = ""
+      if erreur:
+        break
 
-      break
-
-    return erreur, message
-
-#===========================  Fin de la méthode ==================================
-
-#=========================== Début de la méthode =================================
-
-  def surf_objet_geom (self, objet_geom):
-    """Calcule la surface médiane pour un objet GEOM passé en argument
-
-Entrées :
-  :objet_geom: l'objet GEOM à traiter
-
-Sorties :
-  :erreur: code d'erreur
-  :message: message d'erreur
-"""
-
-    nom_fonction = __name__ + "/surf_objet_geom"
-    blabla = "\nDans {} :\n".format(nom_fonction)
-
-    if self._verbose_max:
-      print (blabla)
-
-    erreur, message = self._traitement_objet ( objet_geom=objet_geom )
-
-    if ( erreur and self._verbose_max ):
-      print (blabla, message)
-
-    return erreur, message
-
-#===========================  Fin de la méthode ==================================
-
-#=========================== Début de la méthode =================================
-
-  def lancement (self):
-
-    """Lancement
-
-Sorties :
-  :erreur: code d'erreur
-  :message: message d'erreur
-"""
-
-    nom_fonction = __name__ + "/lancement"
-    blabla = "\nDans {} :\n".format(nom_fonction)
-
-    if self._verbose_max:
-      print (blabla)
-
-    erreur, message = self._traitement_objet ( )
+# 4. Mise en forme de l'objet principal récupéré
+      if ( recover is not None ):
+        _ = self._nom_sous_objets (recover, False)
 
-    if ( erreur and self._verbose_max ):
-      print (blabla, message)
+      break
 
     return erreur, message
 
@@ -2692,13 +2725,13 @@ if __name__ == "__main__" :
   HOME_SH_SM_EXCHANGE = os.environ["HOME_SH_SM_EXCHANGE"]
   L_FIC_CAO = list()
   #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "Solid_7.step"))
-  #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Objet_1.stp"))
+  L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Objet_1.stp"))
   #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval_007.stp"))
   ##L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Naval.stp"))
   #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2.step"))
   #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_22.step"))
   #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Partition_2_1_5.step"))
-  L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Observatoire.stp"))
+  #L_FIC_CAO.append(os.path.join(HOME_SH_SM_EXCHANGE, "SHAPER", "SurfaceMediane", "CAO_STEP", "Observatoire.stp"))
 
   for FIC_CAO in L_FIC_CAO: