FreeCAD

Форк
0
/
TestPathProfile.py 
240 строк · 11.0 Кб
1
# -*- coding: utf-8 -*-
2
# ***************************************************************************
3
# *   Copyright (c) 2023 Robert Schöftner <rs@unfoo.net>                    *
4
# *   Copyright (c) 2021 Russell Johnson (russ4262) <russ4262@gmail.com>    *
5
# *                                                                         *
6
# *   This file is part of the FreeCAD CAx development system.              *
7
# *                                                                         *
8
# *   This program is free software; you can redistribute it and/or modify  *
9
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
10
# *   as published by the Free Software Foundation; either version 2 of     *
11
# *   the License, or (at your option) any later version.                   *
12
# *   for detail see the LICENCE text file.                                 *
13
# *                                                                         *
14
# *   This program is distributed in the hope that it will be useful,       *
15
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
16
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
17
# *   GNU Library General Public License for more details.                  *
18
# *                                                                         *
19
# *   You should have received a copy of the GNU Library General Public     *
20
# *   License along with this program; if not, write to the Free Software   *
21
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
22
# *   USA                                                                   *
23
# *                                                                         *
24
# ***************************************************************************
25

26
import FreeCAD
27
import Part
28
import Path.Op.Profile as PathProfile
29
import Path.Main.Job as PathJob
30
from Tests.PathTestUtils import PathTestBase
31
from Tests.TestPathAdaptive import getGcodeMoves
32

33
if FreeCAD.GuiUp:
34
    import Path.Main.Gui.Job as PathJobGui
35
    import Path.Op.Gui.Profile as PathProfileGui
36

37

38
class TestPathProfile(PathTestBase):
39
    """Unit tests for the Adaptive operation."""
40

41
    @classmethod
42
    def setUpClass(cls):
43
        """setUpClass()...
44
        This method is called upon instantiation of this test class.  Add code and objects here
45
        that are needed for the duration of the test() methods in this class.  In other words,
46
        set up the 'global' test environment here; use the `setUp()` method to set up a 'local'
47
        test environment.
48
        This method does not have access to the class `self` reference, but it
49
        is able to call static methods within this same class.
50
        """
51
        cls.needsInit = True
52

53
    @classmethod
54
    def initClass(cls):
55
        # Open existing FreeCAD document with test geometry
56
        cls.needsInit = False
57
        FreeCAD.ConfigSet("SuppressRecomputeRequiredDialog", "True")
58
        cls.doc = FreeCAD.open(FreeCAD.getHomePath() + "Mod/CAM/Tests/test_profile.fcstd")
59
        FreeCAD.ConfigSet("SuppressRecomputeRequiredDialog", "")
60

61
        # Create Job object, adding geometry objects from file opened above
62
        cls.job = PathJob.Create("Job", [cls.doc.Body], None)
63
        cls.job.GeometryTolerance.Value = 0.001
64
        if FreeCAD.GuiUp:
65
            cls.job.ViewObject.Proxy = PathJobGui.ViewProvider(cls.job.ViewObject)
66

67
        # Instantiate an Profile operation for querying available properties
68
        cls.prototype = PathProfile.Create("Profile")
69
        cls.prototype.Base = [(cls.doc.Body, ["Face18"])]
70
        cls.prototype.Label = "Prototype"
71
        _addViewProvider(cls.prototype)
72

73
        cls.doc.recompute()
74

75
    @classmethod
76
    def tearDownClass(cls):
77
        """tearDownClass()...
78
        This method is called prior to destruction of this test class.  Add code and objects here
79
        that cleanup the test environment after the test() methods in this class have been executed.
80
        This method does not have access to the class `self` reference.  This method
81
        is able to call static methods within this same class.
82
        """
83
        # FreeCAD.Console.PrintMessage("TestPathAdaptive.tearDownClass()\n")
84

85
        # Close geometry document without saving
86
        if not cls.needsInit:
87
            FreeCAD.closeDocument(cls.doc.Name)
88

89
    # Setup and tear down methods called before and after each unit test
90
    def setUp(self):
91
        """setUp()...
92
        This method is called prior to each `test()` method.  Add code and objects here
93
        that are needed for multiple `test()` methods.
94
        """
95
        if self.needsInit:
96
            self.initClass()
97

98
    def tearDown(self):
99
        """tearDown()...
100
        This method is called after each test() method. Add cleanup instructions here.
101
        Such cleanup instructions will likely undo those in the setUp() method.
102
        """
103
        pass
104

105
    # Unit tests
106
    def test00(self):
107
        """test00() Empty test."""
