Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchPlugin / Test / TestMirror.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     TestConstraintMirror.py
22     Unit test of SketchPlugin_ConstraintMirror class
23
24     SketchPlugin_ConstraintMirror
25         static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
26         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
27         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::typeId());
28         data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::typeId());
29
30 """
31 from GeomDataAPI import *
32 from ModelAPI import *
33 import math
34 from salome.shaper import model
35
36 #=========================================================================
37 # Initialization of the test
38 #=========================================================================
39
40 __updated__ = "2015-03-17"
41
42 #=========================================================================
43 # Auxiliary functions
44 #=========================================================================
45 def normalize(theDir):
46     aLen = math.hypot(theDir[0], theDir[1])
47     if aLen < 1.e-10:
48         aLen = 1.0
49     return [theDir[0] / aLen, theDir[1] / aLen]
50
51 def checkMirror(theListInit, theListMirr, theMirrorLine):
52     TOL = 6.e-5
53     aListSize = theListInit.size()
54
55     aLineStartPoint = geomDataAPI_Point2D(theMirrorLine.attribute("StartPoint"))
56     aLineEndPoint = geomDataAPI_Point2D(theMirrorLine.attribute("EndPoint"))
57     aLineDir = [aLineEndPoint.x() - aLineStartPoint.x(), aLineEndPoint.y() - aLineStartPoint.y()]
58     aLineDir = normalize(aLineDir)
59
60     for ind in range(0, aListSize):
61         aFeatureB = ModelAPI_Feature.feature(theListInit.object(ind))
62         aFeatureC = ModelAPI_Feature.feature(theListMirr.object(ind))
63         assert(aFeatureB is not None)
64         assert(aFeatureC is not None)
65         assert(aFeatureB.getKind() == aFeatureC.getKind())
66
67         anAttributes = []
68         if (aFeatureB.getKind() == "SketchLine"):
69             anAttributes = ['StartPoint', 'EndPoint']
70         elif (aFeatureB.getKind() == "SketchArc"):
71             anAttributes = ['center_point', 'start_point', 'end_point']
72
73         for key in anAttributes:
74             aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
75             aPointC = geomDataAPI_Point2D(aFeatureC.attribute(key))
76             aDir = [aPointC.x() - aPointB.x(), aPointC.y() - aPointB.y()]
77             aDir = normalize(aDir)
78             aDot = aLineDir[0] * aDir[0] + aLineDir[1] * aDir[1]
79             assert math.fabs(aDot) < TOL, "aDot = {0}".format(aDot)
80             aDir[0] = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
81             aDir[1] = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
82             aCross = aLineDir[0] * aDir[1] - aLineDir[1] * aDir[0]
83             assert math.fabs(aCross) < TOL, "aCross = {0}".format(aCross)
84
85
86 #=========================================================================
87 # Start of test
88 #=========================================================================
89 aSession = ModelAPI_Session.get()
90 aDocument = aSession.moduleDocument()
91 #=========================================================================
92 # Creation of a sketch
93 #=========================================================================
94 aSession.startOperation()
95 aSketchCommonFeature = aDocument.addFeature("Sketch")
96 aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
97 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
98 origin.setValue(0, 0, 0)
99 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
100 dirx.setValue(1, 0, 0)
101 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
102 norm.setValue(0, 0, 1)
103 aSession.finishOperation()
104 #=========================================================================
105 # Creation of an arc and two lines
106 #=========================================================================
107 # Arc
108 aSession.startOperation()
109 aSketchArc1 = aSketchFeature.addFeature("SketchArc")
110 anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("center_point"))
111 anArcCentr.setValue(10., 10.)
112 anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
113 anArcStartPoint.setValue(0., 50.)
114 anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("end_point"))
115 anArcEndPoint.setValue(50., 0.)
116 aSession.finishOperation()
117 # Line 1
118 aSession.startOperation()
119 aSketchLine1 = aSketchFeature.addFeature("SketchLine")
120 aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
121 aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
122 aLine1StartPoint.setValue(0., 50.)
123 aLine1EndPoint.setValue(0., 100.)
124 aSession.finishOperation()
125 # Line 2
126 aSession.startOperation()
127 aSketchLine2 = aSketchFeature.addFeature("SketchLine")
128 aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
129 aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
130 aLine2StartPoint.setValue(50., 0.)
131 aLine2EndPoint.setValue(100., 0.)
132 aSession.finishOperation()
133 assert (model.dof(aSketchFeature) == 13)
134 #=========================================================================
135 # Link arc points and lines points by the coincidence constraint
136 #=========================================================================
137 aSession.startOperation()
138 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
139 reflistA = aConstraint.refattr("ConstraintEntityA")
140 reflistB = aConstraint.refattr("ConstraintEntityB")
141 reflistA.setAttr(anArcStartPoint)
142 reflistB.setAttr(aLine1StartPoint)
143 aConstraint.execute()
144 aSession.finishOperation()
145 aSession.startOperation()
146 aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
147 reflistA = aConstraint.refattr("ConstraintEntityA")
148 reflistB = aConstraint.refattr("ConstraintEntityB")
149 reflistA.setAttr(anArcEndPoint)
150 reflistB.setAttr(aLine2StartPoint)
151 aConstraint.execute()
152 aSession.finishOperation()
153 assert (model.dof(aSketchFeature) == 9)
154 #=========================================================================
155 # Add tangency constraint and check correctness
156 #=========================================================================
157 aSession.startOperation()
158 aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
159 aRefObjectA = aTangency.refattr("ConstraintEntityA")
160 aRefObjectB = aTangency.refattr("ConstraintEntityB")
161 anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
162 anObjectB = modelAPI_ResultConstruction(aSketchLine1.lastResult())
163 assert (anObjectA is not None)
164 assert (anObjectB is not None)
165 aRefObjectA.setObject(anObjectA)
166 aRefObjectB.setObject(anObjectB)
167 aTangency.execute()
168 aSession.finishOperation()
169 assert (model.dof(aSketchFeature) == 8)
170 #=========================================================================
171 # Create mirror line
172 #=========================================================================
173 aSession.startOperation()
174 aMirrorLine = aSketchFeature.addFeature("SketchLine")
175 aLineStartPoint = geomDataAPI_Point2D(aMirrorLine.attribute("StartPoint"))
176 aLineEndPoint = geomDataAPI_Point2D(aMirrorLine.attribute("EndPoint"))
177 aLineStartPoint.setValue(100., 0.)
178 aLineEndPoint.setValue(100., 100.)
179 aSession.finishOperation()
180 assert (model.dof(aSketchFeature) == 12)
181 #=========================================================================
182 # Make mirror for objects created above
183 #=========================================================================
184 aSession.startOperation()
185 aMirror = aSketchFeature.addFeature("SketchConstraintMirror")
186 aRefObjectA = aMirror.refattr("ConstraintEntityA")
187 aRefObjectA.setObject(modelAPI_ResultConstruction(aMirrorLine.firstResult()))
188 aRefListInitial = aMirror.reflist("ConstraintMirrorList")
189 aRefListInitial.append(aSketchLine1.lastResult())
190 aRefListInitial.append(aSketchArc1.lastResult())
191 aRefListInitial.append(aSketchLine2.lastResult())
192 aMirror.execute()
193 aSession.finishOperation()
194 assert (model.dof(aSketchFeature) == 12)
195 #=========================================================================
196 # Verify the simmetricity of all mirrored objects
197 #=========================================================================
198 aRefListB = aMirror.reflist("ConstraintEntityB")
199 aRefListC = aMirror.reflist("ConstraintEntityC")
200 assert (aRefListB.size() == 3)
201 assert (aRefListC.size() == 3)
202 checkMirror(aRefListB, aRefListC, aMirrorLine)
203 assert (model.dof(aSketchFeature) == 12)
204
205 #=========================================================================
206 # Remove object from mirror
207 #=========================================================================
208 aSession.startOperation()
209 aRefListInitial.remove(aSketchLine2.lastResult())
210 aSession.finishOperation()
211 assert (aRefListB.size() == 2)
212 assert (aRefListC.size() == 2)
213 checkMirror(aRefListB, aRefListC, aMirrorLine)
214 assert (model.dof(aSketchFeature) == 12)
215
216 #=========================================================================
217 # Clear list of mirrored features
218 #=========================================================================
219 aSession.startOperation()
220 aRefListInitial.clear()
221 assert (aRefListB.size() == 0)
222 assert (aRefListC.size() == 0)
223 # add arc once again
224 aRefListInitial.append(aSketchArc1.lastResult())
225 aSession.finishOperation()
226 assert (aRefListB.size() == 1)
227 assert (aRefListC.size() == 1)
228 checkMirror(aRefListB, aRefListC, aMirrorLine)
229 assert (model.dof(aSketchFeature) == 12)
230
231 #=========================================================================
232 # Create distance between original and mirrored entities (check the error appears)
233 #=========================================================================
234 aSketchErrorAttr = aSketchFeature.string("SolverError")
235 assert len(aSketchErrorAttr.value()) == 0, "Sketch failed with error: {}".format(aSketchErrorAttr.value())
236 aMirroredArc = model.lastSubFeature(aSketchFeature, "SketchArc")
237 aSession.startOperation()
238 aConstraint = aSketchFeature.addFeature("SketchConstraintDistance")
239 refAttrA = aConstraint.refattr("ConstraintEntityA")
240 refAttrB = aConstraint.refattr("ConstraintEntityB")
241 anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
242 aMirroredArcStartPoint = geomDataAPI_Point2D(aMirroredArc.attribute("start_point"))
243 refAttrA.setAttr(anArcStartPoint)
244 refAttrB.setAttr(aMirroredArcStartPoint)
245 aConstraint.real("ConstraintValue").setValue(200.)
246 aSession.finishOperation()
247 print("Sketch error : {}".format(aSketchErrorAttr.value()))
248 assert len(aSketchErrorAttr.value()) != 0, "ERROR: Sketch has not been failed as expected"
249 aSession.startOperation()
250 aDocument.removeFeature(aConstraint)
251 aSession.finishOperation()
252
253 #=========================================================================
254 # End of test
255 #=========================================================================
256
257 assert(model.checkPythonDump())