]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
macro midsurface
authorGérald NICOLAS <gerald.nicolas@edf.fr>
Mon, 9 Jan 2023 17:08:25 +0000 (18:08 +0100)
committerGérald NICOLAS <gerald.nicolas@edf.fr>
Wed, 25 Jan 2023 10:48:21 +0000 (11:48 +0100)
src/PythonAddons/macros/midSurface/__init__.py [new file with mode: 0755]
src/PythonAddons/macros/midSurface/feature.py [new file with mode: 0755]
src/PythonAddons/macros/midSurface/icons/midSurface.png [new file with mode: 0644]
src/PythonAddons/macros/midSurface/midSurface.stp [new file with mode: 0644]
src/PythonAddons/macros/midSurface/surfaceMediane.py [new file with mode: 0755]
src/PythonAddons/macros/midSurface/widget.xml [new file with mode: 0644]

diff --git a/src/PythonAddons/macros/midSurface/__init__.py b/src/PythonAddons/macros/midSurface/__init__.py
new file mode 100755 (executable)
index 0000000..cb192e2
--- /dev/null
@@ -0,0 +1,19 @@
+# Copyright (C) 2016-2022  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
diff --git a/src/PythonAddons/macros/midSurface/feature.py b/src/PythonAddons/macros/midSurface/feature.py
new file mode 100755 (executable)
index 0000000..44f5bcb
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2016-2022  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+"""Obtention des surfaces médianes à partir d'une CAO contenue dans un fichier
+
+On sait traiter les faces :
+  . planes
+  . cylindriques
+  . sphériques
+  . toriques
+  . coniques
+
+Author: Gérald NICOLAS
+"""
+__revision__ = "V02.04"
+
+import os
+
+from salome.shaper import model
+
+import ModelAPI
+
+from macros.midSurface.surfaceMediane import SurfaceMediane
+
+class midSurface(model.Feature):
+    """Création des fibres neutres"""
+
+# Feature initializations
+
+    def __init__(self):
+        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
+        model.Feature.__init__(self)
+
+    @staticmethod
+    def ID():
+        """Return Id of the Feature."""
+        return "midSurface"
+
+    @staticmethod
+    def FILE_ID():
+        """Returns ID of the CAD file."""
+        return "file_path"
+
+    def getKind(self):
+        """Override Feature.getKind()"""
+        return midSurface.ID()
+
+
+#====================================================================================
+# Initialization of the dialog panel
+
+    def initAttributes(self):
+        """Override Feature.initAttributes()"""
+        # Creating the input argument of the feature
+        self.data().addAttribute(self.FILE_ID(), ModelAPI.ModelAPI_AttributeString_typeId())
+
+#====================================================================================
+# Execution
+
+    def execute(self):
+        """F.execute() -- execute the Feature"""
+        # Retrieving the user input
+        apath    = self.string(self.FILE_ID())
+
+        filepath = apath.value()
+        #print("filepath : '{}'".format(filepath))
+        if filepath != "" :
+            if os.path.isfile(filepath):
+                # Lancement du script de création des fibres neutres
+                l_options = list()
+                #l_options.append("-v")
+                l_options.append("-vmax")
+                #l_options.append("-export_step")
+                print("l_options : '{}'".format(l_options))
+                s_med = SurfaceMediane(l_options)
+                with open("/tmp/grr_1", "w") as fic :
+                      fic.write("{}".format(dir(s_med)))
+                      fic.write("\n{}".format(filepath))
+                erreur, message = s_med.surf_fic_cao (filepath)
+                with open("/tmp/grr_2", "w") as fic :
+                      fic.write("erreur = {}, message = '{}'".format(erreur, message))
+                del s_med
+                if erreur:
+                    self.setError(message)
+            else:
+                self.setError("The file '{}' does not exist".format(filepath))
+
+        return
+
+    def isMacro(self):
+        """Override Feature.initAttributes().
+        F.isMacro() -> True
+
+        midSurface feature is macro: removes itself on the creation transaction
+        finish.
+        """
+        return False
diff --git a/src/PythonAddons/macros/midSurface/icons/midSurface.png b/src/PythonAddons/macros/midSurface/icons/midSurface.png
new file mode 100644 (file)
index 0000000..bb8452e
Binary files /dev/null and b/src/PythonAddons/macros/midSurface/icons/midSurface.png differ
diff --git a/src/PythonAddons/macros/midSurface/midSurface.stp b/src/PythonAddons/macros/midSurface/midSurface.stp
new file mode 100644 (file)
index 0000000..e334717
--- /dev/null
@@ -0,0 +1,1348 @@
+ISO-10303-21;
+HEADER;
+FILE_DESCRIPTION(('Open CASCADE Model'),'2;1');
+FILE_NAME('Open CASCADE Shape Model','2021-06-14T08:47:00',('Author'),(
+    'Open CASCADE'),'Open CASCADE STEP processor 7.5','Open CASCADE 7.5'
+  ,'Unknown');
+FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
+ENDSEC;
+DATA;
+#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
+  'automotive_design',2000,#2);
+#2 = APPLICATION_CONTEXT(
+  'core data for automotive mechanical design processes');
+#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
+#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
+#5 = PRODUCT_DEFINITION('design','',#6,#9);
+#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
+#7 = PRODUCT('Open CASCADE STEP translator 7.5 1',
+  'Open CASCADE STEP translator 7.5 1','',(#8));
+#8 = PRODUCT_CONTEXT('',#2,'mechanical');
+#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
+#10 = SHAPE_REPRESENTATION('',(#11,#15,#19,#23),#27);
+#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
+#12 = CARTESIAN_POINT('',(0.,0.,0.));
+#13 = DIRECTION('',(0.,0.,1.));
+#14 = DIRECTION('',(1.,0.,-0.));
+#15 = AXIS2_PLACEMENT_3D('',#16,#17,#18);
+#16 = CARTESIAN_POINT('',(0.,0.,0.));
+#17 = DIRECTION('',(0.,0.,1.));
+#18 = DIRECTION('',(1.,0.,-0.));
+#19 = AXIS2_PLACEMENT_3D('',#20,#21,#22);
+#20 = CARTESIAN_POINT('',(0.,0.,0.));
+#21 = DIRECTION('',(0.,0.,1.));
+#22 = DIRECTION('',(1.,0.,-0.));
+#23 = AXIS2_PLACEMENT_3D('',#24,#25,#26);
+#24 = CARTESIAN_POINT('',(0.,0.,0.));
+#25 = DIRECTION('',(0.,0.,1.));
+#26 = DIRECTION('',(1.,0.,-0.));
+#27 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#31)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
+(#28,#29,#30)) REPRESENTATION_CONTEXT('Context #1',
+  '3D Context with UNIT and UNCERTAINTY') );
+#28 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT($,.METRE.) );
+#29 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
+#30 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
+#31 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-06),#28,
+  'distance_accuracy_value','confusion accuracy');
+#32 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
+#33 = NON_MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#11,#34,#167,#594),
+  #1139);
+#34 = SHELL_BASED_SURFACE_MODEL('',(#35));
+#35 = CLOSED_SHELL('',(#36,#73,#128,#163));
+#36 = ADVANCED_FACE('',(#37),#50,.F.);
+#37 = FACE_BOUND('',#38,.T.);
+#38 = EDGE_LOOP('',(#39));
+#39 = ORIENTED_EDGE('',*,*,#40,.F.);
+#40 = EDGE_CURVE('',#41,#41,#43,.T.);
+#41 = VERTEX_POINT('',#42);
+#42 = CARTESIAN_POINT('',(51.,0.,0.));
+#43 = SURFACE_CURVE('',#44,(#49,#61),.PCURVE_S1.);
+#44 = CIRCLE('',#45,51.);
+#45 = AXIS2_PLACEMENT_3D('',#46,#47,#48);
+#46 = CARTESIAN_POINT('',(0.,0.,0.));
+#47 = DIRECTION('',(0.,0.,1.));
+#48 = DIRECTION('',(1.,0.,-0.));
+#49 = PCURVE('',#50,#55);
+#50 = PLANE('',#51);
+#51 = AXIS2_PLACEMENT_3D('',#52,#53,#54);
+#52 = CARTESIAN_POINT('',(0.,0.,0.));
+#53 = DIRECTION('',(0.,0.,1.));
+#54 = DIRECTION('',(1.,0.,-0.));
+#55 = DEFINITIONAL_REPRESENTATION('',(#56),#60);
+#56 = CIRCLE('',#57,51.);
+#57 = AXIS2_PLACEMENT_2D('',#58,#59);
+#58 = CARTESIAN_POINT('',(0.,0.));
+#59 = DIRECTION('',(1.,-0.));
+#60 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#61 = PCURVE('',#62,#67);
+#62 = CYLINDRICAL_SURFACE('',#63,51.);
+#63 = AXIS2_PLACEMENT_3D('',#64,#65,#66);
+#64 = CARTESIAN_POINT('',(0.,0.,0.));
+#65 = DIRECTION('',(0.,0.,1.));
+#66 = DIRECTION('',(1.,0.,-0.));
+#67 = DEFINITIONAL_REPRESENTATION('',(#68),#72);
+#68 = LINE('',#69,#70);
+#69 = CARTESIAN_POINT('',(0.,0.));
+#70 = VECTOR('',#71,1.);
+#71 = DIRECTION('',(1.,0.));
+#72 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#73 = ADVANCED_FACE('',(#74),#62,.T.);
+#74 = FACE_BOUND('',#75,.T.);
+#75 = EDGE_LOOP('',(#76,#77,#100,#127));
+#76 = ORIENTED_EDGE('',*,*,#40,.T.);
+#77 = ORIENTED_EDGE('',*,*,#78,.T.);
+#78 = EDGE_CURVE('',#41,#79,#81,.T.);
+#79 = VERTEX_POINT('',#80);
+#80 = CARTESIAN_POINT('',(51.,0.,0.5));
+#81 = SEAM_CURVE('',#82,(#86,#93),.PCURVE_S1.);
+#82 = LINE('',#83,#84);
+#83 = CARTESIAN_POINT('',(51.,0.,0.));
+#84 = VECTOR('',#85,1.);
+#85 = DIRECTION('',(0.,0.,1.));
+#86 = PCURVE('',#62,#87);
+#87 = DEFINITIONAL_REPRESENTATION('',(#88),#92);
+#88 = LINE('',#89,#90);
+#89 = CARTESIAN_POINT('',(0.,0.));
+#90 = VECTOR('',#91,1.);
+#91 = DIRECTION('',(0.,1.));
+#92 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#93 = PCURVE('',#62,#94);
+#94 = DEFINITIONAL_REPRESENTATION('',(#95),#99);
+#95 = LINE('',#96,#97);
+#96 = CARTESIAN_POINT('',(6.28318530718,0.));
+#97 = VECTOR('',#98,1.);
+#98 = DIRECTION('',(0.,1.));
+#99 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#100 = ORIENTED_EDGE('',*,*,#101,.F.);
+#101 = EDGE_CURVE('',#79,#79,#102,.T.);
+#102 = SURFACE_CURVE('',#103,(#108,#115),.PCURVE_S1.);
+#103 = CIRCLE('',#104,51.);
+#104 = AXIS2_PLACEMENT_3D('',#105,#106,#107);
+#105 = CARTESIAN_POINT('',(0.,0.,0.5));
+#106 = DIRECTION('',(0.,0.,1.));
+#107 = DIRECTION('',(1.,0.,-0.));
+#108 = PCURVE('',#62,#109);
+#109 = DEFINITIONAL_REPRESENTATION('',(#110),#114);
+#110 = LINE('',#111,#112);
+#111 = CARTESIAN_POINT('',(0.,0.5));
+#112 = VECTOR('',#113,1.);
+#113 = DIRECTION('',(1.,0.));
+#114 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#115 = PCURVE('',#116,#121);
+#116 = PLANE('',#117);
+#117 = AXIS2_PLACEMENT_3D('',#118,#119,#120);
+#118 = CARTESIAN_POINT('',(0.,0.,0.5));
+#119 = DIRECTION('',(0.,0.,1.));
+#120 = DIRECTION('',(1.,0.,-0.));
+#121 = DEFINITIONAL_REPRESENTATION('',(#122),#126);
+#122 = CIRCLE('',#123,51.);
+#123 = AXIS2_PLACEMENT_2D('',#124,#125);
+#124 = CARTESIAN_POINT('',(0.,0.));
+#125 = DIRECTION('',(1.,-0.));
+#126 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#127 = ORIENTED_EDGE('',*,*,#78,.F.);
+#128 = ADVANCED_FACE('',(#129,#160),#116,.T.);
+#129 = FACE_BOUND('',#130,.F.);
+#130 = EDGE_LOOP('',(#131));
+#131 = ORIENTED_EDGE('',*,*,#132,.T.);
+#132 = EDGE_CURVE('',#133,#133,#135,.T.);
+#133 = VERTEX_POINT('',#134);
+#134 = CARTESIAN_POINT('',(50.5,0.,0.5));
+#135 = SURFACE_CURVE('',#136,(#141,#148),.PCURVE_S1.);
+#136 = CIRCLE('',#137,50.5);
+#137 = AXIS2_PLACEMENT_3D('',#138,#139,#140);
+#138 = CARTESIAN_POINT('',(0.,0.,0.5));
+#139 = DIRECTION('',(0.,0.,1.));
+#140 = DIRECTION('',(1.,0.,-0.));
+#141 = PCURVE('',#116,#142);
+#142 = DEFINITIONAL_REPRESENTATION('',(#143),#147);
+#143 = CIRCLE('',#144,50.5);
+#144 = AXIS2_PLACEMENT_2D('',#145,#146);
+#145 = CARTESIAN_POINT('',(0.,0.));
+#146 = DIRECTION('',(1.,-0.));
+#147 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#148 = PCURVE('',#149,#154);
+#149 = PLANE('',#150);
+#150 = AXIS2_PLACEMENT_3D('',#151,#152,#153);
+#151 = CARTESIAN_POINT('',(0.,0.,0.5));
+#152 = DIRECTION('',(0.,0.,1.));
+#153 = DIRECTION('',(1.,0.,-0.));
+#154 = DEFINITIONAL_REPRESENTATION('',(#155),#159);
+#155 = CIRCLE('',#156,50.5);
+#156 = AXIS2_PLACEMENT_2D('',#157,#158);
+#157 = CARTESIAN_POINT('',(0.,0.));
+#158 = DIRECTION('',(1.,-0.));
+#159 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#160 = FACE_BOUND('',#161,.F.);
+#161 = EDGE_LOOP('',(#162));
+#162 = ORIENTED_EDGE('',*,*,#101,.F.);
+#163 = ADVANCED_FACE('',(#164),#149,.T.);
+#164 = FACE_BOUND('',#165,.F.);
+#165 = EDGE_LOOP('',(#166));
+#166 = ORIENTED_EDGE('',*,*,#132,.F.);
+#167 = SHELL_BASED_SURFACE_MODEL('',(#168));
+#168 = CLOSED_SHELL('',(#169,#336,#438,#486,#536,#562,#563));
+#169 = ADVANCED_FACE('',(#170),#182,.T.);
+#170 = FACE_BOUND('',#171,.T.);
+#171 = EDGE_LOOP('',(#172,#200,#201,#202,#231,#258,#287,#314));
+#172 = ORIENTED_EDGE('',*,*,#173,.F.);
+#173 = EDGE_CURVE('',#79,#174,#176,.T.);
+#174 = VERTEX_POINT('',#175);
+#175 = CARTESIAN_POINT('',(51.,0.,135.));
+#176 = SEAM_CURVE('',#177,(#181,#193),.PCURVE_S1.);
+#177 = LINE('',#178,#179);
+#178 = CARTESIAN_POINT('',(51.,0.,0.));
+#179 = VECTOR('',#180,1.);
+#180 = DIRECTION('',(0.,0.,1.));
+#181 = PCURVE('',#182,#187);
+#182 = CYLINDRICAL_SURFACE('',#183,51.);
+#183 = AXIS2_PLACEMENT_3D('',#184,#185,#186);
+#184 = CARTESIAN_POINT('',(0.,0.,0.));
+#185 = DIRECTION('',(0.,0.,1.));
+#186 = DIRECTION('',(1.,0.,-0.));
+#187 = DEFINITIONAL_REPRESENTATION('',(#188),#192);
+#188 = LINE('',#189,#190);
+#189 = CARTESIAN_POINT('',(0.,0.));
+#190 = VECTOR('',#191,1.);
+#191 = DIRECTION('',(0.,1.));
+#192 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#193 = PCURVE('',#182,#194);
+#194 = DEFINITIONAL_REPRESENTATION('',(#195),#199);
+#195 = LINE('',#196,#197);
+#196 = CARTESIAN_POINT('',(6.28318530718,0.));
+#197 = VECTOR('',#198,1.);
+#198 = DIRECTION('',(0.,1.));
+#199 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#200 = ORIENTED_EDGE('',*,*,#101,.T.);
+#201 = ORIENTED_EDGE('',*,*,#173,.T.);
+#202 = ORIENTED_EDGE('',*,*,#203,.F.);
+#203 = EDGE_CURVE('',#204,#174,#206,.T.);
+#204 = VERTEX_POINT('',#205);
+#205 = CARTESIAN_POINT('',(50.744359292438,-5.1,135.));
+#206 = SURFACE_CURVE('',#207,(#212,#219),.PCURVE_S1.);
+#207 = CIRCLE('',#208,51.);
+#208 = AXIS2_PLACEMENT_3D('',#209,#210,#211);
+#209 = CARTESIAN_POINT('',(0.,0.,135.));
+#210 = DIRECTION('',(0.,0.,1.));
+#211 = DIRECTION('',(1.,0.,-0.));
+#212 = PCURVE('',#182,#213);
+#213 = DEFINITIONAL_REPRESENTATION('',(#214),#218);
+#214 = LINE('',#215,#216);
+#215 = CARTESIAN_POINT('',(0.,135.));
+#216 = VECTOR('',#217,1.);
+#217 = DIRECTION('',(1.,0.));
+#218 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#219 = PCURVE('',#220,#225);
+#220 = PLANE('',#221);
+#221 = AXIS2_PLACEMENT_3D('',#222,#223,#224);
+#222 = CARTESIAN_POINT('',(7.65,-5.1,135.));
+#223 = DIRECTION('',(0.,0.,1.));
+#224 = DIRECTION('',(1.,0.,-0.));
+#225 = DEFINITIONAL_REPRESENTATION('',(#226),#230);
+#226 = CIRCLE('',#227,51.);
+#227 = AXIS2_PLACEMENT_2D('',#228,#229);
+#228 = CARTESIAN_POINT('',(-7.65,5.1));
+#229 = DIRECTION('',(1.,0.));
+#230 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#231 = ORIENTED_EDGE('',*,*,#232,.T.);
+#232 = EDGE_CURVE('',#204,#233,#235,.T.);
+#233 = VERTEX_POINT('',#234);
+#234 = CARTESIAN_POINT('',(50.744359292438,-5.1,150.));
+#235 = SURFACE_CURVE('',#236,(#240,#246),.PCURVE_S1.);
+#236 = LINE('',#237,#238);
+#237 = CARTESIAN_POINT('',(50.744359292438,-5.1,0.));
+#238 = VECTOR('',#239,1.);
+#239 = DIRECTION('',(0.,0.,1.));
+#240 = PCURVE('',#182,#241);
+#241 = DEFINITIONAL_REPRESENTATION('',(#242),#245);
+#242 = B_SPLINE_CURVE_WITH_KNOTS('',1,(#243,#244),.UNSPECIFIED.,.F.,.F.,
+  (2,2),(127.5,150.0000204),.PIECEWISE_BEZIER_KNOTS.);
+#243 = CARTESIAN_POINT('',(6.183017886018,127.5));
+#244 = CARTESIAN_POINT('',(6.183017886018,150.0000204));
+#245 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#246 = PCURVE('',#247,#252);
+#247 = PLANE('',#248);
+#248 = AXIS2_PLACEMENT_3D('',#249,#250,#251);
+#249 = CARTESIAN_POINT('',(7.65,-5.1,135.));
+#250 = DIRECTION('',(-0.,1.,0.));
+#251 = DIRECTION('',(0.,0.,1.));
+#252 = DEFINITIONAL_REPRESENTATION('',(#253),#257);
+#253 = LINE('',#254,#255);
+#254 = CARTESIAN_POINT('',(-135.,43.094359292438));
+#255 = VECTOR('',#256,1.);
+#256 = DIRECTION('',(1.,0.));
+#257 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#258 = ORIENTED_EDGE('',*,*,#259,.F.);
+#259 = EDGE_CURVE('',#260,#233,#262,.T.);
+#260 = VERTEX_POINT('',#261);
+#261 = CARTESIAN_POINT('',(50.744359292438,5.1,150.));
+#262 = SURFACE_CURVE('',#263,(#268,#275),.PCURVE_S1.);
+#263 = CIRCLE('',#264,51.);
+#264 = AXIS2_PLACEMENT_3D('',#265,#266,#267);
+#265 = CARTESIAN_POINT('',(0.,0.,150.));
+#266 = DIRECTION('',(0.,0.,1.));
+#267 = DIRECTION('',(1.,0.,-0.));
+#268 = PCURVE('',#182,#269);
+#269 = DEFINITIONAL_REPRESENTATION('',(#270),#274);
+#270 = LINE('',#271,#272);
+#271 = CARTESIAN_POINT('',(0.,150.));
+#272 = VECTOR('',#273,1.);
+#273 = DIRECTION('',(1.,0.));
+#274 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#275 = PCURVE('',#276,#281);
+#276 = PLANE('',#277);
+#277 = AXIS2_PLACEMENT_3D('',#278,#279,#280);
+#278 = CARTESIAN_POINT('',(0.,0.,150.));
+#279 = DIRECTION('',(0.,0.,1.));
+#280 = DIRECTION('',(1.,0.,-0.));
+#281 = DEFINITIONAL_REPRESENTATION('',(#282),#286);
+#282 = CIRCLE('',#283,51.);
+#283 = AXIS2_PLACEMENT_2D('',#284,#285);
+#284 = CARTESIAN_POINT('',(0.,0.));
+#285 = DIRECTION('',(1.,-0.));
+#286 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#287 = ORIENTED_EDGE('',*,*,#288,.F.);
+#288 = EDGE_CURVE('',#289,#260,#291,.T.);
+#289 = VERTEX_POINT('',#290);
+#290 = CARTESIAN_POINT('',(50.744359292438,5.1,135.));
+#291 = SURFACE_CURVE('',#292,(#296,#302),.PCURVE_S1.);
+#292 = LINE('',#293,#294);
+#293 = CARTESIAN_POINT('',(50.744359292438,5.1,0.));
+#294 = VECTOR('',#295,1.);
+#295 = DIRECTION('',(0.,0.,1.));
+#296 = PCURVE('',#182,#297);
+#297 = DEFINITIONAL_REPRESENTATION('',(#298),#301);
+#298 = B_SPLINE_CURVE_WITH_KNOTS('',1,(#299,#300),.UNSPECIFIED.,.F.,.F.,
+  (2,2),(127.5,150.0000204),.PIECEWISE_BEZIER_KNOTS.);
+#299 = CARTESIAN_POINT('',(0.100167421162,127.5));
+#300 = CARTESIAN_POINT('',(0.100167421162,150.0000204));
+#301 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#302 = PCURVE('',#303,#308);
+#303 = PLANE('',#304);
+#304 = AXIS2_PLACEMENT_3D('',#305,#306,#307);
+#305 = CARTESIAN_POINT('',(7.65,5.1,135.));
+#306 = DIRECTION('',(-0.,1.,0.));
+#307 = DIRECTION('',(0.,0.,1.));
+#308 = DEFINITIONAL_REPRESENTATION('',(#309),#313);
+#309 = LINE('',#310,#311);
+#310 = CARTESIAN_POINT('',(-135.,43.094359292438));
+#311 = VECTOR('',#312,1.);
+#312 = DIRECTION('',(1.,0.));
+#313 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#314 = ORIENTED_EDGE('',*,*,#315,.F.);
+#315 = EDGE_CURVE('',#174,#289,#316,.T.);
+#316 = SURFACE_CURVE('',#317,(#322,#329),.PCURVE_S1.);
+#317 = CIRCLE('',#318,51.);
+#318 = AXIS2_PLACEMENT_3D('',#319,#320,#321);
+#319 = CARTESIAN_POINT('',(0.,0.,135.));
+#320 = DIRECTION('',(0.,0.,1.));
+#321 = DIRECTION('',(1.,0.,-0.));
+#322 = PCURVE('',#182,#323);
+#323 = DEFINITIONAL_REPRESENTATION('',(#324),#328);
+#324 = LINE('',#325,#326);
+#325 = CARTESIAN_POINT('',(0.,135.));
+#326 = VECTOR('',#327,1.);
+#327 = DIRECTION('',(1.,0.));
+#328 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#329 = PCURVE('',#220,#330);
+#330 = DEFINITIONAL_REPRESENTATION('',(#331),#335);
+#331 = CIRCLE('',#332,51.);
+#332 = AXIS2_PLACEMENT_2D('',#333,#334);
+#333 = CARTESIAN_POINT('',(-7.65,5.1));
+#334 = DIRECTION('',(1.,0.));
+#335 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#336 = ADVANCED_FACE('',(#337),#220,.T.);
+#337 = FACE_BOUND('',#338,.T.);
+#338 = EDGE_LOOP('',(#339,#362,#391,#415,#436,#437));
+#339 = ORIENTED_EDGE('',*,*,#340,.F.);
+#340 = EDGE_CURVE('',#341,#289,#343,.T.);
+#341 = VERTEX_POINT('',#342);
+#342 = CARTESIAN_POINT('',(50.24181525383,5.1,135.));
+#343 = SURFACE_CURVE('',#344,(#348,#355),.PCURVE_S1.);
+#344 = LINE('',#345,#346);
+#345 = CARTESIAN_POINT('',(7.65,5.1,135.));
+#346 = VECTOR('',#347,1.);
+#347 = DIRECTION('',(1.,0.,-0.));
+#348 = PCURVE('',#220,#349);
+#349 = DEFINITIONAL_REPRESENTATION('',(#350),#354);
+#350 = LINE('',#351,#352);
+#351 = CARTESIAN_POINT('',(0.,10.2));
+#352 = VECTOR('',#353,1.);
+#353 = DIRECTION('',(1.,0.));
+#354 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#355 = PCURVE('',#303,#356);
+#356 = DEFINITIONAL_REPRESENTATION('',(#357),#361);
+#357 = LINE('',#358,#359);
+#358 = CARTESIAN_POINT('',(0.,0.));
+#359 = VECTOR('',#360,1.);
+#360 = DIRECTION('',(0.,1.));
+#361 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#362 = ORIENTED_EDGE('',*,*,#363,.F.);
+#363 = EDGE_CURVE('',#364,#341,#366,.T.);
+#364 = VERTEX_POINT('',#365);
+#365 = CARTESIAN_POINT('',(50.5,0.,135.));
+#366 = SURFACE_CURVE('',#367,(#372,#379),.PCURVE_S1.);
+#367 = CIRCLE('',#368,50.5);
+#368 = AXIS2_PLACEMENT_3D('',#369,#370,#371);
+#369 = CARTESIAN_POINT('',(0.,0.,135.));
+#370 = DIRECTION('',(0.,0.,1.));
+#371 = DIRECTION('',(1.,0.,-0.));
+#372 = PCURVE('',#220,#373);
+#373 = DEFINITIONAL_REPRESENTATION('',(#374),#378);
+#374 = CIRCLE('',#375,50.5);
+#375 = AXIS2_PLACEMENT_2D('',#376,#377);
+#376 = CARTESIAN_POINT('',(-7.65,5.1));
+#377 = DIRECTION('',(1.,0.));
+#378 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#379 = PCURVE('',#380,#385);
+#380 = CYLINDRICAL_SURFACE('',#381,50.5);
+#381 = AXIS2_PLACEMENT_3D('',#382,#383,#384);
+#382 = CARTESIAN_POINT('',(0.,0.,0.5));
+#383 = DIRECTION('',(0.,0.,1.));
+#384 = DIRECTION('',(1.,0.,-0.));
+#385 = DEFINITIONAL_REPRESENTATION('',(#386),#390);
+#386 = LINE('',#387,#388);
+#387 = CARTESIAN_POINT('',(0.,134.5));
+#388 = VECTOR('',#389,1.);
+#389 = DIRECTION('',(1.,0.));
+#390 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#391 = ORIENTED_EDGE('',*,*,#392,.F.);
+#392 = EDGE_CURVE('',#393,#364,#395,.T.);
+#393 = VERTEX_POINT('',#394);
+#394 = CARTESIAN_POINT('',(50.24181525383,-5.1,135.));
+#395 = SURFACE_CURVE('',#396,(#401,#408),.PCURVE_S1.);
+#396 = CIRCLE('',#397,50.5);
+#397 = AXIS2_PLACEMENT_3D('',#398,#399,#400);
+#398 = CARTESIAN_POINT('',(0.,0.,135.));
+#399 = DIRECTION('',(0.,0.,1.));
+#400 = DIRECTION('',(1.,0.,-0.));
+#401 = PCURVE('',#220,#402);
+#402 = DEFINITIONAL_REPRESENTATION('',(#403),#407);
+#403 = CIRCLE('',#404,50.5);
+#404 = AXIS2_PLACEMENT_2D('',#405,#406);
+#405 = CARTESIAN_POINT('',(-7.65,5.1));
+#406 = DIRECTION('',(1.,0.));
+#407 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#408 = PCURVE('',#380,#409);
+#409 = DEFINITIONAL_REPRESENTATION('',(#410),#414);
+#410 = LINE('',#411,#412);
+#411 = CARTESIAN_POINT('',(0.,134.5));
+#412 = VECTOR('',#413,1.);
+#413 = DIRECTION('',(1.,0.));
+#414 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#415 = ORIENTED_EDGE('',*,*,#416,.T.);
+#416 = EDGE_CURVE('',#393,#204,#417,.T.);
+#417 = SURFACE_CURVE('',#418,(#422,#429),.PCURVE_S1.);
+#418 = LINE('',#419,#420);
+#419 = CARTESIAN_POINT('',(7.65,-5.1,135.));
+#420 = VECTOR('',#421,1.);
+#421 = DIRECTION('',(1.,0.,-0.));
+#422 = PCURVE('',#220,#423);
+#423 = DEFINITIONAL_REPRESENTATION('',(#424),#428);
+#424 = LINE('',#425,#426);
+#425 = CARTESIAN_POINT('',(0.,0.));
+#426 = VECTOR('',#427,1.);
+#427 = DIRECTION('',(1.,0.));
+#428 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#429 = PCURVE('',#247,#430);
+#430 = DEFINITIONAL_REPRESENTATION('',(#431),#435);
+#431 = LINE('',#432,#433);
+#432 = CARTESIAN_POINT('',(0.,0.));
+#433 = VECTOR('',#434,1.);
+#434 = DIRECTION('',(0.,1.));
+#435 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#436 = ORIENTED_EDGE('',*,*,#203,.T.);
+#437 = ORIENTED_EDGE('',*,*,#315,.T.);
+#438 = ADVANCED_FACE('',(#439),#303,.F.);
+#439 = FACE_BOUND('',#440,.F.);
+#440 = EDGE_LOOP('',(#441,#442,#464,#485));
+#441 = ORIENTED_EDGE('',*,*,#340,.F.);
+#442 = ORIENTED_EDGE('',*,*,#443,.T.);
+#443 = EDGE_CURVE('',#341,#444,#446,.T.);
+#444 = VERTEX_POINT('',#445);
+#445 = CARTESIAN_POINT('',(50.24181525383,5.1,150.));
+#446 = SURFACE_CURVE('',#447,(#451,#458),.PCURVE_S1.);
+#447 = LINE('',#448,#449);
+#448 = CARTESIAN_POINT('',(50.24181525383,5.1,0.5));
+#449 = VECTOR('',#450,1.);
+#450 = DIRECTION('',(0.,0.,1.));
+#451 = PCURVE('',#303,#452);
+#452 = DEFINITIONAL_REPRESENTATION('',(#453),#457);
+#453 = LINE('',#454,#455);
+#454 = CARTESIAN_POINT('',(-134.5,42.59181525383));
+#455 = VECTOR('',#456,1.);
+#456 = DIRECTION('',(1.,0.));
+#457 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#458 = PCURVE('',#380,#459);
+#459 = DEFINITIONAL_REPRESENTATION('',(#460),#463);
+#460 = B_SPLINE_CURVE_WITH_KNOTS('',1,(#461,#462),.UNSPECIFIED.,.F.,.F.,
+  (2,2),(127.,149.5000204),.PIECEWISE_BEZIER_KNOTS.);
+#461 = CARTESIAN_POINT('',(0.101162558036,127.));
+#462 = CARTESIAN_POINT('',(0.101162558036,149.5000204));
+#463 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#464 = ORIENTED_EDGE('',*,*,#465,.T.);
+#465 = EDGE_CURVE('',#444,#260,#466,.T.);
+#466 = SURFACE_CURVE('',#467,(#471,#478),.PCURVE_S1.);
+#467 = LINE('',#468,#469);
+#468 = CARTESIAN_POINT('',(3.825,5.1,150.));
+#469 = VECTOR('',#470,1.);
+#470 = DIRECTION('',(1.,0.,-0.));
+#471 = PCURVE('',#303,#472);
+#472 = DEFINITIONAL_REPRESENTATION('',(#473),#477);
+#473 = LINE('',#474,#475);
+#474 = CARTESIAN_POINT('',(15.,-3.825));
+#475 = VECTOR('',#476,1.);
+#476 = DIRECTION('',(0.,1.));
+#477 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#478 = PCURVE('',#276,#479);
+#479 = DEFINITIONAL_REPRESENTATION('',(#480),#484);
+#480 = LINE('',#481,#482);
+#481 = CARTESIAN_POINT('',(3.825,5.1));
+#482 = VECTOR('',#483,1.);
+#483 = DIRECTION('',(1.,-0.));
+#484 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#485 = ORIENTED_EDGE('',*,*,#288,.F.);
+#486 = ADVANCED_FACE('',(#487),#276,.T.);
+#487 = FACE_BOUND('',#488,.F.);
+#488 = EDGE_LOOP('',(#489,#490,#514,#535));
+#489 = ORIENTED_EDGE('',*,*,#465,.F.);
+#490 = ORIENTED_EDGE('',*,*,#491,.T.);
+#491 = EDGE_CURVE('',#444,#492,#494,.T.);
+#492 = VERTEX_POINT('',#493);
+#493 = CARTESIAN_POINT('',(50.24181525383,-5.1,150.));
+#494 = SURFACE_CURVE('',#495,(#500,#507),.PCURVE_S1.);
+#495 = CIRCLE('',#496,50.5);
+#496 = AXIS2_PLACEMENT_3D('',#497,#498,#499);
+#497 = CARTESIAN_POINT('',(0.,0.,150.));
+#498 = DIRECTION('',(0.,0.,1.));
+#499 = DIRECTION('',(1.,0.,-0.));
+#500 = PCURVE('',#276,#501);
+#501 = DEFINITIONAL_REPRESENTATION('',(#502),#506);
+#502 = CIRCLE('',#503,50.5);
+#503 = AXIS2_PLACEMENT_2D('',#504,#505);
+#504 = CARTESIAN_POINT('',(0.,0.));
+#505 = DIRECTION('',(1.,-0.));
+#506 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#507 = PCURVE('',#380,#508);
+#508 = DEFINITIONAL_REPRESENTATION('',(#509),#513);
+#509 = LINE('',#510,#511);
+#510 = CARTESIAN_POINT('',(0.,149.5));
+#511 = VECTOR('',#512,1.);
+#512 = DIRECTION('',(1.,0.));
+#513 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#514 = ORIENTED_EDGE('',*,*,#515,.T.);
+#515 = EDGE_CURVE('',#492,#233,#516,.T.);
+#516 = SURFACE_CURVE('',#517,(#521,#528),.PCURVE_S1.);
+#517 = LINE('',#518,#519);
+#518 = CARTESIAN_POINT('',(3.825,-5.1,150.));
+#519 = VECTOR('',#520,1.);
+#520 = DIRECTION('',(1.,0.,-0.));
+#521 = PCURVE('',#276,#522);
+#522 = DEFINITIONAL_REPRESENTATION('',(#523),#527);
+#523 = LINE('',#524,#525);
+#524 = CARTESIAN_POINT('',(3.825,-5.1));
+#525 = VECTOR('',#526,1.);
+#526 = DIRECTION('',(1.,-0.));
+#527 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#528 = PCURVE('',#247,#529);
+#529 = DEFINITIONAL_REPRESENTATION('',(#530),#534);
+#530 = LINE('',#531,#532);
+#531 = CARTESIAN_POINT('',(15.,-3.825));
+#532 = VECTOR('',#533,1.);
+#533 = DIRECTION('',(0.,1.));
+#534 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#535 = ORIENTED_EDGE('',*,*,#259,.F.);
+#536 = ADVANCED_FACE('',(#537),#247,.T.);
+#537 = FACE_BOUND('',#538,.T.);
+#538 = EDGE_LOOP('',(#539,#540,#560,#561));
+#539 = ORIENTED_EDGE('',*,*,#416,.F.);
+#540 = ORIENTED_EDGE('',*,*,#541,.T.);
+#541 = EDGE_CURVE('',#393,#492,#542,.T.);
+#542 = SURFACE_CURVE('',#543,(#547,#554),.PCURVE_S1.);
+#543 = LINE('',#544,#545);
+#544 = CARTESIAN_POINT('',(50.24181525383,-5.1,0.5));
+#545 = VECTOR('',#546,1.);
+#546 = DIRECTION('',(0.,0.,1.));
+#547 = PCURVE('',#247,#548);
+#548 = DEFINITIONAL_REPRESENTATION('',(#549),#553);
+#549 = LINE('',#550,#551);
+#550 = CARTESIAN_POINT('',(-134.5,42.59181525383));
+#551 = VECTOR('',#552,1.);
+#552 = DIRECTION('',(1.,0.));
+#553 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#554 = PCURVE('',#380,#555);
+#555 = DEFINITIONAL_REPRESENTATION('',(#556),#559);
+#556 = B_SPLINE_CURVE_WITH_KNOTS('',1,(#557,#558),.UNSPECIFIED.,.F.,.F.,
+  (2,2),(127.,149.5000204),.PIECEWISE_BEZIER_KNOTS.);
+#557 = CARTESIAN_POINT('',(6.182022749144,127.));
+#558 = CARTESIAN_POINT('',(6.182022749144,149.5000204));
+#559 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#560 = ORIENTED_EDGE('',*,*,#515,.T.);
+#561 = ORIENTED_EDGE('',*,*,#232,.F.);
+#562 = ADVANCED_FACE('',(#129,#160),#116,.F.);
+#563 = ADVANCED_FACE('',(#564),#380,.F.);
+#564 = FACE_BOUND('',#565,.F.);
+#565 = EDGE_LOOP('',(#566,#587,#588,#589,#590,#591,#592,#593));
+#566 = ORIENTED_EDGE('',*,*,#567,.F.);
+#567 = EDGE_CURVE('',#133,#364,#568,.T.);
+#568 = SEAM_CURVE('',#569,(#573,#580),.PCURVE_S1.);
+#569 = LINE('',#570,#571);
+#570 = CARTESIAN_POINT('',(50.5,0.,0.5));
+#571 = VECTOR('',#572,1.);
+#572 = DIRECTION('',(0.,0.,1.));
+#573 = PCURVE('',#380,#574);
+#574 = DEFINITIONAL_REPRESENTATION('',(#575),#579);
+#575 = LINE('',#576,#577);
+#576 = CARTESIAN_POINT('',(0.,0.));
+#577 = VECTOR('',#578,1.);
+#578 = DIRECTION('',(0.,1.));
+#579 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#580 = PCURVE('',#380,#581);
+#581 = DEFINITIONAL_REPRESENTATION('',(#582),#586);
+#582 = LINE('',#583,#584);
+#583 = CARTESIAN_POINT('',(6.28318530718,0.));
+#584 = VECTOR('',#585,1.);
+#585 = DIRECTION('',(0.,1.));
+#586 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#587 = ORIENTED_EDGE('',*,*,#132,.T.);
+#588 = ORIENTED_EDGE('',*,*,#567,.T.);
+#589 = ORIENTED_EDGE('',*,*,#392,.F.);
+#590 = ORIENTED_EDGE('',*,*,#541,.T.);
+#591 = ORIENTED_EDGE('',*,*,#491,.F.);
+#592 = ORIENTED_EDGE('',*,*,#443,.F.);
+#593 = ORIENTED_EDGE('',*,*,#363,.F.);
+#594 = SHELL_BASED_SURFACE_MODEL('',(#595));
+#595 = CLOSED_SHELL('',(#596,#843,#939,#1036,#1105,#1106));
+#596 = ADVANCED_FACE('',(#597),#610,.T.);
+#597 = FACE_BOUND('',#598,.T.);
+#598 = EDGE_LOOP('',(#599,#674,#675,#745,#785,#809,#810));
+#599 = ORIENTED_EDGE('',*,*,#600,.T.);
+#600 = EDGE_CURVE('',#601,#260,#603,.T.);
+#601 = VERTEX_POINT('',#602);
+#602 = CARTESIAN_POINT('',(7.65,5.1,200.16440471091));
+#603 = SURFACE_CURVE('',#604,(#609,#662),.PCURVE_S1.);
+#604 = CIRCLE('',#605,50.744359292438);
+#605 = AXIS2_PLACEMENT_3D('',#606,#607,#608);
+#606 = CARTESIAN_POINT('',(0.,5.1,150.));
+#607 = DIRECTION('',(-0.,1.,0.));
+#608 = DIRECTION('',(0.,0.,1.));
+#609 = PCURVE('',#610,#615);
+#610 = SPHERICAL_SURFACE('',#611,51.);
+#611 = AXIS2_PLACEMENT_3D('',#612,#613,#614);
+#612 = CARTESIAN_POINT('',(0.,0.,150.));
+#613 = DIRECTION('',(0.,0.,1.));
+#614 = DIRECTION('',(1.,0.,-0.));
+#615 = DEFINITIONAL_REPRESENTATION('',(#616),#661);
+#616 = B_SPLINE_CURVE_WITH_KNOTS('',8,(#617,#618,#619,#620,#621,#622,
+    #623,#624,#625,#626,#627,#628,#629,#630,#631,#632,#633,#634,#635,
+    #636,#637,#638,#639,#640,#641,#642,#643,#644,#645,#646,#647,#648,
+    #649,#650,#651,#652,#653,#654,#655,#656,#657,#658,#659,#660),
+  .UNSPECIFIED.,.F.,.F.,(9,7,7,7,7,7,9),(0.151332636977,0.240049117591,
+    0.406392518741,0.551942994748,0.80665632776,1.188726327277,
+    1.570796326795),.UNSPECIFIED.);
+#617 = CARTESIAN_POINT('',(0.588002603548,1.389527695651));
+#618 = CARTESIAN_POINT('',(0.554439938102,1.380300623925));
+#619 = CARTESIAN_POINT('',(0.524804277488,1.370837601429));
+#620 = CARTESIAN_POINT('',(0.498413133057,1.361186676967));
+#621 = CARTESIAN_POINT('',(0.474730741157,1.351381955417));
+#622 = CARTESIAN_POINT('',(0.453343573848,1.341448995293));
+#623 = CARTESIAN_POINT('',(0.43392007826,1.331407581206));
+#624 = CARTESIAN_POINT('',(0.416193500334,1.321273364895));
+#625 = CARTESIAN_POINT('',(0.369478703749,1.291906967005));
+#626 = CARTESIAN_POINT('',(0.344208471707,1.272473079502));
+#627 = CARTESIAN_POINT('',(0.322691694553,1.252840436459));
+#628 = CARTESIAN_POINT('',(0.304081327549,1.233054883899));
+#629 = CARTESIAN_POINT('',(0.28778060328,1.213149039849));
+#630 = CARTESIAN_POINT('',(0.273364656314,1.193145415053));
+#631 = CARTESIAN_POINT('',(0.260511235187,1.173061185037));
+#632 = CARTESIAN_POINT('',(0.238876577886,1.135276565191));
+#633 = CARTESIAN_POINT('',(0.229787122325,1.117592014924));
+#634 = CARTESIAN_POINT('',(0.221538425219,1.099864489187));
+#635 = CARTESIAN_POINT('',(0.21400725191,1.082100431401));
+#636 = CARTESIAN_POINT('',(0.207097029403,1.064304870251));
+#637 = CARTESIAN_POINT('',(0.200729652719,1.046481863854));
+#638 = CARTESIAN_POINT('',(0.194841352608,1.028634716083));
+#639 = CARTESIAN_POINT('',(0.179819378509,0.979496261441));
+#640 = CARTESIAN_POINT('',(0.171563861561,0.9481608547));
+#641 = CARTESIAN_POINT('',(0.164326907751,0.916774737928));
+#642 = CARTESIAN_POINT('',(0.157922834037,0.885347484224));
+#643 = CARTESIAN_POINT('',(0.152213340543,0.853886242422));
+#644 = CARTESIAN_POINT('',(0.14709448037,0.822396396839));
+#645 = CARTESIAN_POINT('',(0.142484250011,0.790882219155));
+#646 = CARTESIAN_POINT('',(0.132066960145,0.712044510553));
+#647 = CARTESIAN_POINT('',(0.126814023495,0.664694848546));
+#648 = CARTESIAN_POINT('',(0.122337988005,0.617309719261));
+#649 = CARTESIAN_POINT('',(0.118501123849,0.569896505503));
+#650 = CARTESIAN_POINT('',(0.115202848793,0.522460760406));
+#651 = CARTESIAN_POINT('',(0.112370208776,0.475006697084));
+#652 = CARTESIAN_POINT('',(0.109947602902,0.427537731213));
+#653 = CARTESIAN_POINT('',(0.105838687151,0.332575648522));
+#654 = CARTESIAN_POINT('',(0.104152368025,0.285082532156));
+#655 = CARTESIAN_POINT('',(0.102792273891,0.237580169534));
+#656 = CARTESIAN_POINT('',(0.101729846306,0.19007081886));
+#657 = CARTESIAN_POINT('',(0.100945534056,0.142556416594));
+#658 = CARTESIAN_POINT('',(0.100426785688,9.503871251789E-02));
+#659 = CARTESIAN_POINT('',(0.100167421162,4.751935620192E-02));
+#660 = CARTESIAN_POINT('',(0.100167421162,0.));
+#661 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#662 = PCURVE('',#663,#668);
+#663 = PLANE('',#664);
+#664 = AXIS2_PLACEMENT_3D('',#665,#666,#667);
+#665 = CARTESIAN_POINT('',(7.65,5.1,135.));
+#666 = DIRECTION('',(-0.,1.,0.));
+#667 = DIRECTION('',(0.,0.,1.));
+#668 = DEFINITIONAL_REPRESENTATION('',(#669),#673);
+#669 = CIRCLE('',#670,50.744359292438);
+#670 = AXIS2_PLACEMENT_2D('',#671,#672);
+#671 = CARTESIAN_POINT('',(15.,-7.65));
+#672 = DIRECTION('',(1.,0.));
+#673 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#674 = ORIENTED_EDGE('',*,*,#259,.T.);
+#675 = ORIENTED_EDGE('',*,*,#676,.F.);
+#676 = EDGE_CURVE('',#677,#233,#679,.T.);
+#677 = VERTEX_POINT('',#678);
+#678 = CARTESIAN_POINT('',(7.65,-5.1,200.16440471091));
+#679 = SURFACE_CURVE('',#680,(#685,#733),.PCURVE_S1.);
+#680 = CIRCLE('',#681,50.744359292438);
+#681 = AXIS2_PLACEMENT_3D('',#682,#683,#684);
+#682 = CARTESIAN_POINT('',(0.,-5.1,150.));
+#683 = DIRECTION('',(-0.,1.,0.));
+#684 = DIRECTION('',(0.,0.,1.));
+#685 = PCURVE('',#610,#686);
+#686 = DEFINITIONAL_REPRESENTATION('',(#687),#732);
+#687 = B_SPLINE_CURVE_WITH_KNOTS('',8,(#688,#689,#690,#691,#692,#693,
+    #694,#695,#696,#697,#698,#699,#700,#701,#702,#703,#704,#705,#706,
+    #707,#708,#709,#710,#711,#712,#713,#714,#715,#716,#717,#718,#719,
+    #720,#721,#722,#723,#724,#725,#726,#727,#728,#729,#730,#731),
+  .UNSPECIFIED.,.F.,.F.,(9,7,7,7,7,7,9),(0.151332636977,0.240049117591,
+    0.406392518741,0.551942994748,0.80665632776,1.188726327277,
+    1.570796326795),.UNSPECIFIED.);
+#688 = CARTESIAN_POINT('',(5.695182703632,1.389527695651));
+#689 = CARTESIAN_POINT('',(5.728745369077,1.380300623925));
+#690 = CARTESIAN_POINT('',(5.75838102969,1.370837601429));
+#691 = CARTESIAN_POINT('',(5.784772174102,1.361186676967));
+#692 = CARTESIAN_POINT('',(5.808454566049,1.351381955417));
+#693 = CARTESIAN_POINT('',(5.829841733303,1.341448995293));
+#694 = CARTESIAN_POINT('',(5.84926522892,1.331407581206));
+#695 = CARTESIAN_POINT('',(5.866991806846,1.321273364895));
+#696 = CARTESIAN_POINT('',(5.91370660343,1.291906967005));
+#697 = CARTESIAN_POINT('',(5.938976835465,1.272473079502));
+#698 = CARTESIAN_POINT('',(5.960493612627,1.252840436459));
+#699 = CARTESIAN_POINT('',(5.979103979611,1.233054883899));
+#700 = CARTESIAN_POINT('',(5.995404703899,1.213149039849));
+#701 = CARTESIAN_POINT('',(6.009820650861,1.193145415053));
+#702 = CARTESIAN_POINT('',(6.022674071993,1.173061185037));
+#703 = CARTESIAN_POINT('',(6.044308729294,1.135276565191));
+#704 = CARTESIAN_POINT('',(6.053398184855,1.117592014924));
+#705 = CARTESIAN_POINT('',(6.061646881962,1.099864489187));
+#706 = CARTESIAN_POINT('',(6.06917805527,1.082100431401));
+#707 = CARTESIAN_POINT('',(6.076088277776,1.064304870251));
+#708 = CARTESIAN_POINT('',(6.082455654461,1.046481863854));
+#709 = CARTESIAN_POINT('',(6.088343954572,1.028634716083));
+#710 = CARTESIAN_POINT('',(6.10336592867,0.979496261441));
+#711 = CARTESIAN_POINT('',(6.111621445612,0.9481608547));
+#712 = CARTESIAN_POINT('',(6.118858399441,0.916774737928));
+#713 = CARTESIAN_POINT('',(6.125262473121,0.885347484224));
+#714 = CARTESIAN_POINT('',(6.130971966653,0.853886242422));
+#715 = CARTESIAN_POINT('',(6.136090826811,0.822396396839));
+#716 = CARTESIAN_POINT('',(6.140701057168,0.790882219155));
+#717 = CARTESIAN_POINT('',(6.151118347034,0.712044510553));
+#718 = CARTESIAN_POINT('',(6.156371283678,0.664694848546));
+#719 = CARTESIAN_POINT('',(6.160847319174,0.617309719261));
+#720 = CARTESIAN_POINT('',(6.164684183288,0.569896505503));
+#721 = CARTESIAN_POINT('',(6.167982458395,0.522460760406));
+#722 = CARTESIAN_POINT('',(6.170815098397,0.475006697084));
+#723 = CARTESIAN_POINT('',(6.173237704278,0.427537731213));
+#724 = CARTESIAN_POINT('',(6.177346620029,0.332575648522));
+#725 = CARTESIAN_POINT('',(6.179032939155,0.285082532156));
+#726 = CARTESIAN_POINT('',(6.180393033288,0.237580169534));
+#727 = CARTESIAN_POINT('',(6.181455460874,0.19007081886));
+#728 = CARTESIAN_POINT('',(6.182239773124,0.142556416594));
+#729 = CARTESIAN_POINT('',(6.182758521491,9.503871251789E-02));
+#730 = CARTESIAN_POINT('',(6.183017886018,4.751935620192E-02));
+#731 = CARTESIAN_POINT('',(6.183017886018,0.));
+#732 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#733 = PCURVE('',#734,#739);
+#734 = PLANE('',#735);
+#735 = AXIS2_PLACEMENT_3D('',#736,#737,#738);
+#736 = CARTESIAN_POINT('',(7.65,-5.1,135.));
+#737 = DIRECTION('',(-0.,1.,0.));
+#738 = DIRECTION('',(0.,0.,1.));
+#739 = DEFINITIONAL_REPRESENTATION('',(#740),#744);
+#740 = CIRCLE('',#741,50.744359292438);
+#741 = AXIS2_PLACEMENT_2D('',#742,#743);
+#742 = CARTESIAN_POINT('',(15.,-7.65));
+#743 = DIRECTION('',(1.,0.));
+#744 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#745 = ORIENTED_EDGE('',*,*,#746,.F.);
+#746 = EDGE_CURVE('',#747,#677,#749,.T.);
+#747 = VERTEX_POINT('',#748);
+#748 = CARTESIAN_POINT('',(7.65,0.,200.42298582987));
+#749 = SURFACE_CURVE('',#750,(#755,#773),.PCURVE_S1.);
+#750 = CIRCLE('',#751,50.422985829877);
+#751 = AXIS2_PLACEMENT_3D('',#752,#753,#754);
+#752 = CARTESIAN_POINT('',(7.65,0.,150.));
+#753 = DIRECTION('',(1.,0.,-0.));
+#754 = DIRECTION('',(0.,0.,1.));
+#755 = PCURVE('',#610,#756);
+#756 = DEFINITIONAL_REPRESENTATION('',(#757),#772);
+#757 = B_SPLINE_CURVE_WITH_KNOTS('',7,(#758,#759,#760,#761,#762,#763,
+    #764,#765,#766,#767,#768,#769,#770,#771),.UNSPECIFIED.,.F.,.F.,(8,6,
+    8),(0.,5.065880019502E-02,0.10131760039),.UNSPECIFIED.);
+#758 = CARTESIAN_POINT('',(6.28318530718,1.420228054018));
+#759 = CARTESIAN_POINT('',(6.235484691598,1.420228054018));
+#760 = CARTESIAN_POINT('',(6.187784100228,1.419825310827));
+#761 = CARTESIAN_POINT('',(6.140441967762,1.419019829088));
+#762 = CARTESIAN_POINT('',(6.093817672415,1.417818375616));
+#763 = CARTESIAN_POINT('',(6.048227632352,1.416234589835));
+#764 = CARTESIAN_POINT('',(6.003913903085,1.414286707803));
+#765 = CARTESIAN_POINT('',(5.91818498319,1.409704354751));
+#766 = CARTESIAN_POINT('',(5.87676976234,1.407069884647));
+#767 = CARTESIAN_POINT('',(5.83697658071,1.404112919921));
+#768 = CARTESIAN_POINT('',(5.798907965495,1.400856859438));
+#769 = CARTESIAN_POINT('',(5.762598258809,1.397325591087));
+#770 = CARTESIAN_POINT('',(5.728036854313,1.393542045138));
+#771 = CARTESIAN_POINT('',(5.695182703632,1.389527695651));
+#772 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#773 = PCURVE('',#774,#779);
+#774 = PLANE('',#775);
+#775 = AXIS2_PLACEMENT_3D('',#776,#777,#778);
+#776 = CARTESIAN_POINT('',(7.65,-5.1,135.));
+#777 = DIRECTION('',(1.,0.,-0.));
+#778 = DIRECTION('',(0.,0.,1.));
+#779 = DEFINITIONAL_REPRESENTATION('',(#780),#784);
+#780 = CIRCLE('',#781,50.422985829877);
+#781 = AXIS2_PLACEMENT_2D('',#782,#783);
+#782 = CARTESIAN_POINT('',(15.,-5.1));
+#783 = DIRECTION('',(1.,0.));
+#784 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#785 = ORIENTED_EDGE('',*,*,#786,.T.);
+#786 = EDGE_CURVE('',#747,#787,#789,.T.);
+#787 = VERTEX_POINT('',#788);
+#788 = CARTESIAN_POINT('',(0.,0.,201.));
+#789 = SEAM_CURVE('',#790,(#795,#802),.PCURVE_S1.);
+#790 = CIRCLE('',#791,51.);
+#791 = AXIS2_PLACEMENT_3D('',#792,#793,#794);
+#792 = CARTESIAN_POINT('',(0.,0.,150.));
+#793 = DIRECTION('',(0.,-1.,0.));
+#794 = DIRECTION('',(0.,0.,-1.));
+#795 = PCURVE('',#610,#796);
+#796 = DEFINITIONAL_REPRESENTATION('',(#797),#801);
+#797 = LINE('',#798,#799);
+#798 = CARTESIAN_POINT('',(0.,-1.570796326795));
+#799 = VECTOR('',#800,1.);
+#800 = DIRECTION('',(0.,1.));
+#801 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#802 = PCURVE('',#610,#803);
+#803 = DEFINITIONAL_REPRESENTATION('',(#804),#808);
+#804 = LINE('',#805,#806);
+#805 = CARTESIAN_POINT('',(6.28318530718,-1.570796326795));
+#806 = VECTOR('',#807,1.);
+#807 = DIRECTION('',(0.,1.));
+#808 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#809 = ORIENTED_EDGE('',*,*,#786,.F.);
+#810 = ORIENTED_EDGE('',*,*,#811,.F.);
+#811 = EDGE_CURVE('',#601,#747,#812,.T.);
+#812 = SURFACE_CURVE('',#813,(#818,#836),.PCURVE_S1.);
+#813 = CIRCLE('',#814,50.422985829877);
+#814 = AXIS2_PLACEMENT_3D('',#815,#816,#817);
+#815 = CARTESIAN_POINT('',(7.65,0.,150.));
+#816 = DIRECTION('',(1.,0.,-0.));
+#817 = DIRECTION('',(0.,0.,1.));
+#818 = PCURVE('',#610,#819);
+#819 = DEFINITIONAL_REPRESENTATION('',(#820),#835);
+#820 = B_SPLINE_CURVE_WITH_KNOTS('',7,(#821,#822,#823,#824,#825,#826,
+    #827,#828,#829,#830,#831,#832,#833,#834),.UNSPECIFIED.,.F.,.F.,(8,6,
+    8),(6.18186770679,6.232526506985,6.28318530718),.UNSPECIFIED.);
+#821 = CARTESIAN_POINT('',(0.588002603548,1.389527695651));
+#822 = CARTESIAN_POINT('',(0.555148452867,1.393542045138));
+#823 = CARTESIAN_POINT('',(0.520587048371,1.397325591087));
+#824 = CARTESIAN_POINT('',(0.484277341685,1.400856859438));
+#825 = CARTESIAN_POINT('',(0.446208726469,1.404112919922));
+#826 = CARTESIAN_POINT('',(0.406415544839,1.407069884647));
+#827 = CARTESIAN_POINT('',(0.365000323989,1.409704354751));
+#828 = CARTESIAN_POINT('',(0.279271404095,1.414286707803));
+#829 = CARTESIAN_POINT('',(0.234957674827,1.416234589835));
+#830 = CARTESIAN_POINT('',(0.189367634765,1.417818375617));
+#831 = CARTESIAN_POINT('',(0.142743339417,1.419019829087));
+#832 = CARTESIAN_POINT('',(9.540120695172E-02,1.419825310827));
+#833 = CARTESIAN_POINT('',(4.770061558156E-02,1.420228054018));
+#834 = CARTESIAN_POINT('',(1.614388188236E-15,1.420228054018));
+#835 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#836 = PCURVE('',#774,#837);
+#837 = DEFINITIONAL_REPRESENTATION('',(#838),#842);
+#838 = CIRCLE('',#839,50.422985829877);
+#839 = AXIS2_PLACEMENT_2D('',#840,#841);
+#840 = CARTESIAN_POINT('',(15.,-5.1));
+#841 = DIRECTION('',(1.,0.));
+#842 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#843 = ADVANCED_FACE('',(#844),#663,.F.);
+#844 = FACE_BOUND('',#845,.F.);
+#845 = EDGE_LOOP('',(#846,#916,#937,#938));
+#846 = ORIENTED_EDGE('',*,*,#847,.F.);
+#847 = EDGE_CURVE('',#848,#444,#850,.T.);
+#848 = VERTEX_POINT('',#849);
+#849 = CARTESIAN_POINT('',(7.65,5.1,199.65599158208));
+#850 = SURFACE_CURVE('',#851,(#856,#863),.PCURVE_S1.);
+#851 = CIRCLE('',#852,50.24181525383);
+#852 = AXIS2_PLACEMENT_3D('',#853,#854,#855);
+#853 = CARTESIAN_POINT('',(0.,5.1,150.));
+#854 = DIRECTION('',(-0.,1.,0.));
+#855 = DIRECTION('',(0.,0.,1.));
+#856 = PCURVE('',#663,#857);
+#857 = DEFINITIONAL_REPRESENTATION('',(#858),#862);
+#858 = CIRCLE('',#859,50.24181525383);
+#859 = AXIS2_PLACEMENT_2D('',#860,#861);
+#860 = CARTESIAN_POINT('',(15.,-7.65));
+#861 = DIRECTION('',(1.,0.));
+#862 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#863 = PCURVE('',#864,#869);
+#864 = SPHERICAL_SURFACE('',#865,50.5);
+#865 = AXIS2_PLACEMENT_3D('',#866,#867,#868);
+#866 = CARTESIAN_POINT('',(0.,0.,150.));
+#867 = DIRECTION('',(0.,0.,1.));
+#868 = DIRECTION('',(1.,0.,-0.));
+#869 = DEFINITIONAL_REPRESENTATION('',(#870),#915);
+#870 = B_SPLINE_CURVE_WITH_KNOTS('',8,(#871,#872,#873,#874,#875,#876,
+    #877,#878,#879,#880,#881,#882,#883,#884,#885,#886,#887,#888,#889,
+    #890,#891,#892,#893,#894,#895,#896,#897,#898,#899,#900,#901,#902,
+    #903,#904,#905,#906,#907,#908,#909,#910,#911,#912,#913,#914),
+  .UNSPECIFIED.,.F.,.F.,(9,7,7,7,7,7,9),(0.152858182827,0.241479316825,
+    0.407643943072,0.553037991037,0.807477574976,1.189136950886,
+    1.570796326795),.UNSPECIFIED.);
+#871 = CARTESIAN_POINT('',(0.588002603548,1.387712734649));
+#872 = CARTESIAN_POINT('',(0.554815798994,1.378495579571));
+#873 = CARTESIAN_POINT('',(0.525469841025,1.369045366836));
+#874 = CARTESIAN_POINT('',(0.499304525793,1.359409035232));
+#875 = CARTESIAN_POINT('',(0.475800018331,1.349620051233));
+#876 = CARTESIAN_POINT('',(0.454553749725,1.339703566213));
+#877 = CARTESIAN_POINT('',(0.435242330048,1.329679094908));
+#878 = CARTESIAN_POINT('',(0.417605002988,1.319562105426));
+#879 = CARTESIAN_POINT('',(0.371094356849,1.290245684958));
+#880 = CARTESIAN_POINT('',(0.34589313409,1.270844941816));
+#881 = CARTESIAN_POINT('',(0.324411371045,1.251245156063));
+#882 = CARTESIAN_POINT('',(0.305814355987,1.231492019153));
+#883 = CARTESIAN_POINT('',(0.289513390791,1.211618048191));
+#884 = CARTESIAN_POINT('',(0.275088089123,1.191645763188));
+#885 = CARTESIAN_POINT('',(0.262219334511,1.171592352087));
+#886 = CARTESIAN_POINT('',(0.240548508996,1.133864600862));
+#887 = CARTESIAN_POINT('',(0.231439148057,1.116206214753));
+#888 = CARTESIAN_POINT('',(0.223168885131,1.098504499013));
+#889 = CARTESIAN_POINT('',(0.215615271431,1.080765923711));
+#890 = CARTESIAN_POINT('',(0.208682240435,1.062995543815));
+#891 = CARTESIAN_POINT('',(0.202292034666,1.04519744174));
+#892 = CARTESIAN_POINT('',(0.196381111541,1.027374944055));
+#893 = CARTESIAN_POINT('',(0.181297931002,0.978303634151));
+#894 = CARTESIAN_POINT('',(0.173004585112,0.947010239842));
+#895 = CARTESIAN_POINT('',(0.165731769992,0.915665529272));
+#896 = CARTESIAN_POINT('',(0.159293972208,0.884279165975));
+#897 = CARTESIAN_POINT('',(0.153552937892,0.85285837037));
+#898 = CARTESIAN_POINT('',(0.148404652235,0.821408586038));
+#899 = CARTESIAN_POINT('',(0.143767024014,0.789934133485));
+#900 = CARTESIAN_POINT('',(0.133286042719,0.711195000321));
+#901 = CARTESIAN_POINT('',(0.127999214467,0.663903819917));
+#902 = CARTESIAN_POINT('',(0.123493254594,0.616576647396));
+#903 = CARTESIAN_POINT('',(0.119630014343,0.569220964865));
+#904 = CARTESIAN_POINT('',(0.116308577148,0.521842402215));
+#905 = CARTESIAN_POINT('',(0.113455697775,0.474445233887));
+#906 = CARTESIAN_POINT('',(0.111015543895,0.427032926321));
+#907 = CARTESIAN_POINT('',(0.106876539994,0.332183773328));
+#908 = CARTESIAN_POINT('',(0.105177680789,0.284746928357));
+#909 = CARTESIAN_POINT('',(0.103807363612,0.237300686904));
+#910 = CARTESIAN_POINT('',(0.10273688978,0.189847342928));
+#911 = CARTESIAN_POINT('',(0.101946607932,0.142388864184));
+#912 = CARTESIAN_POINT('',(0.10142390157,9.49270290968E-02));
+#913 = CARTESIAN_POINT('',(0.101162558036,4.74635144909E-02));
+#914 = CARTESIAN_POINT('',(0.101162558036,0.));
+#915 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#916 = ORIENTED_EDGE('',*,*,#917,.T.);
+#917 = EDGE_CURVE('',#848,#601,#918,.T.);
+#918 = SURFACE_CURVE('',#919,(#923,#930),.PCURVE_S1.);
+#919 = LINE('',#920,#921);
+#920 = CARTESIAN_POINT('',(7.65,5.1,135.));
+#921 = VECTOR('',#922,1.);
+#922 = DIRECTION('',(0.,0.,1.));
+#923 = PCURVE('',#663,#924);
+#924 = DEFINITIONAL_REPRESENTATION('',(#925),#929);
+#925 = LINE('',#926,#927);
+#926 = CARTESIAN_POINT('',(0.,0.));
+#927 = VECTOR('',#928,1.);
+#928 = DIRECTION('',(1.,0.));
+#929 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#930 = PCURVE('',#774,#931);
+#931 = DEFINITIONAL_REPRESENTATION('',(#932),#936);
+#932 = LINE('',#933,#934);
+#933 = CARTESIAN_POINT('',(0.,-10.2));
+#934 = VECTOR('',#935,1.);
+#935 = DIRECTION('',(1.,0.));
+#936 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#937 = ORIENTED_EDGE('',*,*,#600,.T.);
+#938 = ORIENTED_EDGE('',*,*,#465,.F.);
+#939 = ADVANCED_FACE('',(#940),#774,.T.);
+#940 = FACE_BOUND('',#941,.T.);
+#941 = EDGE_LOOP('',(#942,#965,#1000,#1033,#1034,#1035));
+#942 = ORIENTED_EDGE('',*,*,#943,.F.);
+#943 = EDGE_CURVE('',#944,#677,#946,.T.);
+#944 = VERTEX_POINT('',#945);
+#945 = CARTESIAN_POINT('',(7.65,-5.1,199.65599158208));
+#946 = SURFACE_CURVE('',#947,(#951,#958),.PCURVE_S1.);
+#947 = LINE('',#948,#949);
+#948 = CARTESIAN_POINT('',(7.65,-5.1,135.));
+#949 = VECTOR('',#950,1.);
+#950 = DIRECTION('',(0.,0.,1.));
+#951 = PCURVE('',#774,#952);
+#952 = DEFINITIONAL_REPRESENTATION('',(#953),#957);
+#953 = LINE('',#954,#955);
+#954 = CARTESIAN_POINT('',(0.,0.));
+#955 = VECTOR('',#956,1.);
+#956 = DIRECTION('',(1.,0.));
+#957 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#958 = PCURVE('',#734,#959);
+#959 = DEFINITIONAL_REPRESENTATION('',(#960),#964);
+#960 = LINE('',#961,#962);
+#961 = CARTESIAN_POINT('',(0.,0.));
+#962 = VECTOR('',#963,1.);
+#963 = DIRECTION('',(1.,0.));
+#964 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#965 = ORIENTED_EDGE('',*,*,#966,.F.);
+#966 = EDGE_CURVE('',#967,#944,#969,.T.);
+#967 = VERTEX_POINT('',#968);
+#968 = CARTESIAN_POINT('',(7.65,0.,199.91720645228));
+#969 = SURFACE_CURVE('',#970,(#975,#982),.PCURVE_S1.);
+#970 = CIRCLE('',#971,49.917206452285);
+#971 = AXIS2_PLACEMENT_3D('',#972,#973,#974);
+#972 = CARTESIAN_POINT('',(7.65,0.,150.));
+#973 = DIRECTION('',(1.,0.,-0.));
+#974 = DIRECTION('',(0.,0.,1.));
+#975 = PCURVE('',#774,#976);
+#976 = DEFINITIONAL_REPRESENTATION('',(#977),#981);
+#977 = CIRCLE('',#978,49.917206452285);
+#978 = AXIS2_PLACEMENT_2D('',#979,#980);
+#979 = CARTESIAN_POINT('',(15.,-5.1));
+#980 = DIRECTION('',(1.,0.));
+#981 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#982 = PCURVE('',#864,#983);
+#983 = DEFINITIONAL_REPRESENTATION('',(#984),#999);
+#984 = B_SPLINE_CURVE_WITH_KNOTS('',7,(#985,#986,#987,#988,#989,#990,
+    #991,#992,#993,#994,#995,#996,#997,#998),.UNSPECIFIED.,.F.,.F.,(8,6,
+    8),(0.,5.117388434053E-02,0.102347768681),.UNSPECIFIED.);
+#985 = CARTESIAN_POINT('',(6.28318530718,1.41872573847));
+#986 = CARTESIAN_POINT('',(6.235483022407,1.41872573847));
+#987 = CARTESIAN_POINT('',(6.187780761867,1.418318886065));
+#988 = CARTESIAN_POINT('',(6.140437080844,1.417505185946));
+#989 = CARTESIAN_POINT('',(6.093811479006,1.41629147551));
+#990 = CARTESIAN_POINT('',(6.048220470966,1.414691536456));
+#991 = CARTESIAN_POINT('',(6.003906169481,1.41272379455));
+#992 = CARTESIAN_POINT('',(5.918176951118,1.408094740119));
+#993 = CARTESIAN_POINT('',(5.876762003987,1.405433428521));
+#994 = CARTESIAN_POINT('',(5.836969546141,1.402446347253));
+#995 = CARTESIAN_POINT('',(5.798902100712,1.399157137382));
+#996 = CARTESIAN_POINT('',(5.762593981635,1.395589933234));
+#997 = CARTESIAN_POINT('',(5.72803454552,1.39176790089));
+#998 = CARTESIAN_POINT('',(5.695182703632,1.387712734649));
+#999 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1000 = ORIENTED_EDGE('',*,*,#1001,.F.);
+#1001 = EDGE_CURVE('',#848,#967,#1002,.T.);
+#1002 = SURFACE_CURVE('',#1003,(#1008,#1015),.PCURVE_S1.);
+#1003 = CIRCLE('',#1004,49.917206452285);
+#1004 = AXIS2_PLACEMENT_3D('',#1005,#1006,#1007);
+#1005 = CARTESIAN_POINT('',(7.65,0.,150.));
+#1006 = DIRECTION('',(1.,0.,-0.));
+#1007 = DIRECTION('',(0.,0.,1.));
+#1008 = PCURVE('',#774,#1009);
+#1009 = DEFINITIONAL_REPRESENTATION('',(#1010),#1014);
+#1010 = CIRCLE('',#1011,49.917206452285);
+#1011 = AXIS2_PLACEMENT_2D('',#1012,#1013);
+#1012 = CARTESIAN_POINT('',(15.,-5.1));
+#1013 = DIRECTION('',(1.,0.));
+#1014 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1015 = PCURVE('',#864,#1016);
+#1016 = DEFINITIONAL_REPRESENTATION('',(#1017),#1032);
+#1017 = B_SPLINE_CURVE_WITH_KNOTS('',7,(#1018,#1019,#1020,#1021,#1022,
+    #1023,#1024,#1025,#1026,#1027,#1028,#1029,#1030,#1031),
+  .UNSPECIFIED.,.F.,.F.,(8,6,8),(6.180837538499,6.232011422839,
+    6.28318530718),.UNSPECIFIED.);
+#1018 = CARTESIAN_POINT('',(0.588002603548,1.387712734649));
+#1019 = CARTESIAN_POINT('',(0.55515076166,1.39176790089));
+#1020 = CARTESIAN_POINT('',(0.520591325544,1.395589933234));
+#1021 = CARTESIAN_POINT('',(0.484283206467,1.399157137381));
+#1022 = CARTESIAN_POINT('',(0.446215761039,1.402446347254));
+#1023 = CARTESIAN_POINT('',(0.406423303192,1.405433428521));
+#1024 = CARTESIAN_POINT('',(0.365008356062,1.408094740119));
+#1025 = CARTESIAN_POINT('',(0.279279137698,1.41272379455));
+#1026 = CARTESIAN_POINT('',(0.234964836214,1.414691536456));
+#1027 = CARTESIAN_POINT('',(0.189373828174,1.416291475509));
+#1028 = CARTESIAN_POINT('',(0.142748226336,1.417505185947));
+#1029 = CARTESIAN_POINT('',(9.54045453125E-02,1.418318886065));
+#1030 = CARTESIAN_POINT('',(4.770228477296E-02,1.41872573847));
+#1031 = CARTESIAN_POINT('',(1.598194695534E-15,1.41872573847));
+#1032 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1033 = ORIENTED_EDGE('',*,*,#917,.T.);
+#1034 = ORIENTED_EDGE('',*,*,#811,.T.);
+#1035 = ORIENTED_EDGE('',*,*,#746,.T.);
+#1036 = ADVANCED_FACE('',(#1037),#734,.T.);
+#1037 = FACE_BOUND('',#1038,.T.);
+#1038 = EDGE_LOOP('',(#1039,#1102,#1103,#1104));
+#1039 = ORIENTED_EDGE('',*,*,#1040,.F.);
+#1040 = EDGE_CURVE('',#944,#492,#1041,.T.);
+#1041 = SURFACE_CURVE('',#1042,(#1047,#1054),.PCURVE_S1.);
+#1042 = CIRCLE('',#1043,50.24181525383);
+#1043 = AXIS2_PLACEMENT_3D('',#1044,#1045,#1046);
+#1044 = CARTESIAN_POINT('',(0.,-5.1,150.));
+#1045 = DIRECTION('',(-0.,1.,0.));
+#1046 = DIRECTION('',(0.,0.,1.));
+#1047 = PCURVE('',#734,#1048);
+#1048 = DEFINITIONAL_REPRESENTATION('',(#1049),#1053);
+#1049 = CIRCLE('',#1050,50.24181525383);
+#1050 = AXIS2_PLACEMENT_2D('',#1051,#1052);
+#1051 = CARTESIAN_POINT('',(15.,-7.65));
+#1052 = DIRECTION('',(1.,0.));
+#1053 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1054 = PCURVE('',#864,#1055);
+#1055 = DEFINITIONAL_REPRESENTATION('',(#1056),#1101);
+#1056 = B_SPLINE_CURVE_WITH_KNOTS('',8,(#1057,#1058,#1059,#1060,#1061,
+    #1062,#1063,#1064,#1065,#1066,#1067,#1068,#1069,#1070,#1071,#1072,
+    #1073,#1074,#1075,#1076,#1077,#1078,#1079,#1080,#1081,#1082,#1083,
+    #1084,#1085,#1086,#1087,#1088,#1089,#1090,#1091,#1092,#1093,#1094,
+    #1095,#1096,#1097,#1098,#1099,#1100),.UNSPECIFIED.,.F.,.F.,(9,7,7,7,
+    7,7,9),(0.152858182827,0.241479316825,0.407643943072,0.553037991037,
+    0.807477574976,1.189136950886,1.570796326795),.UNSPECIFIED.);
+#1057 = CARTESIAN_POINT('',(5.695182703632,1.387712734649));
+#1058 = CARTESIAN_POINT('',(5.728369508186,1.378495579571));
+#1059 = CARTESIAN_POINT('',(5.757715466146,1.369045366836));
+#1060 = CARTESIAN_POINT('',(5.783880781393,1.359409035232));
+#1061 = CARTESIAN_POINT('',(5.807385288816,1.349620051233));
+#1062 = CARTESIAN_POINT('',(5.828631557459,1.339703566213));
+#1063 = CARTESIAN_POINT('',(5.847942977124,1.329679094908));
+#1064 = CARTESIAN_POINT('',(5.865580304192,1.319562105426));
+#1065 = CARTESIAN_POINT('',(5.912090950331,1.290245684958));
+#1066 = CARTESIAN_POINT('',(5.93729217309,1.270844941816));
+#1067 = CARTESIAN_POINT('',(5.958773936116,1.251245156063));
+#1068 = CARTESIAN_POINT('',(5.977370951205,1.231492019153));
+#1069 = CARTESIAN_POINT('',(5.993671916371,1.211618048191));
+#1070 = CARTESIAN_POINT('',(6.00809721806,1.191645763188));
+#1071 = CARTESIAN_POINT('',(6.020965972669,1.171592352087));
+#1072 = CARTESIAN_POINT('',(6.042636798184,1.133864600862));
+#1073 = CARTESIAN_POINT('',(6.051746159122,1.116206214753));
+#1074 = CARTESIAN_POINT('',(6.060016422051,1.098504499013));
+#1075 = CARTESIAN_POINT('',(6.06757003575,1.080765923711));
+#1076 = CARTESIAN_POINT('',(6.074503066746,1.062995543815));
+#1077 = CARTESIAN_POINT('',(6.080893272514,1.04519744174));
+#1078 = CARTESIAN_POINT('',(6.086804195639,1.027374944055));
+#1079 = CARTESIAN_POINT('',(6.101887376178,0.978303634151));
+#1080 = CARTESIAN_POINT('',(6.110180722069,0.947010239842));
+#1081 = CARTESIAN_POINT('',(6.117453537172,0.915665529272));
+#1082 = CARTESIAN_POINT('',(6.123891334977,0.884279165975));
+#1083 = CARTESIAN_POINT('',(6.129632369288,0.85285837037));
+#1084 = CARTESIAN_POINT('',(6.134780654945,0.821408586038));
+#1085 = CARTESIAN_POINT('',(6.139418283166,0.789934133485));
+#1086 = CARTESIAN_POINT('',(6.149899264461,0.711195000321));
+#1087 = CARTESIAN_POINT('',(6.155186092708,0.663903819917));
+#1088 = CARTESIAN_POINT('',(6.159692052584,0.616576647396));
+#1089 = CARTESIAN_POINT('',(6.163555292809,0.569220964865));
+#1090 = CARTESIAN_POINT('',(6.166876730033,0.521842402215));
+#1091 = CARTESIAN_POINT('',(6.169729609396,0.474445233887));
+#1092 = CARTESIAN_POINT('',(6.172169763285,0.427032926321));
+#1093 = CARTESIAN_POINT('',(6.176308767185,0.332183773328));
+#1094 = CARTESIAN_POINT('',(6.178007626391,0.284746928357));
+#1095 = CARTESIAN_POINT('',(6.179377943569,0.237300686904));
+#1096 = CARTESIAN_POINT('',(6.180448417401,0.189847342928));
+#1097 = CARTESIAN_POINT('',(6.181238699249,0.142388864184));
+#1098 = CARTESIAN_POINT('',(6.181761405609,9.49270290968E-02));
+#1099 = CARTESIAN_POINT('',(6.182022749144,4.74635144909E-02));
+#1100 = CARTESIAN_POINT('',(6.182022749144,0.));
+#1101 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1102 = ORIENTED_EDGE('',*,*,#943,.T.);
+#1103 = ORIENTED_EDGE('',*,*,#676,.T.);
+#1104 = ORIENTED_EDGE('',*,*,#515,.F.);
+#1105 = ADVANCED_FACE('',(#487),#276,.F.);
+#1106 = ADVANCED_FACE('',(#1107),#864,.F.);
+#1107 = FACE_BOUND('',#1108,.F.);
+#1108 = EDGE_LOOP('',(#1109,#1110,#1111,#1112,#1113,#1137,#1138));
+#1109 = ORIENTED_EDGE('',*,*,#847,.T.);
+#1110 = ORIENTED_EDGE('',*,*,#491,.T.);
+#1111 = ORIENTED_EDGE('',*,*,#1040,.F.);
+#1112 = ORIENTED_EDGE('',*,*,#966,.F.);
+#1113 = ORIENTED_EDGE('',*,*,#1114,.T.);
+#1114 = EDGE_CURVE('',#967,#1115,#1117,.T.);
+#1115 = VERTEX_POINT('',#1116);
+#1116 = CARTESIAN_POINT('',(0.,0.,200.5));
+#1117 = SEAM_CURVE('',#1118,(#1123,#1130),.PCURVE_S1.);
+#1118 = CIRCLE('',#1119,50.5);
+#1119 = AXIS2_PLACEMENT_3D('',#1120,#1121,#1122);
+#1120 = CARTESIAN_POINT('',(0.,0.,150.));
+#1121 = DIRECTION('',(0.,-1.,0.));
+#1122 = DIRECTION('',(0.,0.,-1.));
+#1123 = PCURVE('',#864,#1124);
+#1124 = DEFINITIONAL_REPRESENTATION('',(#1125),#1129);
+#1125 = LINE('',#1126,#1127);
+#1126 = CARTESIAN_POINT('',(0.,-1.570796326795));
+#1127 = VECTOR('',#1128,1.);
+#1128 = DIRECTION('',(0.,1.));
+#1129 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1130 = PCURVE('',#864,#1131);
+#1131 = DEFINITIONAL_REPRESENTATION('',(#1132),#1136);
+#1132 = LINE('',#1133,#1134);
+#1133 = CARTESIAN_POINT('',(6.28318530718,-1.570796326795));
+#1134 = VECTOR('',#1135,1.);
+#1135 = DIRECTION('',(0.,1.));
+#1136 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
+PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
+  ) );
+#1137 = ORIENTED_EDGE('',*,*,#1114,.F.);
+#1138 = ORIENTED_EDGE('',*,*,#1001,.F.);
+#1139 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1143)) 
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#1140,#1141,#1142)) REPRESENTATION_CONTEXT
+('Context #1','3D Context with UNIT and UNCERTAINTY') );
+#1140 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT($,.METRE.) );
+#1141 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
+#1142 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
+#1143 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(2.E-06),#1140,
+  'distance_accuracy_value','confusion accuracy');
+#1144 = SHAPE_DEFINITION_REPRESENTATION(#1145,#33);
+#1145 = PRODUCT_DEFINITION_SHAPE('','',#1146);
+#1146 = PRODUCT_DEFINITION('design','',#1147,#1150);
+#1147 = PRODUCT_DEFINITION_FORMATION('','',#1148);
+#1148 = PRODUCT('Open CASCADE STEP translator 7.5 1.1',
+  'Open CASCADE STEP translator 7.5 1.1','',(#1149));
+#1149 = PRODUCT_CONTEXT('',#2,'mechanical');
+#1150 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
+#1151 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#1152,#1154);
+#1152 = ( REPRESENTATION_RELATIONSHIP('','',#33,#10) 
+REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#1153) 
+SHAPE_REPRESENTATION_RELATIONSHIP() );
+#1153 = ITEM_DEFINED_TRANSFORMATION('','',#11,#15);
+#1154 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',
+  #1155);
+#1155 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('1','','',#5,#1146,$);
+#1156 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#1148));
+ENDSEC;
+END-ISO-10303-21;
diff --git a/src/PythonAddons/macros/midSurface/surfaceMediane.py b/src/PythonAddons/macros/midSurface/surfaceMediane.py
new file mode 100755 (executable)
index 0000000..cfb6e70
--- /dev/null
@@ -0,0 +1,2478 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2016-2022  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+"""Obtention des surfaces médianes à partir d'un objet GEOM ou SHAPER
+
+On sait traiter les faces :
+  . planes
+  . cylindriques
+  . sphériques
+  . toriques
+  . coniques
+
+Pour un objet complexe, on crée l'objet final comme étant la partition de toutes
+les surfaces médianes.
+
+Version initiale par :
+alexandre.prunie@blastsolutions.io
+guillaume.schweitzer@blastsolutions.io
+
+Gérald NICOLAS
++33.1.78.19.43.52
+"""
+
+__revision__ = "V10.48"
+
+#========================= Les imports - Début ===================================
+
+import os
+import sys
+import tempfile
+
+import salome
+
+salome.standalone()
+salome.salome_init()
+
+import SALOMEDS
+from SketchAPI import *
+from salome.shaper import model
+from GeomAPI import *
+from GeomAlgoAPI import *
+
+from salome.geom import geomBuilder
+
+import numpy as np
+
+#========================== Les imports - Fin ====================================
+
+D_FMT = dict()
+D_FMT["stp"] = ["stp", "step"]
+D_FMT["igs"] = ["igs", "iges"]
+for CLE in ("brep", "xao"):
+  D_FMT[CLE] = [CLE]
+
+# statut = 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
+D_COLOR_R = dict()
+D_COLOR_G = dict()
+D_COLOR_B = dict()
+D_COLOR_R[-2] = 255
+D_COLOR_G[-2] = 255
+D_COLOR_B[-2] = 0
+D_COLOR_R[-1] = 255
+D_COLOR_G[-1] = 0
+D_COLOR_B[-1] = 0
+D_COLOR_R[0] = 50
+D_COLOR_G[0] = 50
+D_COLOR_B[0] = 50
+D_COLOR_R[1] = 170
+D_COLOR_G[1] = 255
+D_COLOR_B[1] = 120
+D_COLOR_R[2] = 0
+D_COLOR_G[2] = 0
+D_COLOR_B[2] = 255
+# Transparence des solides traités correctement
+TRANSPARENCE = 0.7
+
+# Limite basse de l'épaisseur pour pouvoir faire les intersections
+EP_MIN = 0.0001
+#EP_MIN = 0.1
+#========================= Début de la fonction ==================================
+
+def decode_cao (fmt_cao):
+  """Décode le format de la cao
+
+Entrées :
+  :fmt_cao: format du fichier, step, iges, etc.
+Sorties :
+  :fmt_cao_0: format décodé
+  """
+
+  fmt_cao_0 = ""
+
+  fmt_cao_low = fmt_cao.lower()
+
+  for cle, l_aux in D_FMT.items():
+    if ( fmt_cao_low in l_aux ):
+      fmt_cao_0 = cle
+      break
+
+  return fmt_cao_0
+
+#=========================  Fin de la fonction ===================================
+
+#========================= Début de la fonction ==================================
+
+def import_cao (part_doc, ficcao, nom_objet=None, verbose=False):
+  """Importation d'une cao
+
+Entrées :
+  :part_doc: part
+  :ficcao: le fichier de la CAO
+Sorties :
+  :objet: l'objet importé dans SHAPER
+  """
+
+
+  erreur = 0
+  message = "Fichier '{}'\n".format(ficcao)
+  if verbose:
+    print (message)
+
+  objet = None
+
+  laux = ficcao.split(".")
+  fmt_cao_0 = decode_cao (laux[-1])
+
+  if ( fmt_cao_0 not in ("stp", "brep", "igs", "xao") ):
+    message += "Le format de CAO est inconnu"
+    erreur = 1
+
+  elif not ficcao:
+    message += "Le fichier de CAO n'a pas été décodé correctement."
+    erreur = 2
+
+  elif not os.path.isfile(ficcao):
+    message += "Le fichier de CAO est inconnu."
+    erreur = 3
+
+  else:
+
+    message = ""
+    objet = model.addImport(part_doc, ficcao)
+    objet.execute(True)
+    model.do()
+
+    if nom_objet is not None:
+      objet.result().setName(nom_objet)
+
+    if verbose:
+      texte  = "Objet   : '{}'\n".format(objet.result().name())
+      texte += "De type : '{}'".format(objet.result().shapeType())
+      print (texte)
+
+
+  return erreur, message, objet
+
+#=========================  Fin de la fonction ===================================
+
+#=================================== La classe ===================================
+
+class SurfaceMediane (object):
+
+  """Calcul des surfaces médianes de solides minces
+
+L'objectif de ce programme est de créer les surfaces médianes, encore appelées fibres neutres, pour \
+une structure qui est un solide ou un assemblage de solides (compound).
+Pour réaliser l'opération, trois façons de faire :
+
+1. On lance le script en précisant le fichier à analyser dans la zone d'auto-test.
+
+2. Si on part d'un script qui manipule un fichier au format CAO, on crée une instance de la classe SurfaceMediane \
+puis on appelle la méthode surf_fic_cao avec ce fichier en argument.
+
+3. Si on part d'un script qui crée un objet SHAPER, on crée une instance de la classe SurfaceMediane \
+puis on appelle la méthode surf_objet_shaper avec cet objet en argument.
+
+
+Le programme crée les surfaces sous réserve que pour le solide envisagé, il a réussi à trouver deux faces \
+de taille identique et supérieure aux tailles des autres faces du solide. \
+Cela fonctionne pour des surfaces planes ou de forme canonique.
+Il crée alors une surface au milieu de ces deux grandes faces. \
+Cette face est coloriée en vert, le solide est en vert et transparent.
+
+On sait traiter les faces :
+  . planes
+  . cylindriques
+  . sphériques
+  . toriques
+  . coniques
+
+Si la création n'a pas eu lieu, un message est émis et les solides sont mise en couleur :
+. Rouge : le solide n'est pas assez mince.
+. Bleu : le solide est trop mince, vis-à-vis de la précision de SHAPER.
+. Orange : la forme de la face n'est pas reconnue.
+
+Options obligatoires
+********************
+Aucune
+
+Options facultatives
+********************
+. Exportation finale dans un fichier step. Par défaut, pas d'export.
+-export_step/-no_export_step
+
+  """
+
+# A. La base
+
+  message_info = ""
+  _verbose = 0
+  _verbose_max = 0
+  affiche_aide_globale = 0
+
+# B. Les variables
+
+  _choix_objet = 0
+  _export_step = False
+  nom_solide = None
+  nom_solide_aux = None
+  _epsilon = 5.e-2
+  part_doc = None
+
+  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 :
+  # 0 si pas encore traité, 1 si traité avec succès, 2 si trop mince, -1 si pas assez mince, -2 si impossible.
+  d_statut_so = dict()
+  # Liste des faces médianes créées et des fonctions initiales
+  l_faces_m = list()
+  # La fonction initiale
+  fonction_0 = None
+
+  faces_pb_nb = 0
+  faces_pb_msg = ""
+
+#=========================== Début de la méthode =================================
+
+  def __init__ ( self, liste_option ):
+
+    """Le constructeur de la classe SurfaceMediane
+
+Décodage des arguments
+On cherche ici les arguments généraux : aide, verbeux
+    """
+
+    for option in liste_option :
+
+      #print (option)
+      if isinstance(option,str):
+        saux = option.upper()
+      #print (saux)
+      if saux in ( "-H", "-HELP" ):
+        self.affiche_aide_globale = 1
+      elif saux == "-V" :
+        self._verbose = 1
+      elif saux == "-VMAX" :
+        self._verbose = 1
+        self._verbose_max = 1
+      elif saux == "-EXPORT_STEP":
+        self._export_step = True
+      elif saux == "-NO_EXPORT_STEP":
+        self._export_step = False
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def __del__(self):
+    """A la suppression de l'instance de classe"""
+    if self._verbose_max:
+      print ("Suppression de l'instance de la classe.")
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _nom_sous_objets (self, objet, lecture, n_recur=0, rang=0):
+    """Gère les noms des sous_objets solides
+
+Entrées :
+  :objet: objet à traiter
+  :lecture: vrai pour lire les noms, faux pour les attribuer
+  :n_recur: niveau de récursivité
+  :rang: rang du sous-objet
+
+Sorties :
+  :rang: rang du sous-objet
+    """
+
+    nom_fonction = __name__ + "/_nom_sous_objets"
+    blabla = "Dans {} :\n".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)
+      texte += "\n{}lecture = {}".format(prefixe,lecture)
+      print (texte)
+
+# 1. Au premier passage, il faut garder la référence au résultat principal
+
+    if ( n_recur ==  0 ):
+      objet_0 = objet.result()
+      if self._verbose_max:
+        print ("d_statut_so = {}".format(self.d_statut_so))
+    else:
+      objet_0 = objet
+
+# 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:
+      texte = "{}Examen de l'objet '{}' ".format(prefixe,objet_0.name())
+      texte += "de type '{}'".format(objet_0.shapeType())
+      texte += "\n{}objet.result().numberOfSubs() : {}".format(prefixe,nb_sub_results)
+      print (texte)
+
+    for n_sobj in range(nb_sub_results):
+
+# 2.1. Exploration récursive de l'arborescence
+
+      rang = self._nom_sous_objets ( objet_0.subResult(n_sobj), lecture, n_recur+1, rang )
+
+# 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
+
+    if ( objet_0.shapeType() == "SOLID" ):
+      # A la lecture, on enregistre le nom
+      if lecture:
+        nom = objet_0.name()
+        self.l_noms_so.append(nom)
+        self.d_statut_so[nom] = 0
+      # A la récupération, on redonne le nom et on affecte une couleur dépendant de l'état
+      else:
+        nom = self.l_noms_so[rang]
+        objet_0.setName(nom)
+        etat = self.d_statut_so[nom]
+        objet_0.setColor (D_COLOR_R[etat],D_COLOR_G[etat],D_COLOR_B[etat])
+        if ( etat == 1 ):
+          objet_0.setTransparency (TRANSPARENCE)
+        rang += 1
+
+    return rang
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _couleur_objet (self, objet, n_recur=0, coul_r=1, coul_g=0, coul_b=0):
+    """Appliquer une couleur à un objet et à ses sous_objets
+
+Entrées :
+  :objet: objet à traiter
+  :n_recur: niveau de récursivité
+  :coul_r,coul_g,coul_b: code RGB de la couleur à appliquer
+
+Sorties :
+  :rang: rang du sous-objet
+    """
+
+    nom_fonction = __name__ + "/_couleur_objet"
+    blabla = "Dans {} :\n".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)
+      texte += "\n{}RGB = ({},{},{})".format(prefixe,coul_r,coul_g,coul_b)
+      print (texte)
+
+# 1. Au premier passage, il faut garder la référence au résultat principal
+
+    if ( n_recur ==  0 ):
+      objet_0 = objet.result()
+    else:
+      objet_0 = objet
+
+# 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:
+      texte = "{}Examen de l'objet '{}' ".format(prefixe,objet_0.name())
+      texte += "de type '{}' ".format(objet_0.shapeType())
+      texte += "et de {} sous-objets".format(nb_sub_results)
+      print (texte)
+
+    for n_sobj in range(nb_sub_results):
+
+# 2.1. Exploration récursive de l'arborescence
+
+      self._couleur_objet ( objet_0.subResult(n_sobj), n_recur+1, coul_r, coul_g, coul_b )
+
+# 2.2. Cet objet n'a pas de sous-objets : on le colore
+    if self._verbose_max:
+      texte = "{}Couleur affectée à l'objet '{}' ".format(prefixe,objet_0.name())
+      print (texte)
+    objet_0.setColor (int(coul_r),int(coul_g),int(coul_b))
+
+    #print ("sortie de {}".format(nom_fonction))
+
+    return
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _isole_solide ( self, solide ):
+    """Isole le solide de son arboresence
+
+Entrées :
+  :solide: le solide à traiter
+
+Sorties :
+  :objet: le solide isolé
+  :recover: la fonction de récupération
+    """
+
+    nom_fonction = __name__ + "/_isole_solide"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+    if self._verbose_max:
+      texte = blabla
+      texte += "Pour le solide '{}' ".format(solide.name())
+      texte += "de l'objet principal '{}'".format(self.objet_principal.name())
+      print (texte)
+
+    if ( solide.name() != self.objet_principal.name() ):
+
+      if self._verbose_max:
+        print (". Extraction du solide")
+
+# 1. Extraction du solide
+      remove_subshapes = model.addRemoveSubShapes(self.part_doc, model.selection("COMPOUND", self.objet_principal.name()))
+      remove_subshapes.setSubShapesToKeep([model.selection("SOLID", solide.name())])
+
+      self.nom_solide_aux = "{}_S".format(solide.name())
+      remove_subshapes.result().setName(self.nom_solide_aux)
+
+      self.fonction_0 = remove_subshapes
+
+# 2. Récupération de l'objet principal
+      recover = model.addRecover(self.part_doc, remove_subshapes, [self.objet_principal])
+      recover.result().setName(self.objet_principal.name())
+
+      objet = remove_subshapes.result()
+
+    else:
+
+      if self._verbose_max:
+        print (". Mise en place du solide")
+
+      objet = solide
+      self.nom_solide_aux = self.objet_principal.name()
+      self.fonction_0 = None
+      recover = None
+
+    if self._verbose_max:
+      texte = "objet final : '{}'\n".format(objet.name())
+      texte += "fonction_0 : {}".format(self.fonction_0)
+      texte += "recover : {}".format(recover)
+      print (texte)
+
+    return objet, recover
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _faces_du_solide ( self, geompy, solide ):
+    """Détermine les faces d'un solide
+
+Entrées :
+  :geompy: environnement de GEOM
+  :solide: le solide à traiter
+
+Sorties :
+  :l_faces: liste des faces du solide
+    """
+
+    nom_fonction = __name__ + "/_faces_du_solide"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+    if self._verbose_max:
+      print (blabla)
+
+    erreur = 0
+    message = ""
+    l_faces = list()
+
+    while ( not erreur ):
+
+      if self._verbose_max:
+        print (".. Traitement du solide '{}'".format(self.nom_solide))
+        longueur, aire, volume = geompy.BasicProperties(solide)
+        texte = "{}".format(geompy.WhatIs(solide))
+        texte += ". longueur, aire, volume : {}, {}, {}".format(longueur,aire,volume)
+        print (texte)
+
+# Liste des faces qui composent le solide
+      l_faces = geompy.ExtractShapes(solide, geompy.ShapeType["FACE"], True)
+      #if self._verbose_max:
+        #print ("Liste des {} faces qui composent le solide :".format(len(l_faces)))
+        #for iaux, face in enumerate(l_faces):
+          #print ("Face n° {} :\n {}".format(iaux,geompy.WhatIs(face)))
+
+      break
+
+    return erreur, message, l_faces
+
+#===========================  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
+
+Entrées :
+  :geompy: environnement de GEOM
+  :l_faces: liste des faces du solide
+
+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)
+    if self._verbose_max:
+      print (blabla+"Nombre de faces : {}.".format(nb_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)
+      if self._verbose_max:
+        texte = "\t. Face numéro {}".format(iaux)
+        #texte += "\n\t. longueur, aire, volume : {}, {}, {}".format(longueur,aire,volume)
+        print (texte)
+
+      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]))
+
+    return tb_caract
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _tri_faces ( self, tb_caract ):
+    """Trie les faces en fonction de leurs surfaces
+
+Entrées :
+  :tb_caract: tableau des caractéristiques géométriques des faces
+
+Sorties :
+  :tb_caract_1[-1], tb_caract_1[-2]: les caractéristiques des 2 faces les plus grandes
+    """
+
+    erreur = 0
+    message = ""
+
+    nom_fonction = __name__ + "/_tri_faces"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+# Tri du tableau en fonction des surfaces
+    if self._verbose_max:
+      print (blabla+"tb_caract brut : {}".format(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))
+
+    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])
+      texte += "\tSurface de la face suivante         : {}, de caractéristiques {}".format(tb_caract_1[-2][1],tb_caract_1[-2][2])
+      if self._verbose_max:
+        texte += "\n\tSurface de la 3ème face suivante    : {}, de caractéristiques {}".format(tb_caract_1[-3][1],tb_caract_1[-3][2])
+      print (texte)
+
+# La surface suivante doit être différente, sinon ce n'est pas un solide mince
+    ecart = np.abs((tb_caract_1[-1][1]-tb_caract_1[-3][1])/tb_caract_1[-1][1])
+    if ( ecart < self._epsilon ):
+      message  = "\nSolide '{}'\n".format(self.nom_solide)
+      message += ". Surface de la plus grande face   : {}\n".format(tb_caract_1[-1][1])
+      message += ". Surface de la 1ère face suivante : {}\n".format(tb_caract_1[-2][1])
+      message += ". Surface de la 2ème face suivante : {}\n".format(tb_caract_1[-3][1])
+      if self._verbose_max:
+        message += ". Ecart relatif :{:4.1f}%\n".format(ecart*100.)
+      message += "L'écart est trop faible par rapport à la limite de {}%.\n".format(self._epsilon*100.)
+      message += "==> Impossible de créer la face médiane car le solide n'est pas assez mince.\n"
+      erreur = -1
+      self.d_statut_so[self.nom_solide] = -1
+      self.faces_pb_nb += 1
+      self.faces_pb_msg += message
+
+    return erreur, message, tb_caract_1[-1], tb_caract_1[-2]
+
+#===========================  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 ):
+    """Contrôle de la validité de l'épaisseur
+
+Entrées :
+  :epaisseur: épaisseur du solide
+    """
+
+    nom_fonction = __name__ + "/_verif_epaisseur"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      texte = blabla
+      texte += ". Epaisseur du solide : {}\n".format(epaisseur)
+      texte += ". EP_MIN              : {}".format(EP_MIN)
+      print (texte)
+
+    if ( epaisseur <= EP_MIN ):
+      message  = "\nSolide '{}'\n".format(self.nom_solide)
+      message += ". Epaisseur : {}\n".format(epaisseur)
+      message += "L'épaisseur est trop faible par rapport à la limite de {}.\n".format(EP_MIN)
+      message += "==> Impossible de créer la face médiane car le solide est trop mince.\n"
+      erreur = 2
+      self.d_statut_so[self.nom_solide] = 2
+      self.faces_pb_nb += 1
+      self.faces_pb_msg += message
+
+    else:
+      erreur = 0
+
+    return erreur
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane ( self, solide, geompy, caract_face_1, caract_face_2 ):
+    """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
+
+Sorties :
+  :face: la face médiane créée
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+    erreur = 0
+    face =  None
+
+# 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 )
+
+# 2.2. Face cylindrique
+    elif forme == geompy.kind.CYLINDER2D:
+      erreur, face = self._cree_face_mediane_cylindre ( solide, caract_face_1, caract_face_2 )
+
+# 2.3. Face sphérique
+    elif forme == geompy.kind.SPHERE2D:
+      erreur, face = self._cree_face_mediane_sphere ( caract_face_1, caract_face_2 )
+
+# 2.4. Face torique
+    elif forme == geompy.kind.TORUS2D:
+      erreur, face = self._cree_face_mediane_tore ( caract_face_1, caract_face_2 )
+
+# 2.5. Face conique
+    elif forme == geompy.kind.CONE2D:
+      erreur, face = self._cree_face_mediane_cone ( geompy, caract_face_1, caract_face_2 )
+
+# 2.N. Face de forme inconnue
+    else:
+      message  = "\nSolide '{}'\n".format(self.nom_solide)
+      message += "sa face la plus grande est de forme : {}\n".format(forme)
+      message += "==> Impossible de créer la face médiane.\n"
+      erreur = -2
+      self.d_statut_so[self.nom_solide] = -2
+      self.faces_pb_nb += 1
+      self.faces_pb_msg += message
+
+# 3. Gestion de la face produite
+
+    if face is not None:
+      self._cree_face_mediane_0 ( face )
+
+    return erreur, face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_0 ( self, face ):
+    """Gestion de la face médiane créée entre deux autres
+
+Entrées :
+  :face: la face médiane créée
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_0"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      texte = blabla
+      print (texte)
+
+# 1. Nom de la face
+    nom_face = self.nom_solide+"_M"
+    #if ( self.nom_solide_aux != self.objet_principal.name() ):
+      #nom_face += "S"
+    face.setName(nom_face)
+    face.result().setName(nom_face)
+
+# 2. Mémorisation de la face et de la fonction initiale
+    self.l_faces_m.append((face, self.fonction_0))
+
+# 3. Couleur verte pour la face
+    self._couleur_objet (face, coul_r=0, coul_g=170, coul_b=0)
+
+# 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 ):
+    """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
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_plane"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+    if self._verbose_max:
+      print (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 )
+
+#   Contrôle de la validité de l'épaisseur
+    erreur = self._verif_epaisseur ( d_face_1_2 )
+
+#   Création de la face
+    if not erreur:
+      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 )
+    else:
+      face = None
+
+    return erreur, face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_plane_0 ( self, geompy, solide, caract_face_1, caract_face_2 ):
+    """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
+
+Sorties :
+  :coo_x, coo_y, coo_z: coordonnées du centre de la base
+  :vnor_x, vnor_y, vnor_z: coordonnées du vecteur normal
+  :taille: estimation de la taille de la future face
+  :d_face_1_2: la distance entre les deux faces
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_plane_0"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+# 1. Caractéristiques de la base
+#   Coordonnées du centre de la base
+    coo_x = caract_face_1[2][1]
+    coo_y = caract_face_1[2][2]
+    coo_z = caract_face_1[2][3]
+#   Coordonnées du vecteur normal
+    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 )
+    taille = 10.*l_diag
+    if self._verbose_max:
+      print ("Taille englobante : {}".format(taille))
+
+# 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)
+    if self._verbose_max:
+      print ("Distance entre les deux faces = {}".format(d_face_1_2))
+
+    return coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_plane_1 ( self, solide, coo_x, coo_y, coo_z, vnor_x, vnor_y, vnor_z, taille, d_face_1_2 ):
+    """Crée la face médiane entre deux autres - cas des surfaces planes
+
+Création des objets temporaires et de la face médiane
+
+Entrées :
+  :solide: l'objet solide à traiter
+  :coo_x, coo_y, coo_z: coordonnées du centre de la base
+  :vnor_x, vnor_y, vnor_z: coordonnées du vecteur normal
+  :taille: estimation de la taille de la future face
+  :d_face_1_2: la distance entre les deux faces
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_plane_1"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+    if self._verbose_max:
+      texte = blabla
+      texte += "Centre   : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
+      texte += "Normale  : ({}, {}, {})\n".format(vnor_x, vnor_y, vnor_z)
+      texte += "Taille   : {}\n".format(taille)
+      texte += "Distance entre les deux faces : {}".format(d_face_1_2)
+      print (texte)
+
+#   Création de paramètres
+    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_x, coo_y, coo_z)
+    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_x, vnor_y, vnor_z)
+    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 d'un sketch
+    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()
+
+    ### Create SketchLine
+    SketchLine_1 = sketch.addLine(-taille/2., taille/2., taille/2., taille/2.)
+
+    ### Create SketchLine
+    SketchLine_2 = sketch.addLine(taille/2., taille/2., taille/2., -taille/2.)
+
+    ### Create SketchLine
+    SketchLine_3 = sketch.addLine(taille/2., -taille/2., -taille/2., -taille/2.)
+
+    ### Create SketchLine
+    SketchLine_4 = sketch.addLine(-taille/2., -taille/2., -taille/2., taille/2.)
+    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())
+
+    ### Create SketchLine
+    SketchLine_5 = sketch.addLine(-taille/2., taille/2., taille/2., -taille/2.)
+    SketchLine_5.setAuxiliary(True)
+
+    ### 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)
+
+    ### 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))
+
+    # 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 ( nom_sketch, nom_normal, nom_solide, distance, iaux )
+
+      if face.results():
+        # Si on traite un objet solide unique, on le récupère
+        if ( self.nom_solide_aux == self.objet_principal.name() ):
+          if self._verbose_max:
+            print ("On traite un objet solide unique ==> on le récupère.")
+          Recover_2 = model.addRecover(self.part_doc, face, [Recover_1.result()])
+          Recover_2.result().setName("{}_S".format(self.nom_solide_aux))
+        nb_inter = face.result().numberOfSubs()
+        if self._verbose_max:
+          print ("Nombre d'intersections : {}".format(nb_inter))
+        # Une seule intersection : c'est la bonne
+        # Sinon, c'est que le solide est trop mince. On fusionnerait les faces.
+        if (nb_inter > 1 ):
+          face = self._cree_face_mediane_plane_3 ( face )
+        break
+      # Si l'intersection est vide, on la translate dans l'autre sens
+      else:
+        if self._verbose_max:
+          print ("L'intersection est vide.")
+        face = None
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_plane_2 ( self, nom_sketch, nom_normal, nom_solide, distance, icpt=0 ):
+    """Crée la face médiane entre deux autres - cas des surfaces planes
+
+Intersection de la face avec le solide
+
+Entrées :
+  :nom_sketch: nom du sketch
+  :nom_normal: nom du vecteur normal
+  :nom_solide: nom du solide à intersecter
+  :distance: la distance de translation
+  :icpt: numéro de la tentative
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_plane_2"
+    blabla = "\nDans {} :\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)
+
+    # 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)
+
+#   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)
+    Translation_1.result().setColor(85, 0, 255)
+
+#   Intersection de cette face avec le solide initial
+    face = model.addCommon(self.part_doc, [model.selection("SOLID", nom_solide), model.selection("FACE", nom_trans)], keepSubResults = True)
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_plane_3 ( self, face ):
+    """Crée la face médiane entre deux autres - cas des surfaces planes
+
+Fusion des 2 intersections
+
+Entrées :
+  :face: la face médiane composée de plusieurs intersections
+
+Sorties :
+  :face_m: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_plane_3"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+    if self._verbose_max:
+      texte = blabla
+      print (texte)
+
+# Nommage des sous-objets
+    l_fuse = list()
+    for iaux in range(face.result().numberOfSubs()):
+      nom = "{}_common_{}".format(self.nom_solide_aux,iaux)
+      face.result().subResult(iaux).setName(nom)
+      l_fuse.append(model.selection("FACE", '{}'.format(nom)))
+
+#   Fusion
+    if self._verbose_max:
+      print ("Fusion de {} faces.".format(len(l_fuse)))
+    face_m = model.addFuse(self.part_doc, l_fuse, keepSubResults = True)
+
+    return face_m
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cylindre ( self, solide, caract_face_1, caract_face_2 ):
+    """Crée la face médiane entre deux autres - cas des cylindres
+
+Entrées :
+  :solide: solide SHAPER à traiter
+  :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_cylindre"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Caractéristiques des cylindres
+    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 )
+
+#   Contrôle de la validité de l'épaisseur
+    erreur = self._verif_epaisseur ( epaisseur )
+
+#   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 )
+    else:
+      self._couleur_objet (solide, coul_r=0, coul_g=0, coul_b=255)
+      face = None
+
+    return erreur, face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cylindre_0 ( self, solide, caract_face_1, caract_face_2 ):
+    """Crée la face médiane entre deux autres - cas des cylindres
+
+Décodage des caractéristiques
+
+Entrées :
+  :solide: l'objet solide à traiter
+  :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
+
+Sorties :
+  :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
+  :hauteur: hauteur du cylindre
+  :epaisseur: épaisseur de l'interface entre les deux faces
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_cylindre_0"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Coordonnées du centre de la base
+    coo_x = caract_face_1[2][1]
+    coo_y = caract_face_1[2][2]
+    coo_z = caract_face_1[2][3]
+#   Coordonnées de l'axe
+    axe_x = caract_face_1[2][4]
+    axe_y = caract_face_1[2][5]
+    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 )
+    hauteur = 10.*l_diag
+    if self._verbose_max:
+      print ("Hauteur englobante : {}".format(hauteur))
+#   Epaisseur
+    epaisseur = np.abs(caract_face_2[2][7]-caract_face_1[2][7])
+
+    return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon, hauteur, epaisseur
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== 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 ):
+    """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
+  :hauteur: hauteur du cylindre
+
+Sorties :
+  :face: la face médiane
+    """
+    nom_fonction = __name__ + "/_cree_face_mediane_cylindre_1"
+    blabla = "\nDans {} :\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)
+
+#   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 d'un sketch
+    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))
+
+    SketchProjection_1 = sketch.addProjection(model.selection("VERTEX", nom_centre), 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)
+
+#   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")
+    nom_cylindre = "{}_cylindre".format(self.nom_solide)
+    cylindre.setName(nom_cylindre)
+    cylindre.result().setName(nom_cylindre)
+    cylindre.result().setColor(85, 0, 255)
+
+#   Intersection de la face cylindrique avec le solide initial
+    face = self._creation_face_inter ( nom_cylindre )
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_sphere ( self, caract_face_1, caract_face_2 ):
+    """Crée la face médiane entre deux autres - cas des sphères
+
+Entrées :
+  :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_sphere"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Caractéristiques des sphères
+    coo_x, coo_y, coo_z, rayon, epaisseur = self._cree_face_mediane_sphere_0 ( caract_face_1, caract_face_2 )
+
+#   Contrôle de la validité de l'épaisseur
+    erreur = self._verif_epaisseur ( epaisseur )
+
+#   Création de la face
+    if not erreur:
+      face = self._cree_face_mediane_sphere_1 ( coo_x, coo_y, coo_z, rayon )
+    else:
+      face = None
+
+    return erreur, face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_sphere_0 ( self, caract_face_1, caract_face_2 ):
+    """Crée la face médiane entre deux autres - cas des sphères
+
+Décodage des caractéristiques
+
+Entrées :
+  :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
+
+Sorties :
+  :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
+  :rayon: rayon moyen entre les deux faces
+  :epaisseur: épaisseur de l'interface entre les deux faces
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_sphere_0"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Coordonnées du centre de la sphère
+    coo_x = caract_face_1[2][1]
+    coo_y = caract_face_1[2][2]
+    coo_z = caract_face_1[2][3]
+#   Rayons
+    rayon = (caract_face_2[2][4]+caract_face_1[2][4])/2.
+#   Epaisseur
+    epaisseur = np.abs(caract_face_2[2][4]-caract_face_1[2][4])
+
+    return coo_x, coo_y, coo_z, rayon, epaisseur
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_sphere_1 ( self, coo_x, coo_y, coo_z, rayon ):
+    """Crée la face médiane entre deux autres - cas des sphères
+
+Création des objets temporaires et de la face externe de la sphère support
+
+Entrées :
+  :coo_x, coo_y, coo_z: coordonnées du centre de la sphère
+  :rayon: rayon moyen entre les deux faces
+
+Sorties :
+  :face: la face externe de la sphère support
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_sphere_1"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les caractéristiques de la sphère à créer
+    if self._verbose_max:
+      texte = blabla
+      texte += "Centre : ({}, {}, {})\n".format(coo_x, coo_y, coo_z)
+      texte += "Rayon : {}".format(rayon)
+      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 d'un plan passant par ce centre et cet axe
+    plan = model.addPlane(self.part_doc, model.selection("EDGE", "PartSet/OX"), model.selection("VERTEX", nom_centre), False)
+    nom_plan = "{}_plan".format(self.nom_solide)
+    plan.result().setName(nom_plan)
+
+#   Création d'un sketch
+    nom_par_1 = "{}_R".format(self.nom_solide)
+    model.addParameter(self.part_doc, "{}".format(nom_par_1), "{}".format(rayon))
+
+    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()
+
+    ### Create SketchArc
+    SketchArc_1 = sketch.addArc(coo_x, coo_y, coo_x-rayon, coo_y, coo_x+rayon, coo_y, False)
+    sketch.setRadius(SketchArc_1.results()[1], nom_par_1)
+    sketch.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+
+    ### Create SketchLine
+    SketchLine_1 = sketch.addLine(coo_x-rayon, coo_y, coo_x+rayon, coo_y)
+    nom_ligne = "{}_ligne".format(self.nom_solide)
+    SketchLine_1.setName(nom_ligne)
+    SketchLine_1.result().setName(nom_ligne)
+    SketchLine_1.setAuxiliary(True)
+    sketch.setHorizontal(SketchLine_1.result())
+    sketch.setCoincident(SketchArc_1.startPoint(), SketchLine_1.startPoint())
+    sketch.setCoincident(SketchArc_1.endPoint(), SketchLine_1.endPoint())
+    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result())
+
+    model.do()
+    nom_sketch = "{}_esquisse".format(self.nom_solide)
+    sketch.setName(nom_sketch)
+    sketch.result().setName(nom_sketch)
+
+#   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)
+
+#   Intersection de la face sphérique avec le solide initial
+    face = self._creation_face_inter ( nom_sphere )
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_tore ( self, caract_face_1, caract_face_2 ):
+    """Crée la face médiane entre deux autres - cas des tores
+
+Entrées :
+  :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_tore"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Caractéristiques des tores
+    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 )
+
+#   Contrôle de la validité de l'épaisseur (bidon)
+    erreur = self._verif_epaisseur ( EP_MIN*10. )
+
+#   Création de la face
+    if not erreur:
+      face = self._cree_face_mediane_tore_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 )
+    else:
+      face = None
+
+    return erreur, face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_tore_0 ( self, caract_face_1, caract_face_2 ):
+    """Crée la face médiane entre deux autres - cas des tores
+
+Décodage des caractéristiques
+
+Entrées :
+  :caract_face_1, caract_face_2: les caractéristiques des 2 faces les plus grandes
+
+Sorties :
+  :coo_x, coo_y, coo_z: coordonnées du centre du tore
+  :axe_x, axe_y, axe_z: coordonnées de l'axe
+  :rayon_1 : rayon principal
+  :rayon_2 : rayon secondaire
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_tore_0"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Coordonnées du centre du tore
+    coo_x = caract_face_1[2][1]
+    coo_y = caract_face_1[2][2]
+    coo_z = caract_face_1[2][3]
+#   Coordonnées de l'axe
+    axe_x = caract_face_1[2][4]
+    axe_y = caract_face_1[2][5]
+    axe_z = caract_face_1[2][6]
+#   Rayons
+    rayon_1 = caract_face_2[2][7]
+    rayon_2 = (caract_face_2[2][8]+caract_face_1[2][8])/2.
+
+    return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_tore_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2 ):
+    """Crée la face médiane entre deux autres - cas des tores
+
+Création des objets temporaires et de la face externe du tore support
+
+Entrées :
+  :coo_x, coo_y, coo_z: coordonnées du centre du tore
+  :axe_x, axe_y, axe_z: coordonnées de l'axe
+  :rayon_1 : rayon principal
+  :rayon_2 : rayon secondaire
+
+Sorties :
+  :face: la face externe du tore support
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_tore_1"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    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 principal : {}\n".format(rayon_1)
+      texte += "Rayon secondaire : {}".format(rayon_2)
+      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)
+
+#   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)
+    nom_plan = "{}_plan".format(self.nom_solide)
+    plan.result().setName(nom_plan)
+
+#   Création d'un sketch
+    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)
+    model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
+
+    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()
+
+    SketchProjection_2 = sketch.addProjection(model.selection("EDGE", nom_axe), False)
+    SketchLine_1 = SketchProjection_2.createdFeature()
+
+    SketchPoint_2 = sketch.addPoint(rayon_1, 0.)
+    sketch.setDistance(SketchPoint_1.result(), SketchPoint_2.coordinates(), nom_par_1, True)
+
+    SketchLine_2 = sketch.addLine(0., 0., rayon_1, 0.)
+    SketchLine_2.setAuxiliary(True)
+    sketch.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.startPoint())
+    sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_2.endPoint())
+    sketch.setPerpendicular(SketchLine_1.result(), SketchLine_2.result())
+
+    SketchCircle_1 = sketch.addCircle(0., 0., rayon_2)
+    sketch.setCoincident(SketchPoint_2.result(), SketchCircle_1.center())
+    sketch.setRadius(SketchCircle_1.results()[1], nom_par_2)
+
+    model.do()
+    nom_sketch = "{}_esquisse".format(self.nom_solide)
+    sketch.setName(nom_sketch)
+    sketch.result().setName(nom_sketch)
+
+#   Création du tore complet
+    nom_tore = "{}_tore".format(self.nom_solide)
+    self._cree_revolution ( nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_tore )
+
+#   Intersection de la face torique avec le solide initial
+    face = self._creation_face_inter ( nom_tore )
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cone ( self, geompy, caract_face_1, caract_face_2 ):
+    """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
+
+Sorties :
+  :face: la face médiane
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_cone"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   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 )
+
+#   Contrôle de la validité de l'épaisseur (bidon)
+    erreur = self._verif_epaisseur ( EP_MIN*10. )
+
+#   Création de la face
+    if not erreur:
+      face = self._cree_face_mediane_cone_1 ( coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur )
+    else:
+      face = None
+
+    return erreur, face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cone_0 ( self, geompy, caract_face_1, caract_face_2 ):
+    """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
+
+Sorties :
+  :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_1, rayon_2: rayons moyens du côté de la base et à l'opposé
+  :hauteur: hauteur du cone
+    """
+
+    nom_fonction = __name__ + "/_cree_face_mediane_cone_0"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    if self._verbose_max:
+      texte = blabla
+      texte += "face_1 : {}\n".format(caract_face_1)
+      texte += "face_2 : {}".format(caract_face_2)
+      print (texte)
+
+#   Coordonnées du centre de la base
+    coo_x = caract_face_1[2][1]
+    coo_y = caract_face_1[2][2]
+    coo_z = caract_face_1[2][3]
+#   Coordonnées de l'axe
+    axe_x = caract_face_1[2][4]
+    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
+#   Hauteur
+    hauteur = caract_face_1[2][9]
+
+    return coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_face_mediane_cone_1 ( self, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, rayon_1, rayon_2, hauteur ):
+    """Crée la face médiane entre deux autres - cas des cones
+
+Création des objets temporaires et de la face externe du cone 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_1, rayon_2: rayons moyens du côté de la base et à l'opposé
+  :hauteur: hauteur du cone
+
+Sorties :
+  :face: la face externe du cone support
+    """
+    nom_fonction = __name__ + "/_cree_face_mediane_cone_1"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+#   Les deux faces
+    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 += "Rayons : {}, {}\n".format(rayon_1, rayon_2)
+      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)
+
+#   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)
+    nom_plan = "{}_plan".format(self.nom_solide)
+    plan.result().setName(nom_plan)
+
+#   Création d'un sketch
+    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)
+    model.addParameter(self.part_doc, "{}".format(nom_par_2), "{}".format(rayon_2))
+    nom_par_3 = "{}_H".format(self.nom_solide)
+    model.addParameter(self.part_doc, "{}".format(nom_par_3), "{}".format(hauteur))
+
+    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()
+
+    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)
+
+    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))
+
+    SketchPoint_2 = sketch.addPoint(coo_x, coo_y)
+    sketch.setCoincident(SketchPoint_2.coordinates(), SketchLine_3.result())
+    sketch.setMiddlePoint(SketchPoint_2.coordinates(), SketchLine_3.result())
+
+    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())
+
+    model.do()
+    nom_sketch = "{}_esquisse".format(self.nom_solide)
+    sketch.setName(nom_sketch)
+    sketch.result().setName(nom_sketch)
+
+#   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 )
+
+#   Intersection de la face conique avec le solide initial
+    face = self._creation_face_inter ( nom_cone )
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _calcul_boite_englobante ( self, objet ):
+    """Crée la hauteur englobant à coup sûr l'objet
+
+Entrées :
+  :objet: l'objet à traiter
+
+Sorties :
+  :l_diag: longueur de la diagonale de la boîte englobante
+    """
+
+    nom_fonction = __name__ + "/_calcul_boite_englobante"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      texte = blabla[:-1]
+      print (texte)
+
+#   Hauteur : la diagonale de la boîte englobante permet d'être certain de tout prendre
+    if self._verbose_max:
+      texte = "Création de la boite englobante pour l'objet '{}' ".format(objet.name())
+      texte += "de type '{}'".format(objet.shapeType())
+      print (texte)
+    bbox = model.getBoundingBox(self.part_doc, model.selection("{}".format(objet.shapeType()), "{}".format(objet.name())))
+
+    bbox_nom = bbox.name()
+    if self._verbose_max:
+      print ("Boîte englobante : '{}' '{}'".format(bbox.name(), bbox.result().name()))
+
+    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 = "\tXmin = {}, 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(texte)
+
+    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 ("Longueur de la diagonale : {}".format(l_diag))
+
+    return l_diag
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _cree_revolution ( self, nom_sketch, nom_centre, coo_x, coo_y, coo_z, axe_x, axe_y, axe_z, nom_objet ):
+    """Crée un volume de révolution
+
+Entrées :
+  :nom_sketch: nom du sketch à révolutionner
+  :nom_centre: nom du point associé au centre du volume de révolution
+  :coo_x, coo_y, coo_z: coordonnées du centre du tore
+  :axe_x, axe_y, axe_z: coordonnées de l'axe
+  :rayon_1 : rayon principal
+  :rayon_2 : rayon secondaire
+  :nom_objet: nom de l'objet 2D créé
+    """
+
+    nom_fonction = __name__ + "/_cree_revolution"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    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)
+      print (texte)
+
+#   Création d'un point décalé par rapport au point central
+    point = model.addPoint(self.part_doc, coo_x+axe_x, coo_y+axe_y, coo_z+axe_z)
+    nom_point = "{}_point".format(self.nom_solide)
+    point.result().setName(nom_point)
+
+#   Création de l'axe de la rotation
+    axe_r = model.addAxis(self.part_doc, model.selection("VERTEX", nom_centre), model.selection("VERTEX", nom_point))
+    nom_axe_r = "{}_axe_r".format(self.nom_solide)
+    axe_r.result().setName(nom_axe_r)
+
+#   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
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _creation_face_inter ( self, nom_objet ):
+    """Crée la face par intersection entre l'objet initial et une face complète
+
+. Repère la face principale de l'objet support
+. Réalise l'intersection avec le solide initial
+
+Entrées :
+  :nom_objet: nom de l'objet 2D créé
+
+Sorties :
+  :face: la face externe de l'objet support intersecté avec le solide initial
+    """
+
+    nom_fonction = __name__ + "/_creation_face_inter"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+
+    face = model.addCommon(self.part_doc, [model.selection("SOLID", self.nom_solide_aux), model.selection("FACE", nom_objet)], keepSubResults = True)
+
+    return face
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def face_mediane_solide (self, solide, geompy, objet_geom):
+    """Calcul de la face médiane pour un solide
+
+Entrées :
+  :solide: solide SHAPER à traiter
+  :geompy: environnement de GEOM
+  :objet_geom: l'objet solide au format GEOM à traiter
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/face_mediane_solide"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+    if self._verbose:
+      print ("Traitement du solide '{}'".format(solide.name()))
+
+# 1. Préalables
+
+    erreur = 0
+    message = ""
+
+    while not erreur :
+
+# 2. Explosion du solide en faces
+
+      erreur, message, l_faces = self._faces_du_solide ( geompy, objet_geom )
+      if erreur:
+        break
+
+# 3. Calcul des caractéristiques géométriques des faces
+
+      tb_caract = self._calcul_caract_faces ( geompy, l_faces )
+
+# 4. 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 )
+      if erreur:
+        break
+
+# 5. Création de la face médiane
+
+      erreur, face = self._cree_face_mediane ( solide, geompy, caract_face_1, caract_face_2 )
+      if erreur:
+        break
+
+# 6. Exportation step
+
+      if self._export_step:
+        fichier = os.path.join(self.rep_step, "{}.stp".format(face.result().name()))
+        export = model.exportToFile(self.part_doc, fichier, [model.selection(face.result().shapeType(), face.result().name())])
+        export.execute(True)
+        model.do()
+
+# 7. La fin
+
+      break
+
+    if ( erreur and self._verbose_max ):
+      print (blabla, message)
+
+    return erreur, message
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _traitement_objet (self, solide=None, objet_geom=None):
+    """Traitement d'un objet
+
+Entrées :
+  :solide: solide SHAPER à traiter
+  :objet_geom: l'objet GEOM équivalent
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/_traitement_objet"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+
+# 1. Préalables
+
+    erreur = 0
+    message = ""
+
+    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
+#    Attention à ne pas recréer le répertoire à chaque fois
+      if self._export_step:
+
+        if self._verbose_max:
+          print ("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()))
+          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 ("Les fichiers CAO des surfaces seront dans le répertoire {}".format(self.rep_step))
+
+# 5. Calcul réel de la face médiane
+
+      if solide is None:
+        self.nom_solide = objet_geom.GetName()
+
+      erreur, message = self.face_mediane_solide (solide, geompy, objet_geom)
+      if erreur:
+        break
+
+      break
+
+    return erreur, message
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def surf_fic_cao (self, ficcao, nom_objet=None):
+    """Calcule la surface médiane pour un objet dans un fichier passé en argument
+
+Entrées :
+  :ficcao: fichier de l'objet à traiter
+  :nom_objet: un nom à donner à l'objet à traiter
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/surf_fic_cao"
+    blabla = "\nDans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+
+    erreur = 0
+    message = ""
+
+    model.begin()
+
+    while not erreur :
+
+# 1. Définition de la pièce
+
+      self.part_doc = model.activeDocument()
+
+# 2. Import de la CAO
+
+      self.ficcao = ficcao
+      print ("Traitement du fichier {}".format(ficcao))
+
+      erreur, message, objet = import_cao (self.part_doc, ficcao, nom_objet, self._verbose_max)
+      if erreur:
+        break
+
+# 3. Calcul des surfaces
+
+      erreur, message = self.surf_objet_shaper ( objet )
+      if erreur:
+        break
+      #print (message)
+
+      break
+
+    model.end()
+
+    if ( erreur and self._verbose_max ):
+      print (blabla, message)
+
+    return erreur, message
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def surf_objet_shaper (self, objet):
+    """Calcule les surfaces médianes pour un objet SHAPER passé en argument
+
+Entrées :
+  :objet: objet à traiter
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/surf_objet_shaper"
+    blabla = "Dans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+
+# 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._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 )
+
+# 3. Gestion des faces créées
+
+    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)
+
+    return erreur, message
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _surf_objet_shaper_0 (self, objet, n_recur=0):
+    """Calcule les surfaces médianes pour un objet SHAPER passé en argument
+
+Entrées :
+  :objet: objet à traiter
+  :n_recur: niveau de récursivité
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/_surf_objet_shaper_0"
+    blabla = "Dans {} :\n".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)
+
+    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
+
+      if ( n_recur == 0 ):
+        self.part_doc = model.activeDocument()
+        objet_0 = objet.result()
+        self.objet_principal = objet_0
+      else:
+        objet_0 = objet
+
+# 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:
+        texte = "Examen de l'objet '{}' ".format(objet_0.name())
+        texte += "de type '{}'".format(objet_0.shapeType())
+        texte += "\nobjet.result().numberOfSubs() : {}".format(nb_sub_results)
+        print (texte)
+
+      for n_sobj in range(nb_sub_results):
+
+# 2.1. Exploration récursive de l'arborescence
+
+        erreur, message = self._surf_objet_shaper_0 ( objet_0.subResult(n_sobj), n_recur+1 )
+        if erreur:
+          break
+
+# 2.2. Cet objet n'a pas de sous-objets. Si c'est un solide, on le traite
+
+      if ( objet_0.shapeType() == "SOLID" ):
+        erreur, message = self.surf_solide_shaper ( objet_0 )
+        if erreur:
+          break
+
+      if erreur:
+        break
+
+# 3. Futur message pour le résultat
+
+      if self._export_step:
+        message = "Les fichiers STEP des surfaces sont dans le répertoire {}".format(self.rep_step)
+
+      break
+
+    return erreur, message
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def _surf_objet_shaper_1 (self):
+    """Gestion des surfaces médianes créées
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/_surf_objet_shaper_1"
+    blabla = "Dans {} :\n".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+
+# 1. Informations sur les faces à problème
+
+    if self.faces_pb_nb:
+      if ( self.faces_pb_nb == 1 ):
+        texte = "1 face pose"
+      else:
+        texte = "{} faces posent".format(self.faces_pb_nb)
+      print ("\n{} problème.\n{}".format(texte,self.faces_pb_msg))
+
+# 2. Si plus d'une face a été créée
+    if ( len(self.l_faces_m) > 1 ):
+
+# 2.1. Partition du paquet de faces
+
+      if self._verbose_max:
+        print ("Partitionnnement des faces créées.")
+
+      l_objets = list()
+      for (face,_) in self.l_faces_m:
+        l_objets.append(model.selection("COMPOUND", "all-in-{}".format(face.name())))
+
+      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()))
+      self._couleur_objet (Partition_1, coul_r=0, coul_g=170, coul_b=0)
+
+# 2.2. Récupération des faces individuelles
+
+      if self._verbose_max:
+        print ("Récupération des faces individuelles.")
+
+      l_objets = list()
+      for iaux, (face,_) in enumerate(self.l_faces_m):
+        l_objets.append(face.result())
+
+      Recover_1 = model.addRecover(self.part_doc, Partition_1, l_objets)
+      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)
+
+# 2.3. Mise en dossier
+
+      if self._verbose_max:
+        print ("Mise en dossier.")
+
+      for (face,fonction_0) in self.l_faces_m:
+        dossier = model.addFolder(self.part_doc, fonction_0, face)
+        dossier.setName(face.name()[:-2])
+
+    return
+
+#===========================  Fin de la méthode ==================================
+
+#=========================== Début de la méthode =================================
+
+  def surf_solide_shaper (self, solide):
+    """Calcule les surfaces médianes pour un solide SHAPER solide passé en argument
+
+Entrées :
+  :solide: solide SHAPER à traiter
+
+Sorties :
+  :erreur: code d'erreur
+  :message: message d'erreur
+    """
+
+    nom_fonction = __name__ + "/surf_solide_shaper"
+    blabla = "Dans {} :".format(nom_fonction)
+
+    if self._verbose_max:
+      print (blabla)
+
+    erreur = 0
+    message = ""
+
+    while not erreur :
+
+      self.nom_solide = solide.name()
+      if self._verbose_max:
+        print ("solide '{}'".format(self.nom_solide))
+
+# 1. Isolement du solide
+      solide_aux, recover = self._isole_solide ( solide )
+
+# 2. Exportation dans un fichier step pour traitement dans GEOM
+
+      fichier = tempfile.mkstemp(suffix=".stp")[1]
+      if self._verbose_max:
+        print ("fichier = {}".format(fichier))
+        print ("solide  = {}".format(solide_aux.name()))
+        print ("de type = {}".format(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 )
+
+      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
+      if ( erreur in (-2,-1,2) ):
+        erreur = 0
+        message = ""
+
+      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 ( )
+
+    if ( erreur and self._verbose_max ):
+      print (blabla, message)
+
+    return erreur, message
+
+#===========================  Fin de la méthode ==================================
+
+#==========================  Fin de la classe ====================================
+
+#==================================================================================
+# Lancement
+#==================================================================================
+
+if __name__ == "__main__" :
+
+# 1. Options
+
+  L_OPTIONS = list()
+  L_OPTIONS.append("-vmax")
+  #L_OPTIONS.append("-export_step")
+  FIC_CAO = os.path.join(os.getenv("SHAPER_ROOT_DIR"), "bin", "salome", "macros", "midSurface", "midSurface.stp")
+  #FIC_CAO = os.path.join(os.getenv("HOME"), "salome-dev", "DEV_package", "modules", "src", "SHAPER", "src", "PythonAddons", "macros", "midSurface", "Objet_1.stp")
+
+# 2. Lancement de la classe
+
+  #print ("L_OPTIONS :", L_OPTIONS)
+
+  SURFACE_MEDIANE = SurfaceMediane(L_OPTIONS)
+  if SURFACE_MEDIANE.affiche_aide_globale:
+    sys.stdout.write(SURFACE_MEDIANE.__doc__+"\n")
+  else:
+    model.begin()
+    PARTSET = model.moduleDocument()
+    _ = model.addPart(PARTSET)
+    ERREUR, MESSAGE_ERREUR = SURFACE_MEDIANE.surf_fic_cao(FIC_CAO)
+    if ERREUR:
+      MESSAGE_ERREUR += "\n Code d'erreur : %d\n" % ERREUR
+      sys.stderr.write(MESSAGE_ERREUR)
+
+  del SURFACE_MEDIANE
+
+  #sys.exit(0)
diff --git a/src/PythonAddons/macros/midSurface/widget.xml b/src/PythonAddons/macros/midSurface/widget.xml
new file mode 100644 (file)
index 0000000..c123c41
--- /dev/null
@@ -0,0 +1,14 @@
+<source>
+  <workbench id="Macros" document="Part">
+    <group id="Samples">
+      <feature id="midSurface"
+        title="Fibre neutre"
+        tooltip="Create"
+        icon="icons/Addons/midSurface.png"
+        helpfile="midSurfaceFeature.html">
+        <file_selector id="file_path" title="Import file" tooltip="Select file" path="">
+        </file_selector>
+      </feature>
+    </group>
+  </workbench>
+</source>