Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / SketchPlugin / Test / TestCreateCircleByCenterAndPassed.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     TestCreateCircleByCenterAndPassed.py
23
24     Test creation methods of a circle built by a center and a passed point
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     aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
51     verifyPointCoordinates(aCenter, theX, theY)
52     aRadius = aLastCircle.real("circle_radius")
53     assert aRadius.value() == theR, "Wrong radius {0}, expected {1}".format(aRadius.value(), theR)
54
55 def verifyPointCoordinates(thePoint, theX, theY):
56     assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.id(), thePoint.x(), thePoint.y(), theX, theY)
57
58 def verifyPointOnLine(thePoint, theLine):
59     aDistance = distancePointLine(thePoint, theLine)
60     assert aDistance < TOLERANCE, "Point is not on Line, distance: {0}".format(aDistance)
61
62 def verifyTangentCircles(theCircle1, theCircle2):
63     aCenter1 = geomDataAPI_Point2D(theCircle1.attribute("circle_center"))
64     aCenter2 = geomDataAPI_Point2D(theCircle2.attribute("circle_center"))
65     aDistCC = model.distancePointPoint(aCenter1, aCenter2)
66     aRadius1 = theCircle1.real("circle_radius").value()
67     aRadius2 = theCircle2.real("circle_radius").value()
68     aRSum = aRadius1 + aRadius2
69     aRDiff = math.fabs(aRadius1 - aRadius2)
70     assert math.fabs(aRSum - aDistCC) < TOLERANCE or math.fabs(aRDiff - aDistCC) < TOLERANCE, "Circles do 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 center and radius
104 #=========================================================================
105 aSession.startOperation()
106 aCircle = aSketchFeature.addFeature("SketchCircle")
107 assert (aCircle.getKind() == "SketchCircle")
108 aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
109 assert (not aCircleCenter.isInitialized())
110 aCircleRadius = aCircle.real("circle_radius")
111 assert (type(aCircleRadius) == ModelAPI_AttributeDouble)
112 # ModelAPI_AttributeDouble.typeId() is checked in ModelAPI_TestConstants
113 assert (aCircleRadius.attributeType() == ModelAPI_AttributeDouble.typeId())
114 aCircleCenter.setValue(-25., -25)
115 aCircleRadius.setValue(25.)
116 aSession.finishOperation()
117 verifyLastCircle(aSketchFeature, -25., -25., 25.)
118 #=========================================================================
119 # Edit the Circle
120 # 1. check that changing the center of a circle does not affect radius and vise versa
121 # 2. also check that int is acceptable as well as a real
122 #=========================================================================
123 aSession.startOperation()
124 aCircleCenter.setValue(10, 60)
125 aSession.finishOperation()
126 verifyLastCircle(aSketchFeature, 10., 60., 25.)
127 aSession.startOperation()
128 aCircleRadius.setValue(int(20))
129 aSession.finishOperation()
130 verifyLastCircle(aSketchFeature, 10., 60., 20.)
131
132 #=========================================================================
133 # Test 2. Create a circle as a macro-feature by center and passed point
134 #=========================================================================
135 aSession.startOperation()
136 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
137 assert (aCircle.getKind() == "SketchMacroCircle")
138 aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
139 assert (not aCircleCenter.isInitialized())
140 aCirclePassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
141 assert (not aCirclePassed.isInitialized())
142 aCircleType = aCircle.string("circle_type")
143 assert (not aCircleType.isInitialized())
144 aCircleType.setValue("circle_type_by_center_and_passed_points")
145 aCircleCenter.setValue(-25., -25)
146 aCirclePassed.setValue(0., -25.)
147 aRadius = model.distancePointPoint(aCircleCenter, aCirclePassed)
148 aSession.finishOperation()
149 assert (aSketchFeature.numberOfSubs() == 2)
150 verifyLastCircle(aSketchFeature, -25., -25., aRadius)
151
152 #=========================================================================
153 # Test 3. Create a circle as a macro-feature by center and passed point coincident to other points
154 #=========================================================================
155 # get previous circle
156 aPrevCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
157 aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
158 # create additional point
159 aPointCoordinates = [0., 0.]
160 aSession.startOperation()
161 aPoint = aSketchFeature.addFeature("SketchPoint")
162 aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordinates"))
163 aPointCoord.setValue(aPointCoordinates[0], aPointCoordinates[1])
164 aSession.finishOperation()
165 # create new circle
166 aSession.startOperation()
167 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
168 aCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
169 aCenterRef = aCircle.refattr("center_point_ref")
170 assert (not aCenterRef.isInitialized())
171 aPassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
172 aPassedRef = aCircle.refattr("passed_point_ref")
173 assert (not aPassedRef.isInitialized())
174 aCircleType = aCircle.string("circle_type")
175 assert (not aCircleType.isInitialized())
176 # initialize attributes
177 aCircleType.setValue("circle_type_by_center_and_passed_points")
178 aCenterRef.setObject(aPoint.lastResult())
179 aCenter.setValue(aPointCoord.pnt())
180 aPassedRef.setAttr(aPrevCenter)
181 aPassed.setValue(aPrevCenter.pnt())
182 aRadius = model.distancePointPoint(aPrevCenter, aPointCoord)
183 aSession.finishOperation()
184 assert (aSketchFeature.numberOfSubs() == 6)
185 verifyPointCoordinates(aPointCoord, aPointCoordinates[0], aPointCoordinates[1])
186 verifyLastCircle(aSketchFeature, aPointCoord.x(), aPointCoord.y(), aRadius)
187 model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 2)
188
189 #=========================================================================
190 # Test 4. Create a circle as a macro-feature by center on a line and passed point on another circle
191 #=========================================================================
192 # get previous circle
193 aPrevCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
194 aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
195 aPrevCenterXY = [aPrevCenter.x(), aPrevCenter.y()]
196 aPrevRadius = aPrevCircle.real("circle_radius").value()
197 # create additional line
198 aLineStart = [10., 0.]
199 aLineEnd = [10., 50.]
200 aSession.startOperation()
201 aLine = aSketchFeature.addFeature("SketchLine")
202 aStartPnt = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
203 aStartPnt.setValue(aLineStart[0], aLineStart[1])
204 aEndPnt = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
205 aEndPnt.setValue(aLineEnd[0], aLineEnd[1])
206 aSession.finishOperation()
207 # create new circle
208 aSession.startOperation()
209 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
210 aCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
211 aCenterRef = aCircle.refattr("center_point_ref")
212 aPassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
213 aPassedRef = aCircle.refattr("passed_point_ref")
214 aCircleType = aCircle.string("circle_type")
215 # initialize attributes
216 aCircleType.setValue("circle_type_by_center_and_passed_points")
217 aCenterRef.setObject(aLine.lastResult())
218 anExpectedCenter = [(aLineStart[0] + aLineEnd[0]) * 0.5, (aLineStart[1] + aLineEnd[1]) * 0.5]
219 aCenter.setValue(anExpectedCenter[0], anExpectedCenter[1])
220 aPassedRef.setObject(aPrevCircle.lastResult())
221 aPassed.setValue(aPrevCenter.x() + aPrevRadius, aPrevCenter.y())
222 aRadius = model.distancePointPoint(aCenter, aPassed)
223 aSession.finishOperation()
224 assert (aSketchFeature.numberOfSubs() == 10)
225 # check connected features do not change their positions
226 verifyPointCoordinates(aPrevCenter, aPrevCenterXY[0], aPrevCenterXY[1])
227 assert(aPrevCircle.real("circle_radius").value() == aPrevRadius)
228 verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
229 verifyPointCoordinates(aEndPnt, aLineEnd[0], aLineEnd[1])
230 # verify newly created circle
231 aCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
232 aCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
233 verifyPointCoordinates(aCenter, anExpectedCenter[0], anExpectedCenter[1])
234 verifyPointOnLine(aCenter, aLine)
235 verifyTangentCircles(aCircle, aPrevCircle)
236 model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3)
237 model.testNbSubFeatures(aSketch, "SketchConstraintTangent", 1)
238
239 #=========================================================================
240 # Test 5. Create a circle as a macro-feature by center and passed point placed on the same line
241 #         Check the circle is not created
242 #=========================================================================
243 aSession.startOperation()
244 aCircle = aSketchFeature.addFeature("SketchMacroCircle")
245 aCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
246 aCenterRef = aCircle.refattr("center_point_ref")
247 aPassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
248 aPassedRef = aCircle.refattr("passed_point_ref")
249 aCircleType = aCircle.string("circle_type")
250 # initialize attributes
251 aCircleType.setValue("circle_type_by_center_and_passed_points")
252 aCenterRef.setObject(aLine.lastResult())
253 aCenter.setValue(anExpectedCenter[0], anExpectedCenter[1])
254 aPassedRef.setObject(aLine.lastResult())
255 aPassed.setValue(aLineStart[0], aLineStart[1])
256 aSession.finishOperation()
257 aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
258 assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
259 aSession.startOperation()
260 aDocument.removeFeature(aCircle)
261 aSession.finishOperation()
262 assert (aSketchFeature.numberOfSubs() == 10)
263
264 #=========================================================================
265 # End of test
266 #=========================================================================
267
268 from salome.shaper import model
269 assert(model.checkPythonDump())