Salome HOME
Adjust test cases according to redesigned Arc and Circle features
[modules/shaper.git] / src / SketchPlugin / Test / TestCreateCircleByThreePoints.py
1 """
2     TestCreateCircleByThreePoints.py
3
4     Test creation methods of a circle built by three points
5 """
6
7 #=========================================================================
8 # Initialization of the test
9 #=========================================================================
10 from GeomDataAPI import *
11 from GeomAPI import *
12 from ModelAPI import *
13 from SketchAPI import SketchAPI_Sketch
14 from salome.shaper import model
15 import math
16
17 __updated__ = "2017-03-22"
18
19
20 #=========================================================================
21 # Auxiliary functions
22 #=========================================================================
23 TOLERANCE = 1.e-7
24
25 def verifyLastCircle(theSketch, theX, theY, theR):
26     """
27     subroutine to verify position of last circle in the sketch
28     """
29     aLastCircle = model.lastSubFeature(theSketch, "SketchCircle")
30     aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
31     verifyPointCoordinates(aCenter, theX, theY)
32     aRadius = aLastCircle.real("circle_radius")
33     assert aRadius.value() == theR, "Wrong radius {0}, expected {1}".format(aRadius.value(), theR)
34
35 def verifyPointCoordinates(thePoint, theX, theY):
36     assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.attributeType(), thePoint.x(), thePoint.y(), theX, theY)
37
38 def verifyPointOnCircle(thePoint, theCircle):
39     aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
40     aDistCP = model.distancePointPoint(aCircleCenter, thePoint)
41     aCircleRadius = theCircle.real("circle_radius").value()
42     assert math.fabs(aDistCP - aCircleRadius) < TOLERANCE, "Point is not on circle, distance: {0}, radius of circle: {1}".format(aDistCP, aCircleRadius)
43
44 def verifyTangentCircles(theCircle1, theCircle2):
45     aCenter1 = geomDataAPI_Point2D(theCircle1.attribute("circle_center"))
46     aCenter2 = geomDataAPI_Point2D(theCircle2.attribute("circle_center"))
47     aDistCC = model.distancePointPoint(aCenter1, aCenter2)
48     aRadius1 = theCircle1.real("circle_radius").value()
49     aRadius2 = theCircle2.real("circle_radius").value()
50     verifyTangentCircular(aDistCC, aRadius1, aRadius2)
51
52 def verifyTangentCircleArc(theCircle, theArc):
53     aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
54     anArcCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
55     anArcStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
56     aDistCC = model.distancePointPoint(aCircleCenter, anArcCenter)
57     aCircleRadius = theCircle.real("circle_radius").value()
58     anArcRadius = model.distancePointPoint(anArcCenter, anArcStart)
59     verifyTangentCircular(aDistCC, aCircleRadius, anArcRadius)
60
61 def verifyTangentCircular(theDistBetweenCenters, theRadius1, theRadius2):
62     aRSum = theRadius1 + theRadius2
63     aRDiff = math.fabs(theRadius1 - theRadius2)
64     assert math.fabs(aRSum - theDistBetweenCenters) < TOLERANCE or math.fabs(aRDiff - theDistBetweenCenters) < TOLERANCE, "Two circulars are not tangent"
65
66 def verifyTangentCircleLine(theCircle, theLine):
67     aCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
68     aRadius = theCircle.real("circle_radius").value()
69     aDistCL = distancePointLine(aCenter, theLine)
70     assert math.fabs(aDistCL - aRadius) < TOLERANCE, "Circle and line are not tangent"
71
72 def distancePointLine(thePoint, theLine):
73     aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint")).pnt().xy()
74     aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint")).pnt().xy()
75     aLineDir = aLineEnd.decreased(aLineStart)
76     aLineLen = aLineEnd.distance(aLineStart)
77     aPntDir = thePoint.pnt().xy().decreased(aLineStart)
78     return math.fabs(aPntDir.cross(aLineDir) / aLineLen)
79
80
81 #=========================================================================
82 # Start of test
83 #=========================================================================
84
85 aSession = ModelAPI_Session.get()
86 aDocument = aSession.moduleDocument()
87 #=========================================================================
88 # Creation of a sketch
89 #=========================================================================
90 aSession.startOperation()
91 aSketchCommonFeature = aDocument.addFeature("Sketch")
92 aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
93 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
94 origin.setValue(0, 0, 0)
95 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
96 dirx.setValue(1, 0, 0)
97 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
98 norm.setValue(0, 0, 1)
99 aSession.finishOperation()
100 aSketch = SketchAPI_Sketch(aSketchFeature)
101
102 #=========================================================================
103 # Test 1. Create a circle by three points
104 #=========================================================================
105 expectedCenter = [0., 0.]
106 expectedRadius = 10.
107 aSession.startOperation()
108 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
109 assert (aCircle.getKind() == "SketchMacroCircle")
110 aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
111 aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
112 aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
113 assert (not aCirclePnt1.isInitialized())
114 assert (not aCirclePnt2.isInitialized())
115 assert (not aCirclePnt3.isInitialized())
116 aCircleType = aCircle.string("circle_type")
117 assert (not aCircleType.isInitialized())
118 aCircleType.setValue("circle_type_by_three_points")
119 aCirclePnt1.setValue(expectedCenter[0] - expectedRadius, expectedCenter[1])
120 aCirclePnt2.setValue(expectedCenter[0] + expectedRadius, expectedCenter[1])
121 aCirclePnt3.setValue(expectedCenter[0], expectedCenter[1] + expectedRadius)
122 aSession.finishOperation()
123 assert (aSketchFeature.numberOfSubs() == 1)
124 verifyLastCircle(aSketchFeature, expectedCenter[0], expectedCenter[1], expectedRadius)
125
126 #=========================================================================
127 # Test 2. Create a circle by three points coincident to other points
128 #=========================================================================
129 # get previous circle
130 aPrevCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
131 aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
132 aPrevCenterXY = [aPrevCenter.x(), aPrevCenter.y()]
133 aPrevCircleRadius = aPrevCircle.real("circle_radius").value()
134 # create additional point and line
135 aPointCoodinates = [5., 20.]
136 aLineStart = [10., 0.]
137 aLineEnd = [10., 50.]
138 aSession.startOperation()
139 aPoint = aSketchFeature.addFeature("SketchPoint")
140 aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordindates"))
141 aPointCoord.setValue(aPointCoodinates[0], aPointCoodinates[1])
142 aLine = aSketchFeature.addFeature("SketchLine")
143 aStartPnt = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
144 aStartPnt.setValue(aLineStart[0], aLineStart[1])
145 aEndPnt = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
146 aEndPnt.setValue(aLineEnd[0], aLineEnd[1])
147 aSession.finishOperation()
148 # create new circle
149 aSession.startOperation()
150 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
151 aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
152 aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
153 aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
154 aCirclePnt1Ref = aCircle.refattr("first_point_ref")
155 aCirclePnt2Ref = aCircle.refattr("second_point_ref")
156 aCirclePnt3Ref = aCircle.refattr("third_point_ref")
157 aCircleType = aCircle.string("circle_type")
158 # initialize attributes
159 aCircleType.setValue("circle_type_by_three_points")
160 aCirclePnt1Ref.setAttr(aPrevCenter)
161 aCirclePnt1.setValue(aPrevCenter.pnt())
162 aCirclePnt2Ref.setObject(aPoint.lastResult())
163 aCirclePnt2.setValue(aPointCoord.pnt())
164 aCirclePnt3Ref.setAttr(aStartPnt)
165 aCirclePnt3.setValue(aLineStart[0], aLineStart[1])
166 aSession.finishOperation()
167 assert (aSketchFeature.numberOfSubs() == 7)
168 # check the points do not change their positions
169 verifyPointCoordinates(aPrevCenter, aPrevCenterXY[0], aPrevCenterXY[1])
170 verifyPointCoordinates(aPointCoord, aPointCoodinates[0], aPointCoodinates[1])
171 verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
172 # check newly created circle passes through the points
173 aCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
174 verifyPointOnCircle(aPrevCenter, aCircle)
175 verifyPointOnCircle(aPointCoord, aCircle)
176 verifyPointOnCircle(aStartPnt, aCircle)
177 model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3)
178 model.testNbSubFeatures(aSketch, "SketchConstraintTangent", 0)
179
180 #=========================================================================
181 # Test 3. Create a circle by three points and tangent to line, circle and arc
182 #=========================================================================
183 # create additional arc
184 anArcRadius = 5.
185 anArcCenter = [-10., 10.]
186 anArcStart = [anArcCenter[0], anArcCenter[1] - anArcRadius]
187 anArcEnd = [anArcCenter[0], anArcCenter[1] + anArcRadius]
188 aSession.startOperation()
189 anArc = aSketchFeature.addFeature("SketchArc")
190 anArcCenterPnt = geomDataAPI_Point2D(anArc.attribute("center_point"))
191 anArcCenterPnt.setValue(anArcCenter[0], anArcCenter[1])
192 anArcStartPnt = geomDataAPI_Point2D(anArc.attribute("start_point"))
193 anArcStartPnt.setValue(anArcStart[0], anArcStart[1])
194 anArcEndPnt = geomDataAPI_Point2D(anArc.attribute("end_point"))
195 anArcEndPnt.setValue(anArcEnd[0], anArcEnd[1])
196 aSession.finishOperation()
197 # create new circle
198 aSession.startOperation()
199 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
200 aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
201 aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
202 aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
203 aCirclePnt1Ref = aCircle.refattr("first_point_ref")
204 aCirclePnt2Ref = aCircle.refattr("second_point_ref")
205 aCirclePnt3Ref = aCircle.refattr("third_point_ref")
206 aCircleType = aCircle.string("circle_type")
207 # initialize attributes
208 aCircleType.setValue("circle_type_by_three_points")
209 aCirclePnt1Ref.setObject(aPrevCircle.lastResult())
210 aCirclePnt1.setValue(aPrevCenter.x(), aPrevCenter.y() + aPrevCircleRadius)
211 aCirclePnt2Ref.setObject(aLine.lastResult())
212 aCirclePnt2.setValue(aLineEnd[0], aLineEnd[1])
213 aCirclePnt3Ref.setObject(anArc.lastResult())
214 aCirclePnt3.setValue(anArcCenter[0] + anArcRadius, anArcCenter[1])
215 aSession.finishOperation()
216 assert (aSketchFeature.numberOfSubs() == 12)
217 # check the tangent entities do not change their positions
218 verifyPointCoordinates(aPrevCenter, aPrevCenterXY[0], aPrevCenterXY[1])
219 assert (aPrevCircle.real("circle_radius").value() == aPrevCircleRadius)
220 verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
221 verifyPointCoordinates(aEndPnt, aLineEnd[0], aLineEnd[1])
222 verifyPointCoordinates(anArcCenterPnt, anArcCenter[0], anArcCenter[1])
223 verifyPointCoordinates(anArcStartPnt, anArcStart[0], anArcStart[1])
224 verifyPointCoordinates(anArcEndPnt, anArcEnd[0], anArcEnd[1])
225 # check newly created circle passes through the points
226 aCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
227 verifyTangentCircles(aCircle, aPrevCircle)
228 verifyTangentCircleArc(aCircle, anArc)
229 verifyTangentCircleLine(aCircle, aLine)
230 model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3)
231 model.testNbSubFeatures(aSketch, "SketchConstraintTangent", 3)
232
233 #=========================================================================
234 # Test 4. Create a circle by three points:
235 #         a. first two points are coincident to extremities of the line
236 #         b. check that this line is not selectable by third point
237 #=========================================================================
238 aSession.startOperation()
239 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
240 aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
241 aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
242 aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
243 aCirclePnt1Ref = aCircle.refattr("first_point_ref")
244 aCirclePnt2Ref = aCircle.refattr("second_point_ref")
245 aCirclePnt3Ref = aCircle.refattr("third_point_ref")
246 aCircleType = aCircle.string("circle_type")
247 # initialize attributes
248 aCircleType.setValue("circle_type_by_three_points")
249 aCirclePnt1Ref.setAttr(aStartPnt)
250 aCirclePnt1.setValue(aStartPnt.pnt())
251 aCirclePnt2Ref.setAttr(aEndPnt)
252 aCirclePnt2.setValue(aEndPnt.pnt())
253 aCirclePnt3Ref.setObject(aLine.lastResult())
254 aCirclePnt3.setValue(aLineEnd[0], aLineEnd[1])
255 aSession.finishOperation()
256 aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
257 assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
258 aDocument.removeFeature(aCircle)
259 assert (aSketchFeature.numberOfSubs() == 12)
260
261 #=========================================================================
262 # Test 5. Create a circle by three points:
263 #         a. first two points are placed on both sides from line
264 #         b. check that this line is not selectable by third point
265 #=========================================================================
266 aDistanceFromLine = 20.
267 aSession.startOperation()
268 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
269 aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
270 aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
271 aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
272 aCirclePnt1Ref = aCircle.refattr("first_point_ref")
273 aCirclePnt2Ref = aCircle.refattr("second_point_ref")
274 aCirclePnt3Ref = aCircle.refattr("third_point_ref")
275 aCircleType = aCircle.string("circle_type")
276 # initialize attributes
277 aCircleType.setValue("circle_type_by_three_points")
278 aCirclePnt1.setValue(aLineStart[0] + aDistanceFromLine, aLineStart[1])
279 aCirclePnt2.setValue(aLineStart[0] - aDistanceFromLine, aLineStart[1])
280 aCirclePnt3Ref.setObject(aLine.lastResult())
281 aCirclePnt3.setValue(aLineEnd[0], aLineEnd[1])
282 aSession.finishOperation()
283 aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
284 assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
285 aDocument.removeFeature(aCircle)
286 assert (aSketchFeature.numberOfSubs() == 12)
287
288 #=========================================================================
289 # End of test
290 #=========================================================================
291
292 from salome.shaper import model
293 assert(model.checkPythonDump())