108
        return
109

110
    def test01(self):
111
        """test01() Verify path generated on Face18, outside, with tool compensation."""
112

113
        # Instantiate a Profile operation and set Base Geometry
114
        profile = PathProfile.Create("Profile1")
115
        profile.Base = [(self.doc.Body, ["Face18"])]  # (base, subs_list)
116
        profile.Label = "test01+"
117
        profile.Comment = (
118
            "test01() Verify path generated on Face18, outside, with tool compensation."
119
        )
120

121
        # Set additional operation properties
122
        # setDepthsAndHeights(adaptive)
123
        profile.processCircles = True
124
        profile.processHoles = True
125
        profile.UseComp = True
126
        profile.Direction = "Climb"
127
        _addViewProvider(profile)
128
        self.doc.recompute()
129

130
        moves = getGcodeMoves(profile.Path.Commands, includeRapids=False)
131
        operationMoves = ";  ".join(moves)
132
        # FreeCAD.Console.PrintMessage("test01_moves: " + operationMoves + "\n")
133

134
        expected_moves = (
135
            "G1 X16.47 Y16.47 Z10.0;  G3 I-2.48 J-2.48 K0.0 X13.93 Y17.5 Z10.0;  "
136
            "G1 X-13.93 Y17.5 Z10.0;  G3 I-0.06 J-3.51 K0.0 X-17.5 Y13.93 Z10.0;  "
137
            "G1 X-17.5 Y-13.93 Z10.0;  G3 I3.51 J-0.06 K0.0 X-13.93 Y-17.5 Z10.0;  "
138
            "G1 X13.93 Y-17.5 Z10.0;  G3 I0.06 J3.51 K0.0 X17.5 Y-13.93 Z10.0;  "
139
            "G1 X17.5 Y13.93 Z10.0;  G3 I-3.51 J0.06 K0.0 X16.47 Y16.47 Z10.0;  "
140
            "G1 X23.55 Y23.54 Z10.0;  G2 I-9.55 J-9.54 K0.0 X27.5 Y14.1 Z10.0;  "
141
            "G1 X27.5 Y-14.0 Z10.0;  G2 I-13.5 J0.0 K0.0 X14.1 Y-27.5 Z10.0;  "
142
            "G1 X-14.0 Y-27.5 Z10.0;  G2 I0.0 J13.5 K0.0 X-27.5 Y-14.1 Z10.0;  "
143
            "G1 X-27.5 Y14.0 Z10.0;  G2 I13.5 J-0.0 K0.0 X-14.1 Y27.5 Z10.0;  "
144
            "G1 X14.0 Y27.5 Z10.0;  G2 I-0.0 J-13.5 K0.0 X23.55 Y23.54 Z10.0"
145
        )
146
        self.assertTrue(
147
            expected_moves == operationMoves,
148
            "expected_moves: {}\noperationMoves: {}".format(expected_moves, operationMoves),
149
        )
150

151
    def test02(self):
152
        """test02() Verify path generated on Face18, outside, without compensation."""
153

154
        # Instantiate a Profile operation and set Base Geometry
155
        profile = PathProfile.Create("Profile2")
156
        profile.Base = [(self.doc.Body, ["Face18"])]  # (base, subs_list)
157
        profile.Label = "test02+"
158
        profile.Comment = "test02() Verify path generated on Face18, outside, without compensation."
159

160
        # Set additional operation properties
161
        # setDepthsAndHeights(adaptive)
162
        profile.processCircles = True
163
        profile.processHoles = True
164
        profile.UseComp = False
165
        profile.Direction = "Climb"
166
        _addViewProvider(profile)
167
        self.doc.recompute()
168

169
        moves = getGcodeMoves(profile.Path.Commands, includeRapids=False)
170
        operationMoves = ";  ".join(moves)
171
        # FreeCAD.Console.PrintMessage("test02_moves: " + operationMoves + "\n")
172

