Salome HOME
Adjust processing of Coincidence constraint by PlaneGCSSolver
[modules/shaper.git] / src / SketchPlugin / Test / TestFillet.py
1 """
2     TestFillet.py
3     Unit test of SketchPlugin_ConstraintFillet class
4
5     SketchPlugin_ConstraintFillet
6         static const std::string MY_CONSTRAINT_FILLET_ID("SketchConstraintFillet");
7         data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
8         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttrList::typeId());
9         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
10         data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefAttrList::typeId());
11
12 """
13 from GeomDataAPI import *
14 from ModelAPI import *
15 import math
16 from salome.shaper import model
17
18 #=========================================================================
19 # Auxiliary functions
20 #=========================================================================
21 aStartPoint1 = []
22
23 def createSketch1(theSketch):
24     global aEndPoint1, aEndPoint2
25     # Initialize sketch by three lines with coincident boundaries
26     allFeatures = []
27     # Line1
28     aSketchLine1 = theSketch.addFeature("SketchLine")
29     aStartPoint1 = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
30     aEndPoint1   = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
31     aStartPoint1.setValue(-10., -10.)
32     aEndPoint1.setValue(-10., 10.)
33     allFeatures.append(aSketchLine1)
34     # Line2
35     aSketchLine2 = theSketch.addFeature("SketchLine")
36     aStartPoint2 = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
37     aEndPoint2   = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
38     aStartPoint2.setValue(-10., 10.)
39     aEndPoint2.setValue(10., 10.)
40     allFeatures.append(aSketchLine2)
41     # Line3
42     aSketchLine3 = theSketch.addFeature("SketchLine")
43     aStartPoint3 = geomDataAPI_Point2D(aSketchLine3.attribute("StartPoint"))
44     aEndPoint3   = geomDataAPI_Point2D(aSketchLine3.attribute("EndPoint"))
45     aStartPoint3.setValue(10., 10.)
46     aEndPoint3.setValue(10., -10.)
47     allFeatures.append(aSketchLine3)
48     # Coincidence1
49     aCoincidence1 = theSketch.addFeature("SketchConstraintCoincidence")
50     aCoincidence1.refattr("ConstraintEntityA").setAttr(aEndPoint1)
51     aCoincidence1.refattr("ConstraintEntityB").setAttr(aStartPoint2)
52     # Coincidence2
53     aCoincidence2 = theSketch.addFeature("SketchConstraintCoincidence")
54     aCoincidence2.refattr("ConstraintEntityA").setAttr(aEndPoint2)
55     aCoincidence2.refattr("ConstraintEntityB").setAttr(aStartPoint3)
56
57     theSketch.execute()
58     return allFeatures
59
60
61 def createSketch2(theSketch):
62     global aStartPoint1
63     # Initialize sketch by line and arc with coincident boundary
64     allFeatures = []
65     # Line
66     aSketchLine = theSketch.addFeature("SketchLine")
67     aStartPoint1 = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
68     aEndPoint1   = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
69     aStartPoint1.setValue(10., 10.)
70     aEndPoint1.setValue(30., 15.)
71     allFeatures.append(aSketchLine)
72     # Arc
73     aSketchArc = theSketch.addFeature("SketchArc")
74     aStartPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
75     aEndPoint2   = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
76     aCenterPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
77     aCenterPoint.setValue(20., 10.)
78     aStartPoint2.setValue(10., 10.)
79     aEndPoint2.setValue(20., 0.)
80     allFeatures.append(aSketchArc)
81     # Coincidence
82     aCoincidence = theSketch.addFeature("SketchConstraintCoincidence")
83     aCoincidence.refattr("ConstraintEntityA").setAttr(aStartPoint1)
84     aCoincidence.refattr("ConstraintEntityB").setAttr(aStartPoint2)
85
86     theSketch.execute()
87     return allFeatures
88
89 def checkFillet(theObjects, theRadius):
90     # Verify the arc and lines are connected smoothly
91     print "Check Fillet"
92     aLine = []
93     anArc = []
94     aSize = len(theObjects)
95     for feat in theObjects:
96         assert(feat is not None)
97         if (feat.getKind() == "SketchLine"):
98             aLine.append(feat)
99         elif (feat.getKind() == "SketchArc"):
100             anArc.append(feat)
101     aFilletArc = anArc[-1]
102     assert(aFilletArc is not None)
103     anArc.pop()
104
105     anArcPoints = []
106     aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcStartPoint"))
107     #print "ArcStartPoint " + repr(aPoint.x()) + " " + repr(aPoint.y())
108     anArcPoints.append((aPoint.x(), aPoint.y()))
109     aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcEndPoint"))
110     #print "ArcEndPoint " + repr(aPoint.x()) + " " + repr(aPoint.y())
111     anArcPoints.append((aPoint.x(), aPoint.y()))
112     aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcCenter"))
113     #print "ArcCenter " + repr(aPoint.x()) + " " + repr(aPoint.y())
114     aCenterX = aPoint.x()
115     aCenterY = aPoint.y()
116     aFilletRadius = math.hypot(anArcPoints[0][0]-aCenterX, anArcPoints[0][1]-aCenterY)
117
118     for line in aLine:
119         aStartPoint = geomDataAPI_Point2D(line.attribute("StartPoint"))
120         aEndPoint = geomDataAPI_Point2D(line.attribute("EndPoint"))
121
122         aLinePoints = []
123         aLinePoints.append((aStartPoint.x(), aStartPoint.y()))
124         #print "aLineStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y())
125         aLinePoints.append((aEndPoint.x(), aEndPoint.y()))
126         #print "aLineEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y())
127
128         aLineDirX = aEndPoint.x() - aStartPoint.x()
129         aLineDirY = aEndPoint.y() - aStartPoint.y()
130
131         for arcPt in anArcPoints:
132             for linePt in aLinePoints:
133                 if (math.hypot(linePt[0]-arcPt[0], linePt[1]-arcPt[1]) < 1.e-10):
134                     aDirX = linePt[0] - aCenterX
135                     aDirY = linePt[1] - aCenterY
136                     assert(math.fabs(math.hypot(aDirX, aDirY) - theRadius) < 1.e-7)
137                     aDot = aDirX * aLineDirX + aDirY * aLineDirY
138
139                     break;
140
141     if (aSize == 3):
142         for arc in anArc:
143             aStartPoint = geomDataAPI_Point2D(arc.attribute("ArcStartPoint"))
144             aEndPoint = geomDataAPI_Point2D(arc.attribute("ArcEndPoint"))
145             aCenterPoint = geomDataAPI_Point2D(arc.attribute("ArcCenter"))
146
147             aBaseArcPoints = []
148             aBaseArcPoints.append((aStartPoint.x(), aStartPoint.y()))
149             #print "anArcStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y())
150             aBaseArcPoints.append((aEndPoint.x(), aEndPoint.y()))
151             #print "anArcEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y())
152             #print "anArcCenter " + repr(aCenterPoint.x()) + " " + repr(aCenterPoint.y())
153
154             aRadius = math.hypot(aStartPoint.x()-aCenterPoint.x(), aStartPoint.y()-aCenterPoint.y())
155             aDist = math.hypot(aCenterPoint.x() - aCenterX, aCenterPoint.y() - aCenterY)
156             assert math.fabs(aFilletRadius + aRadius - aDist) < 1.e-7 or math.fabs(math.fabs(aFilletRadius - aRadius) - aDist) < 1.e-7, \
157                 "Fillet radius = {0}, Base arc radius = {1}, distance between centers = {2}".format(aFilletRadius, aRadius, aDist)
158
159
160 #=========================================================================
161 # Initialization of the test
162 #=========================================================================
163
164 __updated__ = "2015-09-18"
165
166 aSession = ModelAPI_Session.get()
167 aDocument = aSession.moduleDocument()
168 #=========================================================================
169 # Creation of a sketch
170 #=========================================================================
171 aSession.startOperation()
172 aSketchCommonFeature = aDocument.addFeature("Sketch")
173 aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
174 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
175 origin.setValue(0, 0, 0)
176 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
177 dirx.setValue(1, 0, 0)
178 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
179 norm.setValue(0, 0, 1)
180 aSession.finishOperation()
181 #=========================================================================
182 # Initialize sketch by three connected lines
183 #=========================================================================
184 aSession.startOperation()
185 aFeaturesList = createSketch1(aSketchFeature)
186 aSession.finishOperation()
187 aSketchSubFeatures = []
188 for aSubIndex in range(0, aSketchFeature.numberOfSubs()):
189     aSketchSubFeatures.append(aSketchFeature.subFeature(aSubIndex))
190 assert (model.dof(aSketchFeature) == 8)
191 #=========================================================================
192 # Global variables
193 #=========================================================================
194 FILLET_RADIUS1 = 3.
195 FILLET_RADIUS2 = 5.
196 #=========================================================================
197 # Create the Fillet
198 #=========================================================================
199 aSession.startOperation()
200 aFillet = aSketchFeature.addFeature("SketchConstraintFillet")
201 aRefAttrA = aFillet.data().refattrlist("ConstraintEntityA");
202 aRefAttrA.append(aEndPoint1)
203 aRefAttrA.append(aEndPoint2)
204 aRadius = aFillet.real("ConstraintValue")
205 aRadius.setValue(FILLET_RADIUS1)
206 aFillet.execute()
207 aResObjects = []
208 for aSubIndex in range(0, aSketchFeature.numberOfSubs()):
209     aSubFeature = aSketchFeature.subFeature(aSubIndex)
210     if aSubFeature not in aSketchSubFeatures:
211         if aSubFeature.getKind() == "SketchLine":
212             aResObjects.insert(0, aSubFeature)
213         elif aSubFeature.getKind() == "SketchArc":
214             aResObjects.append(aSubFeature)
215 #=========================================================================
216 # Verify the objects of fillet are created
217 #=========================================================================
218 assert(aResObjects)
219 checkFillet(aResObjects, FILLET_RADIUS1)
220 assert model.dof(aSketchFeature) == 8, "PlaneGCS limitation: if you see this message, then PlaneGCS has solved DoF for sketch with fillet correctly (expected DoF = 10, observed = {0}".format(model.dof(aSketchFeature))
221 #=========================================================================
222 # Change Fillet radius
223 #=========================================================================
224 aRadius.setValue(FILLET_RADIUS2)
225 aFillet.execute()
226 aSession.finishOperation()
227 checkFillet(aResObjects, FILLET_RADIUS2)
228 assert model.dof(aSketchFeature) == 8, "PlaneGCS limitation: if you see this message, then PlaneGCS has solved DoF for sketch with fillet correctly (expected DoF = 10, observed = {0}".format(model.dof(aSketchFeature))
229
230 #=========================================================================
231 # Create another sketch
232 #=========================================================================
233 aSession.startOperation()
234 aSketchCommonFeature = aDocument.addFeature("Sketch")
235 aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
236 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
237 origin.setValue(0, 0, 0)
238 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
239 dirx.setValue(1, 0, 0)
240 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
241 norm.setValue(0, 1, 0)
242 aSession.finishOperation()
243 #=========================================================================
244 # Initialize sketch by line and arc
245 #=========================================================================
246 aSession.startOperation()
247 aFeaturesList = createSketch2(aSketchFeature)
248 aSession.finishOperation()
249 aSketchSubFeatures = []
250 for aSubIndex in range(0, aSketchFeature.numberOfSubs()):
251     aSketchSubFeatures.append(aSketchFeature.subFeature(aSubIndex))
252 assert (model.dof(aSketchFeature) == 7)
253 #=========================================================================
254 # Create the Fillet
255 #=========================================================================
256 aSession.startOperation()
257 aFillet = aSketchFeature.addFeature("SketchConstraintFillet")
258 aRefAttrA = aFillet.data().refattrlist("ConstraintEntityA");
259 aRefAttrA.append(aStartPoint1)
260 aRadius = aFillet.real("ConstraintValue")
261 aRadius.setValue(FILLET_RADIUS1)
262 aFillet.execute()
263 aResObjects = []
264 for aSubIndex in range(0, aSketchFeature.numberOfSubs()):
265     aSubFeature = aSketchFeature.subFeature(aSubIndex)
266     if aSubFeature not in aSketchSubFeatures:
267         if aSubFeature.getKind() == "SketchLine":
268             aResObjects.insert(0, aSubFeature)
269         elif aSubFeature.getKind() == "SketchArc":
270             aResObjects.append(aSubFeature)
271 #=========================================================================
272 # Verify the objects of fillet are created
273 #=========================================================================
274 assert(aResObjects)
275 checkFillet(aResObjects, FILLET_RADIUS1)
276 assert model.dof(aSketchFeature) == 7, "PlaneGCS limitation: if you see this message, then PlaneGCS has solved DoF for sketch with fillet correctly (expected DoF = 8, observed = {0}".format(model.dof(aSketchFeature))
277 #=========================================================================
278 # Change Fillet radius
279 #=========================================================================
280 aRadius.setValue(FILLET_RADIUS2)
281 aFillet.execute()
282 aSession.finishOperation()
283 checkFillet(aResObjects, FILLET_RADIUS2)
284 assert model.dof(aSketchFeature) == 11, "PlaneGCS limitation: if you see this message, then PlaneGCS has solved DoF for sketch with fillet correctly (expected DoF = 8, observed = {0}".format(model.dof(aSketchFeature))
285 #=========================================================================
286 # End of test
287 #=========================================================================
288
289 assert(model.checkPythonDump())