Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchPlugin / Test / TestConstraintCoincidence.py
1 # Copyright (C) 2014-2023  CEA, EDF
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 email : webmaster.salome@opencascade.com
18 #
19
20 """
21     TestConstraintCoincidence.py
22     Unit test of SketchPlugin_ConstraintCoincidence class
23
24     SketchPlugin_Constraint
25         static const std::string MY_CONSTRAINT_VALUE("ConstraintValue");
26         static const std::string MY_FLYOUT_VALUE_PNT("ConstraintFlyoutValuePnt");
27         static const std::string MY_ENTITY_A("ConstraintEntityA");
28         static const std::string MY_ENTITY_B("ConstraintEntityB");
29         static const std::string MY_ENTITY_C("ConstraintEntityC");
30         static const std::string MY_ENTITY_D("ConstraintEntityD");
31
32     SketchPlugin_ConstraintCoincidence
33         static const std::string MY_CONSTRAINT_COINCIDENCE_ID("SketchConstraintCoincidence");
34         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
35         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
36
37 """
38 from GeomDataAPI import *
39 from ModelAPI import *
40 import math
41 from salome.shaper import model
42
43 #=========================================================================
44 # Initialization of the test
45 #=========================================================================
46
47 __updated__ = "2014-10-28"
48 TOLERANCE = 1.e-7
49
50
51 #=========================================================================
52 # Auxiliary functions
53 #=========================================================================
54 def checkPointOnLine(point, line):
55     aStart = geomDataAPI_Point2D(line.attribute("StartPoint"))
56     aEnd   = geomDataAPI_Point2D(line.attribute("EndPoint"))
57     aDirX = aEnd.x() - aStart.x()
58     aDirY = aEnd.y() - aStart.y()
59     aVecX = point.x() - aStart.x()
60     aVecY = point.y() - aStart.y()
61     assert (math.fabs(aDirX * aVecY - aDirY * aVecX) <= TOLERANCE)
62
63 def checkPointOnCircle(point, circle):
64     aCenter = geomDataAPI_Point2D(circle.attribute("circle_center"))
65     aRadius = circle.real("circle_radius").value()
66     aDist = math.hypot(point.x() - aCenter.x(), point.y() - aCenter.y())
67     assert (math.fabs(aDist - aRadius) <= TOLERANCE)
68
69 def checkPointOnArc(point, arc):
70     aStart  = geomDataAPI_Point2D(arc.attribute("start_point"))
71     aCenter = geomDataAPI_Point2D(arc.attribute("center_point"))
72     aRadius = math.hypot(aStart.x() - aCenter.x(), aStart.y() - aCenter.y())
73     aDist = math.hypot(point.x() - aCenter.x(), point.y() - aCenter.y())
74     assert (math.fabs(aDist - aRadius) <= TOLERANCE)
75
76
77 #=========================================================================
78 # Start of test
79 #=========================================================================
80 aSession = ModelAPI_Session.get()
81 aDocument = aSession.moduleDocument()
82 # add an origin
83 aSession.startOperation()
84 aFeature = aDocument.addFeature("Point")
85 geomDataAPI_Point(aFeature.attribute("point3d")).setValue(0., 0., 0.)
86 aFeature.string("creation_method").setValue("by_xyz")
87 anOriginName = aFeature.name()
88 aSession.finishOperation()
89 #=========================================================================
90 # Creation of a sketch
91 #=========================================================================
92 aSession.startOperation()
93 aSketchFeature = featureToCompositeFeature(aDocument.addFeature("Sketch"))
94 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
95 origin.setValue(0, 0, 0)
96 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
97 dirx.setValue(1, 0, 0)
98 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
99 norm.setValue(0, 0, 1)
100 aSession.finishOperation()
101 #=========================================================================
102 # Create a line and an arc
103 #=========================================================================
104 aSession.startOperation()
105 aSketchArc = aSketchFeature.addFeature("SketchArc")
106 anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
107 anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
108 anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
109 anArcCentr.setValue(10., 10.)
110 anArcStartPoint.setValue(0., 50.)
111 anArcEndPoint.setValue(50., 0.)
112 aSketchLine = aSketchFeature.addFeature("SketchLine")
113 aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
114 aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
115 # Lets initialize line start at circle's end:
116 aLineStartPoint.setValue(50., 0.)
117 aLineEndPoint.setValue(100., 25.)
118 aSession.finishOperation()
119 assert (model.dof(aSketchFeature) == 9)
120 #=========================================================================
121 # Link arc's end and line's start points with concidence constraint
122 #=========================================================================
123 aSession.startOperation()
124 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
125 reflistA = aConstraint.refattr("ConstraintEntityA")
126 reflistB = aConstraint.refattr("ConstraintEntityB")
127 reflistA.setAttr(anArcEndPoint)
128 reflistB.setAttr(aLineStartPoint)
129 aConstraint.execute()
130 aSession.finishOperation()
131 assert (model.dof(aSketchFeature) == 7)
132 #=========================================================================
133 # Check values and move one constrainted object
134 #=========================================================================
135 assert (anArcEndPoint.x() == aLineStartPoint.x())
136 assert (anArcEndPoint.y() == aLineStartPoint.y())
137 deltaX = deltaY = 40.
138 #  move line
139 aSession.startOperation()
140 aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
141                          aLineStartPoint.y() + deltaY)
142 aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
143                        aLineEndPoint.y() + deltaY)
144 aSession.finishOperation()
145 # check that arc's points are moved also
146 assert (anArcEndPoint.x() == aLineStartPoint.x())
147 assert (anArcEndPoint.y() == aLineStartPoint.y())
148 assert (model.dof(aSketchFeature) == 7)
149 #=========================================================================
150 # Remove coincidence and move the line
151 #=========================================================================
152 aSession.startOperation()
153 aDocument.removeFeature(aConstraint)
154 aSession.finishOperation()
155 aSession.startOperation()
156 aLineStartPoint.setValue(70., 0.)
157 aSession.finishOperation()
158 assert (anArcEndPoint.x() != aLineStartPoint.x() or anArcEndPoint.y() != aLineStartPoint.y())
159 assert (model.dof(aSketchFeature) == 9)
160
161 #=========================================================================
162 # Add constraint point-on-line
163 #=========================================================================
164 aSession.startOperation()
165 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
166 reflistA = aConstraint.refattr("ConstraintEntityA")
167 reflistB = aConstraint.refattr("ConstraintEntityB")
168 reflistA.setAttr(anArcStartPoint)
169 reflistB.setObject(aSketchLine.lastResult())
170 aConstraint.execute()
171 aSession.finishOperation()
172 checkPointOnLine(anArcStartPoint, aSketchLine)
173 assert (model.dof(aSketchFeature) == 8)
174 #=========================================================================
175 # Add constraint point-on-circle
176 #=========================================================================
177 aSession.startOperation()
178 # create circle with center coincident with origin
179 aSketchCircle = aSketchFeature.addFeature("SketchCircle")
180 aCircleCenter = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
181 aCircleRadius = aSketchCircle.real("circle_radius")
182 aCircleCenter.setValue(10., 10.)
183 aCircleRadius.setValue(25.)
184 aSession.finishOperation()
185 assert (model.dof(aSketchFeature) == 11)
186 # create origin
187 aSession.startOperation()
188 anOrigRes = modelAPI_Result(aDocument.objectByName("Construction", anOriginName))
189 assert (anOrigRes)
190 anOrigShape = anOrigRes.shape()
191 assert (anOrigShape)
192 anOrigin = aSketchFeature.addFeature("SketchPoint")
193 anOriginCoord = geomDataAPI_Point2D(anOrigin.attribute("PointCoordinates"))
194 anOriginCoord.setValue(0., 0.)
195 anOrigin.selection("External").setValue(anOrigRes, anOrigShape)
196 aSession.finishOperation()
197 assert (model.dof(aSketchFeature) == 11)
198 # coincidence between center of circle and the origin
199 aSession.startOperation()
200 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
201 reflistA = aConstraint.refattr("ConstraintEntityA")
202 reflistB = aConstraint.refattr("ConstraintEntityB")
203 reflistA.setAttr(aCircleCenter)
204 reflistB.setObject(anOrigin.lastResult())
205 aSession.finishOperation()
206 assert (model.dof(aSketchFeature) == 9)
207 # point-on-circle
208 aSession.startOperation()
209 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
210 reflistA = aConstraint.refattr("ConstraintEntityA")
211 reflistB = aConstraint.refattr("ConstraintEntityB")
212 reflistA.setObject(aSketchCircle.lastResult())
213 reflistB.setAttr(aLineEndPoint)
214 aConstraint.execute()
215 aSession.finishOperation()
216 checkPointOnCircle(aLineEndPoint, aSketchCircle)
217 assert (model.dof(aSketchFeature) == 8)
218 #=========================================================================
219 # Add constraint point-on-arc
220 #=========================================================================
221 aSession.startOperation("constraint point-on-arc")
222 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
223 reflistA = aConstraint.refattr("ConstraintEntityA")
224 reflistB = aConstraint.refattr("ConstraintEntityB")
225 reflistA.setAttr(aCircleCenter)
226 reflistB.setObject(aSketchArc.lastResult())
227 aConstraint.execute()
228 aSession.finishOperation()
229 checkPointOnArc(aCircleCenter, aSketchArc)
230 # check center of circle is still in origin
231 assert (aCircleCenter.x() == 0. and aCircleCenter.y() == 0.)
232 assert (model.dof(aSketchFeature) == 7)
233
234 #=========================================================================
235 # Create two more lines and set multi-coincidence between their extremities
236 #=========================================================================
237 aSession.startOperation()
238 # line 2
239 aLine2 = aSketchFeature.addFeature("SketchLine")
240 aLine2StartPoint = geomDataAPI_Point2D(aLine2.attribute("StartPoint"))
241 aLine2EndPoint = geomDataAPI_Point2D(aLine2.attribute("EndPoint"))
242 aLine2StartPoint.setValue(50., 0.)
243 aLine2EndPoint.setValue(100., 0.)
244 # line 3
245 aLine3 = aSketchFeature.addFeature("SketchLine")
246 aLine3StartPoint = geomDataAPI_Point2D(aLine3.attribute("StartPoint"))
247 aLine3EndPoint = geomDataAPI_Point2D(aLine3.attribute("EndPoint"))
248 aLine3StartPoint.setValue(50., 0.)
249 aLine3EndPoint.setValue(0., 100.)
250 aSession.finishOperation()
251 assert (model.dof(aSketchFeature) == 15)
252 # coincidences between extremities of lines
253 aSession.startOperation()
254 aConstraint12 = aSketchFeature.addFeature("SketchConstraintCoincidence")
255 refAttrA = aConstraint12.refattr("ConstraintEntityA")
256 refAttrB = aConstraint12.refattr("ConstraintEntityB")
257 refAttrA.setAttr(aLineStartPoint)
258 refAttrB.setAttr(aLine2StartPoint)
259 aConstraint23 = aSketchFeature.addFeature("SketchConstraintCoincidence")
260 refAttrA = aConstraint23.refattr("ConstraintEntityA")
261 refAttrB = aConstraint23.refattr("ConstraintEntityB")
262 refAttrA.setAttr(aLine2StartPoint)
263 refAttrB.setAttr(aLine3StartPoint)
264 aConstraint31 = aSketchFeature.addFeature("SketchConstraintCoincidence")
265 refAttrA = aConstraint31.refattr("ConstraintEntityA")
266 refAttrB = aConstraint31.refattr("ConstraintEntityB")
267 refAttrA.setAttr(aLine3StartPoint)
268 refAttrB.setAttr(aLineStartPoint)
269 aSession.finishOperation()
270 # check the points have same coordinates
271 assert (aLineStartPoint.x() == aLine2StartPoint.x() and aLineStartPoint.y() == aLine2StartPoint.y())
272 assert (aLineStartPoint.x() == aLine3StartPoint.x() and aLineStartPoint.y() == aLine3StartPoint.y())
273 assert (model.dof(aSketchFeature) == 11)
274 #=========================================================================
275 # Move one line and check other have been updated too
276 #=========================================================================
277 aSession.startOperation()
278 aLine3StartPoint.setValue(aLine3StartPoint.x() + deltaX,
279                           aLine3StartPoint.y() + deltaY)
280 aLine3EndPoint.setValue(aLine3EndPoint.x() + deltaX,
281                         aLine3EndPoint.y() + deltaY)
282 aSession.finishOperation()
283 assert (aLineStartPoint.x() == aLine2StartPoint.x() and aLineStartPoint.y() == aLine2StartPoint.y())
284 assert (aLineStartPoint.x() == aLine3StartPoint.x() and aLineStartPoint.y() == aLine3StartPoint.y())
285 assert (model.dof(aSketchFeature) == 11)
286 #=========================================================================
287 # Fix a line and move another connected segment
288 #=========================================================================
289 coordX = aLineStartPoint.x()
290 coordY = aLineStartPoint.y()
291 aSession.startOperation()
292 aFixed = aSketchFeature.addFeature("SketchConstraintRigid")
293 refAttrA = aFixed.refattr("ConstraintEntityA")
294 refAttrA.setObject(aLine2.lastResult())
295 aSession.finishOperation()
296 # move another line
297 aSession.startOperation()
298 aLine3StartPoint.setValue(aLine3StartPoint.x() + deltaX,
299                           aLine3StartPoint.y() + deltaY)
300 aLine3EndPoint.setValue(aLine3EndPoint.x() + deltaX,
301                         aLine3EndPoint.y() + deltaY)
302 aSession.finishOperation()
303 assert (aLineStartPoint.x() == coordX and aLineStartPoint.y() == coordY)
304 assert (aLine2StartPoint.x() == coordX and aLine2StartPoint.y() == coordY)
305 assert (aLine3StartPoint.x() == coordX and aLine3StartPoint.y() == coordY)
306 assert (model.dof(aSketchFeature) == 7)
307 #=========================================================================
308 # Detach fixed line and move one of remaining
309 #=========================================================================
310 aSession.startOperation()
311 aDocument.removeFeature(aConstraint12)
312 aDocument.removeFeature(aConstraint23)
313 aSession.finishOperation()
314 # move line
315 deltaX = 1.
316 deltaY = 0.
317 aSession.startOperation()
318 aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
319                           aLineStartPoint.y() + deltaY)
320 aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
321                         aLineEndPoint.y() + deltaY)
322 aSession.finishOperation()
323 assert (aLineStartPoint.x() != aLine2StartPoint.x() or aLineStartPoint.y() != aLine2StartPoint.y())
324 assert (aLineStartPoint.x() == aLine3StartPoint.x() and aLineStartPoint.y() == aLine3StartPoint.y())
325 assert (model.dof(aSketchFeature) == 9)
326
327 #=========================================================================
328 # End of test
329 #=========================================================================
330
331 assert(model.checkPythonDump())