173
        expected_moves = (
174
            "G1 X18.24 Y18.24 Z10.0;  G3 I-4.24 J-4.24 K0.0 X14.0 Y20.0 Z10.0;  "
175
            "G1 X-14.0 Y20.0 Z10.0;  G3 I0.0 J-6.0 K0.0 X-20.0 Y14.0 Z10.0;  "
176
            "G1 X-20.0 Y-14.0 Z10.0;  G3 I6.0 J0.0 K0.0 X-14.0 Y-20.0 Z10.0;  "
177
            "G1 X14.0 Y-20.0 Z10.0;  G3 I-0.0 J6.0 K0.0 X20.0 Y-14.0 Z10.0;  "
178
            "G1 X20.0 Y14.0 Z10.0;  G3 I-6.0 J-0.0 K0.0 X18.24 Y18.24 Z10.0;  "
179
            "G1 X21.78 Y21.78 Z10.0;  G2 I-7.78 J-7.78 K0.0 X25.0 Y14.0 Z10.0;  "
180
            "G1 X25.0 Y-14.0 Z10.0;  G2 I-11.0 J0.0 K0.0 X14.0 Y-25.0 Z10.0;  "
181
            "G1 X-14.0 Y-25.0 Z10.0;  G2 I0.0 J11.0 K0.0 X-25.0 Y-14.0 Z10.0;  "
182
            "G1 X-25.0 Y14.0 Z10.0;  G2 I11.0 J-0.0 K0.0 X-14.0 Y25.0 Z10.0;  "
183
            "G1 X14.0 Y25.0 Z10.0;  G2 I-0.0 J-11.0 K0.0 X21.78 Y21.78 Z10.0"
184
        )
185

186
        self.assertTrue(
187
            expected_moves == operationMoves,
188
            "expected_moves: {}\noperationMoves: {}".format(expected_moves, operationMoves),
189
        )
190

191
    def test03(self):
192
        """test03() Verify path generated on Face18, outside,
193
        with compensation and extra offset -radius."""
194

195
        # Instantiate a Profile operation and set Base Geometry
196
        profile = PathProfile.Create("Profile3")
197
        profile.Base = [(self.doc.Body, ["Face18"])]  # (base, subs_list)
198
        profile.Label = "test03+"
199
        profile.Comment = (
200
            "test03() Verify path generated on Face4, " "with compensation and extra offset -radius"
201
        )
202

203
        # Set additional operation properties
204
        # setDepthsAndHeights(adaptive)
205
        profile.processCircles = True
206
        profile.processHoles = True
207
        profile.UseComp = True
208
        profile.Direction = "Climb"
209
        profile.OffsetExtra = -profile.OpToolDiameter / 2.0
210
        _addViewProvider(profile)
211
        self.doc.recompute()
212

213
        moves = getGcodeMoves(profile.Path.Commands, includeRapids=False)
214
        operationMoves = ";  ".join(moves)
215
        # FreeCAD.Console.PrintMessage("test03_moves: " + operationMoves + "\n")
216

217
        expected_moves = (
218
            "G1 X18.24 Y18.24 Z10.0;  G3 I-4.24 J-4.24 K0.0 X14.0 Y20.0 Z10.0;  "
219
            "G1 X-14.0 Y20.0 Z10.0;  G3 I0.0 J-6.0 K0.0 X-20.0 Y14.0 Z10.0;  "
220
            "G1 X-20.0 Y-14.0 Z10.0;  G3 I6.0 J0.0 K0.0 X-14.0 Y-20.0 Z10.0;  "
221
            "G1 X14.0 Y-20.0 Z10.0;  G3 I-0.0 J6.0 K0.0 X20.0 Y-14.0 Z10.0;  "
222
            "G1 X20.0 Y14.0 Z10.0;  G3 I-6.0 J-0.0 K0.0 X18.24 Y18.24 Z10.0;  "
223
            "G1 X21.78 Y21.78 Z10.0;  G2 I-7.78 J-7.78 K0.0 X25.0 Y14.0 Z10.0;  "
224
            "G1 X25.0 Y-14.0 Z10.0;  G2 I-11.0 J0.0 K0.0 X14.0 Y-25.0 Z10.0;  "
225
            "G1 X-14.0 Y-25.0 Z10.0;  G2 I0.0 J11.0 K0.0 X-25.0 Y-14.0 Z10.0;  "
226
            "G1 X-25.0 Y14.0 Z10.0;  G2 I11.0 J-0.0 K0.0 X-14.0 Y25.0 Z10.0;  "
227
            "G1 X14.0 Y25.0 Z10.0;  G2 I-0.0 J-11.0 K0.0 X21.78 Y21.78 Z10.0"
228
        )
229

230
        self.assertTrue(
231
            expected_moves == operationMoves,
232
            "expected_moves: {}\noperationMoves: {}".format(expected_moves, operationMoves),
233
        )
234

235

236
def _addViewProvider(profileOp):
237
    if FreeCAD.GuiUp:
238
        PathOpGui = PathProfileGui.PathOpGui
239
        cmdRes = PathProfileGui.Command.res
240
        profileOp.ViewObject.Proxy = PathOpGui.ViewProvider(profileOp.ViewObject, cmdRes)
241

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.