Salome HOME
2eabffec068502fb44ae6b8afb020a18de0c5d60
[modules/shaper.git] / src / SketchPlugin / Test / TestFillet.py
1 # Copyright (C) 2014-2021  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 email : webmaster.salome@opencascade.com
18 #
19
20 """
21     TestFillet.py
22     Unit test of SketchPlugin_Fillet class
23
24     SketchPlugin_Fillet
25         static const std::string MY_CONSTRAINT_FILLET_ID("SketchFillet");
26         data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
27         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
28         data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefAttrList::typeId());
29
30 """
31 from GeomDataAPI import *
32 from ModelAPI import *
33 import math
34 from salome.shaper import model
35
36 #=========================================================================
37 # Auxiliary functions
38 #=========================================================================
39 TOLERANCE = 1.e-7
40
41 def createSketch1(theSketch):
42     global aEndPoint1, aEndPoint2
43     # Initialize sketch by three lines with coincident boundaries
44     allFeatures = []
45
46     aSession.startOperation()
47     # Line1
48     aSketchLine1 = theSketch.addFeature("SketchLine")
49     aStartPoint1 = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
50     aEndPoint1   = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
51     aStartPoint1.setValue(-10., -10.)
52     aEndPoint1.setValue(-10., 10.)
53     allFeatures.append(aSketchLine1)
54     # Line2
55     aSketchLine2 = theSketch.addFeature("SketchLine")
56     aStartPoint2 = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
57     aEndPoint2   = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
58     aStartPoint2.setValue(-10., 10.)
59     aEndPoint2.setValue(10., 10.)
60     allFeatures.append(aSketchLine2)
61     # Line3
62     aSketchLine3 = theSketch.addFeature("SketchLine")
63     aStartPoint3 = geomDataAPI_Point2D(aSketchLine3.attribute("StartPoint"))
64     aEndPoint3   = geomDataAPI_Point2D(aSketchLine3.attribute("EndPoint"))
65     aStartPoint3.setValue(10., 10.)
66     aEndPoint3.setValue(10., -10.)
67     allFeatures.append(aSketchLine3)
68     # Coincidence1
69     aCoincidence1 = theSketch.addFeature("SketchConstraintCoincidence")
70     aCoincidence1.refattr("ConstraintEntityA").setAttr(aEndPoint1)
71     aCoincidence1.refattr("ConstraintEntityB").setAttr(aStartPoint2)
72     # Coincidence2
73     aCoincidence2 = theSketch.addFeature("SketchConstraintCoincidence")
74     aCoincidence2.refattr("ConstraintEntityA").setAttr(aEndPoint2)
75     aCoincidence2.refattr("ConstraintEntityB").setAttr(aStartPoint3)
76
77     aSession.finishOperation()
78     return allFeatures
79
80
81 def createSketch2(theSketch):
82     global aStartPoint1
83     # Initialize sketch by line and arc with coincident boundary
84     allFeatures = []
85
86     aSession.startOperation()
87     # Line
88     aSketchLine = theSketch.addFeature("SketchLine")
89     aStartPoint1 = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
90     aEndPoint1   = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
91     aStartPoint1.setValue(10., 10.)
92     aEndPoint1.setValue(30., 15.)
93     allFeatures.append(aSketchLine)
94     # Arc
95     aSketchArc = theSketch.addFeature("SketchArc")
96     aStartPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
97     aEndPoint2   = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
98     aCenterPoint = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
99     aCenterPoint.setValue(20., 10.)
100     aStartPoint2.setValue(10., 10.)
101     aEndPoint2.setValue(20., 0.)
102     allFeatures.append(aSketchArc)
103     # Coincidence
104     aCoincidence = theSketch.addFeature("SketchConstraintCoincidence")
105     aCoincidence.refattr("ConstraintEntityA").setAttr(aStartPoint1)
106     aCoincidence.refattr("ConstraintEntityB").setAttr(aStartPoint2)
107
108     aSession.finishOperation()
109     return allFeatures
110
111 def checkSmoothness(theSketch):
112     aPtPtCoincidences = getCoincidences(theSketch)
113     for coinc in aPtPtCoincidences:
114         aConnectedFeatures = connectedFeatures(coinc)
115         assert(len(aConnectedFeatures) == 2)
116         if aConnectedFeatures[0].getKind() == "SketchArc":
117             if aConnectedFeatures[1].getKind() == "SketchArc":
118                 checkArcArcSmoothness(aConnectedFeatures[0], aConnectedFeatures[1])
119             elif aConnectedFeatures[1].getKind() == "SketchLine":
120                 checkArcLineSmoothness(aConnectedFeatures[0], aConnectedFeatures[1])
121         elif aConnectedFeatures[0].getKind() == "SketchLine" and aConnectedFeatures[1].getKind() == "SketchArc":
122             checkArcLineSmoothness(aConnectedFeatures[1], aConnectedFeatures[0])
123
124 def checkArcLineSmoothness(theArc, theLine):
125     aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
126     aDistance = model.distancePointLine(aCenter, theLine)
127     aRadius = arcRadius(theArc)
128     assert(math.fabs(aRadius - aDistance) < TOLERANCE)
129
130 def checkArcArcSmoothness(theArc1, theArc2):
131     aCenter1 = geomDataAPI_Point2D(theArc1.attribute("center_point"))
132     aCenter2 = geomDataAPI_Point2D(theArc2.attribute("center_point"))
133     aDistance = model.distancePointPoint(aCenter1, aCenter2)
134     aRadius1 = arcRadius(theArc1)
135     aRadius2 = arcRadius(theArc2)
136     aRadSum = aRadius1 + aRadius2
137     aRadDiff = math.fabs(aRadius1 - aRadius2)
138     assert(math.fabs(aDistance - aRadSum) < TOLERANCE or math.fabs(aDistance - aRadDiff) < TOLERANCE)
139
140 def getCoincidences(theSketch):
141     aCoincidences = []
142     for anIndex in range(0, theSketch.numberOfSubs()):
143         aSubFeature = theSketch.subFeature(anIndex)
144         if aSubFeature.getKind() == "SketchConstraintCoincidence":
145             anEntityA = aSubFeature.refattr("ConstraintEntityA")
146             anEntityB = aSubFeature.refattr("ConstraintEntityB")
147             if not anEntityA.isObject() and not anEntityB.isObject():
148                 aCoincidences.append(aSubFeature)
149     return aCoincidences
150
151 def connectedFeatures(theCoincidence):
152     anEntityA = theCoincidence.refattr("ConstraintEntityA")
153     anEntityB = theCoincidence.refattr("ConstraintEntityB")
154     aFeatureA = ModelAPI.ModelAPI_Feature.feature(anEntityA.attr().owner())
155     aFeatureB = ModelAPI.ModelAPI_Feature.feature(anEntityB.attr().owner())
156     return [aFeatureA, aFeatureB]
157
158 def arcRadius(theArc):
159     aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
160     aStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
161     return model.distancePointPoint(aCenter, aStart)
162
163
164 #=========================================================================
165 # Initialization of the test
166 #=========================================================================
167
168 __updated__ = "2015-09-18"
169
170 aSession = ModelAPI_Session.get()
171 aDocument = aSession.moduleDocument()
172 #=========================================================================
173 # Creation of a sketch
174 #=========================================================================
175 aSession.startOperation()
176 aSketchCommonFeature = aDocument.addFeature("Sketch")
177 aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
178 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
179 origin.setValue(0, 0, 0)
180 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
181 dirx.setValue(1, 0, 0)
182 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
183 norm.setValue(0, 0, 1)
184 aSession.finishOperation()
185 #=========================================================================
186 # Initialize sketch by three connected lines
187 #=========================================================================
188 createSketch1(aSketchFeature)
189 assert (model.dof(aSketchFeature) == 8)
190 #=========================================================================
191 # Create the Fillet
192 #=========================================================================
193 aSession.startOperation()
194 aFillet = aSketchFeature.addFeature("SketchFillet")
195 aFillet.refattr("fillet_point").setAttr(aEndPoint1);
196 aSession.finishOperation()
197 aSession.startOperation()
198 aFillet = aSketchFeature.addFeature("SketchFillet")
199 aFillet.refattr("fillet_point").setAttr(aEndPoint2);
200 aSession.finishOperation()
201 #=========================================================================
202 # Verify the objects of fillet are created
203 #=========================================================================
204 checkSmoothness(aSketchFeature)
205 assert (model.dof(aSketchFeature) == 10)
206 #=========================================================================
207 # Move a line and check the fillet is correct
208 #=========================================================================
209 DELTA_X = DELTA_Y = 10.
210 aSession.startOperation()
211 aEndPoint1.setValue(aEndPoint1.x() + DELTA_X, aEndPoint1.y() + DELTA_Y)
212 aSession.finishOperation()
213 checkSmoothness(aSketchFeature)
214 assert (model.dof(aSketchFeature) == 10)
215
216
217 #=========================================================================
218 # Create another sketch
219 #=========================================================================
220 aSession.startOperation()
221 aSketchCommonFeature = aDocument.addFeature("Sketch")
222 aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
223 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
224 origin.setValue(0, 0, 0)
225 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
226 dirx.setValue(1, 0, 0)
227 norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
228 norm.setValue(0, 1, 0)
229 aSession.finishOperation()
230 #=========================================================================
231 # Initialize sketch by line and arc
232 #=========================================================================
233 createSketch2(aSketchFeature)
234 assert (model.dof(aSketchFeature) == 7)
235 #=========================================================================
236 # Create the Fillet
237 #=========================================================================
238 aSession.startOperation()
239 aFillet = aSketchFeature.addFeature("SketchFillet")
240 aFillet.refattr("fillet_point").setAttr(aStartPoint1)
241 aSession.finishOperation()
242 #=========================================================================
243 # Verify the objects of fillet are created
244 #=========================================================================
245 checkSmoothness(aSketchFeature)
246 assert (model.dof(aSketchFeature) == 8)
247 #=========================================================================
248 # Move a line and check the fillet is correct
249 #=========================================================================
250 DELTA_X = 1.
251 DELTA_Y = -2.
252 aSession.startOperation()
253 aStartPoint1.setValue(aStartPoint1.x() + DELTA_X, aStartPoint1.y() + DELTA_Y)
254 aSession.finishOperation()
255 checkSmoothness(aSketchFeature)
256 assert (model.dof(aSketchFeature) == 8)
257 #=========================================================================
258 # End of test
259 #=========================================================================
260
261 # TODO: Improve Fillet test case by moving one of filleted objectes and check coincidence and tangency are correct
262
263 assert(model.checkPythonDump())