+## Copyright (C) 2018-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+import math
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 0, 30, -51.96152422706629)
+SketchLine_2 = Sketch_1.addLine(30, -51.96152422706629, 90, -51.96152422706629)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(90, -51.96152422706629, 120, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(120, 0, 90, 51.96152422706636)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(90, 51.96152422706636, 30, 51.96152422706631)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(30, 51.96152422706631, 0, 0)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_6.endPoint())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_2.result(), SketchLine_1.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_1.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_1.result())
+SketchConstraintEqual_4 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_1.result())
+SketchConstraintEqual_5 = Sketch_1.setEqual(SketchLine_6.result(), SketchLine_1.result())
+SketchConstraintAngle_1 = Sketch_1.setAngleBackward(SketchLine_1.result(), SketchLine_2.result(), 120)
+SketchConstraintAngle_2 = Sketch_1.setAngle(SketchLine_3.result(), SketchLine_2.result(), 120)
+SketchConstraintAngle_3 = Sketch_1.setAngleBackward(SketchLine_3.result(), SketchLine_4.result(), 120)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_5.result(), 60)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchAPI_Point(SketchPoint_1).coordinates())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f")], model.selection(), 100, 0)
+model.do()
+
+TOLERANCE = 1.e-6
+
+# reference data
+REF_DATA = [("Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_1",
+ 120),
+ ("Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1",
+ 120),
+ ("Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1",
+ 60),
+ ("Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_1",
+ "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1",
+ "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1",
+ 120),
+ ("Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1",
+ 104.9068234),
+ ("Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1",
+ 90),
+ ("Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1",
+ "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1",
+ 52.91916441),
+ ("Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1",
+ "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1",
+ "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1",
+ 0)
+ ]
+
+for ref in REF_DATA:
+ angle = model.measureAngle(Part_1_doc, model.selection("VERTEX", ref[0]), model.selection("VERTEX", ref[1]), model.selection("VERTEX", ref[2]))
+ assert(math.fabs(angle - ref[3]) < TOLERANCE), "Angle {} differs from expected value {}".format(angle, ref[3])
+
+# select incorrect data
+angle = model.measureAngle(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"), model.selection("VERTEX", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1"), model.selection("VERTEX", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1"))
+assert(angle == -1.0)
+
+angle = model.measureAngle(Part_1_doc, model.selection("VERTEX", ""), model.selection("VERTEX", ""), model.selection("VERTEX", ""))
+assert(angle == -1.0)
+
+model.end()