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