FreeCAD

Форк
0
634 строки · 28.2 Кб
1
# ***************************************************************************
2
# *   (c) 2009, 2010 Yorik van Havre <yorik@uncreated.net>                  *
3
# *   (c) 2009, 2010 Ken Cline <cline@frii.com>                             *
4
# *   (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de>           *
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
# *   FreeCAD 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 FreeCAD; if not, write to the Free Software        *
21
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
22
# *   USA                                                                   *
23
# *                                                                         *
24
# ***************************************************************************
25
"""Provides GUI tools to create circular arc objects."""
26
## @package gui_arcs
27
# \ingroup draftguitools
28
# \brief Provides GUI tools to create circular arc objects.
29

30
## \addtogroup draftguitools
31
# @{
32
import math
33
from PySide.QtCore import QT_TRANSLATE_NOOP
34

35
import FreeCAD as App
36
import FreeCADGui as Gui
37
import Draft
38
import Draft_rc
39
import DraftVecUtils
40
from FreeCAD import Units as U
41
from draftguitools import gui_base
42
from draftguitools import gui_base_original
43
from draftguitools import gui_tool_utils
44
from draftguitools import gui_trackers as trackers
45
from draftutils import params
46
from draftutils import utils
47
from draftutils.messages import _err, _toolmsg
48
from draftutils.translate import translate
49

50
# The module is used to prevent complaints from code checkers (flake8)
51
True if Draft_rc.__name__ else False
52

53

54
class Arc(gui_base_original.Creator):
55
    """Gui command for the Circular Arc tool."""
56

57
    def __init__(self):
58
        super().__init__()
59
        self.closedCircle = False
60
        self.featureName = "Arc"
61

62
    def GetResources(self):
63
        """Set icon, menu and tooltip."""
64
        return {'Pixmap': 'Draft_Arc',
65
                'Accel': "A, R",
66
                'MenuText': QT_TRANSLATE_NOOP("Draft_Arc", "Arc"),
67
                'ToolTip': QT_TRANSLATE_NOOP("Draft_Arc", "Creates a circular arc by a center point and a radius.\nCTRL to snap, SHIFT to constrain.")}
68

69
    def Activated(self):
70
        """Execute when the command is called."""
71
        super().Activated(name=self.featureName)
72
        if self.ui:
73
            self.step = 0
74
            self.center = None
75
            self.rad = None
76
            self.angle = 0  # angle inscribed by arc
77
            self.tangents = []
78
            self.tanpoints = []
79
            if self.featureName == "Arc":
80
                self.ui.arcUi()
81
            else:
82
                self.ui.circleUi()
83
            self.altdown = False
84
            self.ui.sourceCmd = self
85
            self.linetrack = trackers.lineTracker(dotted=True)
86
            self.arctrack = trackers.arcTracker()
87
            self.call = self.view.addEventCallback("SoEvent", self.action)
88
            _toolmsg(translate("draft", "Pick center point"))
89

90
    def finish(self, cont=False):
91
        """Terminate the operation.
92

93
        Parameters
94
        ----------
95
        cont: bool or None, optional
96
            Restart (continue) the command if `True`, or if `None` and
97
            `ui.continueMode` is `True`.
98
        """
99
        self.end_callbacks(self.call)
100
        if self.ui:
101
            self.linetrack.finalize()
102
            self.arctrack.finalize()
103
        super().finish()
104
        if cont or (cont is None and self.ui and self.ui.continueMode):
105
            self.Activated()
106

107
    def updateAngle(self, angle):
108
        """Update the angle with the new value."""
109
        # previous absolute angle
110
        lastangle = self.firstangle + self.angle
111
        if lastangle <= -2 * math.pi:
112
            lastangle += 2 * math.pi
113
        if lastangle >= 2 * math.pi:
114
            lastangle -= 2 * math.pi
115
        # compute delta = change in angle:
116
        d0 = angle - lastangle
117
        d1 = d0 + 2 * math.pi
118
        d2 = d0 - 2 * math.pi
119
        if abs(d0) < min(abs(d1), abs(d2)):
120
            delta = d0
121
        elif abs(d1) < abs(d2):
122
            delta = d1
123
        else:
124
            delta = d2
125
        newangle = self.angle + delta
126
        # normalize angle, preserving direction
127
        if newangle >= 2 * math.pi:
128
            newangle -= 2 * math.pi
129
        if newangle <= -2 * math.pi:
130
            newangle += 2 * math.pi
131
        self.angle = newangle
132

133
    def action(self, arg):
134
        """Handle the 3D scene events.
135

136
        This is installed as an EventCallback in the Inventor view.
137

138
        Parameters
139
        ----------
140
        arg: dict
141
            Dictionary with strings that indicates the type of event received
142
            from the 3D view.
143
        """
144
        import DraftGeomUtils
145

146
        if arg["Type"] == "SoKeyboardEvent":
147
            if arg["Key"] == "ESCAPE":
148
                self.finish()
149
        elif arg["Type"] == "SoLocation2Event":  # mouse movement detection
150
            self.point, ctrlPoint, info = gui_tool_utils.getPoint(self, arg)
151
            # this is to make sure radius is what you see on screen
152
            if self.center and DraftVecUtils.dist(self.point, self.center) > 0:
153
                viewdelta = DraftVecUtils.project(self.point.sub(self.center),
154
                                                  self.wp.axis)
155
                if not DraftVecUtils.isNull(viewdelta):
156
                    self.point = self.point.add(viewdelta.negative())
157
            if self.step == 0:  # choose center
158
                if gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()):
159
                    if not self.altdown:
160
                        self.altdown = True
161
                        self.ui.switchUi(True)
162
                    else:
163
                        if self.altdown:
164
                            self.altdown = False
165
                            self.ui.switchUi(False)
166
            elif self.step == 1:  # choose radius
167
                if len(self.tangents) == 2:
168
                    cir = DraftGeomUtils.circleFrom2tan1pt(self.tangents[0],
169
                                                           self.tangents[1],
170
                                                           self.point)
171
                    _c = DraftGeomUtils.findClosestCircle(self.point, cir)
172
                    self.center = _c.Center
173
                    self.arctrack.setCenter(self.center)
174
                elif self.tangents and self.tanpoints:
175
                    cir = DraftGeomUtils.circleFrom1tan2pt(self.tangents[0],
176
                                                           self.tanpoints[0],
177
                                                           self.point)
178
                    _c = DraftGeomUtils.findClosestCircle(self.point, cir)
179
                    self.center = _c.Center
180
                    self.arctrack.setCenter(self.center)
181
                if gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()):
182
                    if not self.altdown:
183
                        self.altdown = True
184
                    if info:
185
                        ob = self.doc.getObject(info['Object'])
186
                        num = int(info['Component'].lstrip('Edge')) - 1
187
                        ed = ob.Shape.Edges[num]
188
                        if len(self.tangents) == 2:
189
                            cir = DraftGeomUtils.circleFrom3tan(self.tangents[0],
190
                                                                self.tangents[1],
191
                                                                ed)
192
                            cl = DraftGeomUtils.findClosestCircle(self.point, cir)
193
                            self.center = cl.Center
194
                            self.rad = cl.Radius
195
                            self.arctrack.setCenter(self.center)
196
                        else:
197
                            self.rad = self.center.add(DraftGeomUtils.findDistance(self.center, ed).sub(self.center)).Length
198
                    else:
199
                        self.rad = DraftVecUtils.dist(self.point, self.center)
200
                else:
201
                    if self.altdown:
202
                        self.altdown = False
203
                    self.rad = DraftVecUtils.dist(self.point, self.center)
204
                self.ui.setRadiusValue(self.rad, "Length")
205
                self.arctrack.setRadius(self.rad)
206
                self.linetrack.p1(self.center)
207
                self.linetrack.p2(self.point)
208
                self.linetrack.on()
209
            elif (self.step == 2):  # choose first angle
210
                currentrad = DraftVecUtils.dist(self.point, self.center)
211
                if currentrad != 0:
212
                    angle = DraftVecUtils.angle(self.wp.u, self.point.sub(self.center), self.wp.axis)
213
                else:
214
                    angle = 0
215
                self.linetrack.p2(DraftVecUtils.scaleTo(self.point.sub(self.center), self.rad).add(self.center))
216
                self.ui.setRadiusValue(math.degrees(angle), unit="Angle")
217
                self.firstangle = angle
218
            else:
219
                # choose second angle
220
                currentrad = DraftVecUtils.dist(self.point, self.center)
221
                if currentrad != 0:
222
                    angle = DraftVecUtils.angle(self.wp.u, self.point.sub(self.center), self.wp.axis)
223
                else:
224
                    angle = 0
225
                self.linetrack.p2(DraftVecUtils.scaleTo(self.point.sub(self.center), self.rad).add(self.center))
226
                self.updateAngle(angle)
227
                self.ui.setRadiusValue(math.degrees(self.angle), unit="Angle")
228
                self.arctrack.setApertureAngle(self.angle)
229

230
            gui_tool_utils.redraw3DView()
231

232
        elif arg["Type"] == "SoMouseButtonEvent":  # mouse click
233
            if arg["State"] == "DOWN" and arg["Button"] == "BUTTON1":
234
                if self.point:
235
                    if self.step == 0:  # choose center
236
                        if not self.support:
237
                            gui_tool_utils.getSupport(arg)
238
                            (self.point,
239
                             ctrlPoint, info) = gui_tool_utils.getPoint(self, arg)
240
                        if gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()):
241
                            snapped = self.view.getObjectInfo((arg["Position"][0],
242
                                                               arg["Position"][1]))
243
                            if snapped:
244
                                ob = self.doc.getObject(snapped['Object'])
245
                                num = int(snapped['Component'].lstrip('Edge')) - 1
246
                                ed = ob.Shape.Edges[num]
247
                                self.tangents.append(ed)
248
                                if len(self.tangents) == 2:
249
                                    self.arctrack.on()
250
                                    self.ui.radiusUi()
251
                                    self.step = 1
252
                                    self.ui.setNextFocus()
253
                                    self.linetrack.on()
254
                                    _toolmsg(translate("draft", "Pick radius"))
255
                        else:
256
                            if len(self.tangents) == 1:
257
                                self.tanpoints.append(self.point)
258
                            else:
259
                                self.center = self.point
260
                                self.node = [self.point]
261
                                self.arctrack.setCenter(self.center)
262
                                self.linetrack.p1(self.center)
263
                                self.linetrack.p2(self.view.getPoint(arg["Position"][0],
264
                                                                     arg["Position"][1]))
265
                            self.arctrack.on()
266
                            self.ui.radiusUi()
267
                            self.step = 1
268
                            self.ui.setNextFocus()
269
                            self.linetrack.on()
270
                            _toolmsg(translate("draft", "Pick radius"))
271
                            if self.planetrack:
272
                                self.planetrack.set(self.point)
273
                    elif self.step == 1:  # choose radius
274
                        if self.closedCircle:
275
                            self.drawArc()
276
                        else:
277
                            self.ui.labelRadius.setText(translate("draft", "Start angle"))
278
                            self.ui.radiusValue.setToolTip(translate("draft", "Start angle"))
279
                            self.ui.radiusValue.setText(U.Quantity(0, U.Angle).UserString)
280
                            self.linetrack.p1(self.center)
281
                            self.linetrack.on()
282
                            self.step = 2
283
                            _toolmsg(translate("draft", "Pick start angle"))
284
                    elif self.step == 2:  # choose first angle
285
                        self.ui.labelRadius.setText(translate("draft", "Aperture angle"))
286
                        self.ui.radiusValue.setToolTip(translate("draft", "Aperture angle"))
287
                        ang_offset = DraftVecUtils.angle(self.wp.u,
288
                                                         self.arctrack.getDeviation(),
289
                                                         self.wp.axis)
290
                        self.arctrack.setStartAngle(self.firstangle - ang_offset)
291
                        self.step = 3
292
                        _toolmsg(translate("draft", "Pick aperture"))
293
                    else:  # choose second angle
294
                        self.step = 4
295
                        self.drawArc()
296

297
    def drawArc(self):
298
        """Actually draw the arc object."""
299
        rot, sup, pts, fil = self.getStrings()
300
        if self.closedCircle:
301
            try:
302
                # The command to run is built as a series of text strings
303
                # to be committed through the `draftutils.todo.ToDo` class.
304
                Gui.addModule("Draft")
305
                if params.get_param("UsePartPrimitives"):
306
                    # Insert a Part::Primitive object
307
                    _base = DraftVecUtils.toString(self.center)
308
                    _cmd = 'FreeCAD.ActiveDocument.'
309
                    _cmd += 'addObject("Part::Circle", "Circle")'
310
                    _cmd_list = ['circle = ' + _cmd,
311
                                 'circle.Radius = ' + str(self.rad),
312
                                 'pl = FreeCAD.Placement()',
313
                                 'pl.Rotation.Q = ' + rot,
314
                                 'pl.Base = ' + _base,
315
                                 'circle.Placement = pl',
316
                                 'Draft.autogroup(circle)',
317
                                 'Draft.select(circle)',
318
                                 'FreeCAD.ActiveDocument.recompute()']
319
                    self.commit(translate("draft", "Create Circle (Part)"),
320
                                _cmd_list)
321
                else:
322
                    # Insert a Draft circle
323
                    _base = DraftVecUtils.toString(self.center)
324
                    _cmd = 'Draft.make_circle'
325
                    _cmd += '('
326
                    _cmd += 'radius=' + str(self.rad) + ', '
327
                    _cmd += 'placement=pl, '
328
                    _cmd += 'face=' + fil + ', '
329
                    _cmd += 'support=' + sup
330
                    _cmd += ')'
331
                    _cmd_list = ['pl=FreeCAD.Placement()',
332
                                 'pl.Rotation.Q=' + rot,
333
                                 'pl.Base=' + _base,
334
                                 'circle = ' + _cmd,
335
                                 'Draft.autogroup(circle)',
336
                                 'FreeCAD.ActiveDocument.recompute()']
337
                    self.commit(translate("draft", "Create Circle"),
338
                                _cmd_list)
339
            except Exception:
340
                _err("Draft: error delaying commit")
341
        else:
342
            # Not a closed circle, therefore a circular arc
343
            sta = math.degrees(self.firstangle)
344
            end = math.degrees(self.firstangle + self.angle)
345
            if end < sta:
346
                sta, end = end, sta
347
            sta %= 360
348
            end %= 360
349

350
            try:
351
                Gui.addModule("Draft")
352
                if params.get_param("UsePartPrimitives"):
353
                    # Insert a Part::Primitive object
354
                    _base = DraftVecUtils.toString(self.center)
355
                    _cmd = 'FreeCAD.ActiveDocument.'
356
                    _cmd += 'addObject("Part::Circle", "Circle")'
357
                    _cmd_list = ['circle = ' + _cmd,
358
                                 'circle.Radius = ' + str(self.rad),
359
                                 'circle.Angle1 = ' + str(sta),
360
                                 'circle.Angle2 = ' + str(end),
361
                                 'pl = FreeCAD.Placement()',
362
                                 'pl.Rotation.Q = ' + rot,
363
                                 'pl.Base = ' + _base,
364
                                 'circle.Placement = pl',
365
                                 'Draft.autogroup(circle)',
366
                                 'Draft.select(circle)',
367
                                 'FreeCAD.ActiveDocument.recompute()']
368
                    self.commit(translate("draft", "Create Arc (Part)"),
369
                                _cmd_list)
370
                else:
371
                    # Insert a Draft circle
372
                    _base = DraftVecUtils.toString(self.center)
373
                    _cmd = 'Draft.make_circle'
374
                    _cmd += '('
375
                    _cmd += 'radius=' + str(self.rad) + ', '
376
                    _cmd += 'placement=pl, '
377
                    _cmd += 'face=' + fil + ', '
378
                    _cmd += 'startangle=' + str(sta) + ', '
379
                    _cmd += 'endangle=' + str(end) + ', '
380
                    _cmd += 'support=' + sup
381
                    _cmd += ')'
382
                    _cmd_list = ['pl = FreeCAD.Placement()',
383
                                 'pl.Rotation.Q = ' + rot,
384
                                 'pl.Base = ' + _base,
385
                                 'circle = ' + _cmd,
386
                                 'Draft.autogroup(circle)',
387
                                 'FreeCAD.ActiveDocument.recompute()']
388
                    self.commit(translate("draft", "Create Arc"),
389
                                _cmd_list)
390
            except Exception:
391
                _err("Draft: error delaying commit")
392

393
        # Finalize full circle or circular arc
394
        self.finish(cont=None)
395

396
    def numericInput(self, numx, numy, numz):
397
        """Validate the entry fields in the user interface.
398

399
        This function is called by the toolbar or taskpanel interface
400
        when valid x, y, and z have been entered in the input fields.
401
        """
402
        self.center = App.Vector(numx, numy, numz)
403
        self.node = [self.center]
404
        self.arctrack.setCenter(self.center)
405
        self.arctrack.on()
406
        self.ui.radiusUi()
407
        self.step = 1
408
        self.ui.setNextFocus()
409
        _toolmsg(translate("draft", "Pick radius"))
410

411
    def numericRadius(self, rad):
412
        """Validate the entry radius in the user interface.
413

414
        This function is called by the toolbar or taskpanel interface
415
        when a valid radius has been entered in the input field.
416
        """
417
        import DraftGeomUtils
418

419
        if self.step == 1:
420
            self.rad = rad
421
            if len(self.tangents) == 2:
422
                cir = DraftGeomUtils.circleFrom2tan1rad(self.tangents[0],
423
                                                        self.tangents[1],
424
                                                        rad)
425
                if self.center:
426
                    _c = DraftGeomUtils.findClosestCircle(self.center, cir)
427
                    self.center = _c.Center
428
                else:
429
                    self.center = cir[-1].Center
430
            elif self.tangents and self.tanpoints:
431
                cir = DraftGeomUtils.circleFrom1tan1pt1rad(self.tangents[0],
432
                                                           self.tanpoints[0],
433
                                                           rad)
434
                if self.center:
435
                    _c = DraftGeomUtils.findClosestCircle(self.center, cir)
436
                    self.center = _c.Center
437
                else:
438
                    self.center = cir[-1].Center
439
            if self.closedCircle:
440
                self.drawArc()
441
            else:
442
                self.step = 2
443
                self.arctrack.setCenter(self.center)
444
                self.ui.labelRadius.setText(translate("draft", "Start angle"))
445
                self.ui.radiusValue.setToolTip(translate("draft", "Start angle"))
446
                self.linetrack.p1(self.center)
447
                self.linetrack.on()
448
                self.ui.radiusValue.setText("")
449
                self.ui.radiusValue.setFocus()
450
                _toolmsg(translate("draft", "Pick start angle"))
451
        elif self.step == 2:
452
            self.ui.labelRadius.setText(translate("draft", "Aperture angle"))
453
            self.ui.radiusValue.setToolTip(translate("draft", "Aperture angle"))
454
            self.firstangle = math.radians(rad)
455
            ang_offset = DraftVecUtils.angle(self.wp.u,
456
                                             self.arctrack.getDeviation(),
457
                                             self.wp.axis)
458
            self.arctrack.setStartAngle(self.firstangle - ang_offset)
459
            self.step = 3
460
            self.ui.radiusValue.setText("")
461
            self.ui.radiusValue.setFocus()
462
            _toolmsg(translate("draft", "Pick aperture angle"))
463
        else:
464
            self.updateAngle(rad)
465
            self.angle = math.radians(rad)
466
            self.step = 4
467
            self.drawArc()
468

469

470
Gui.addCommand('Draft_Arc', Arc())
471

472

473
class Arc_3Points(gui_base.GuiCommandBase):
474
    """GuiCommand for the Draft_Arc_3Points tool."""
475

476
    def GetResources(self):
477
        """Set icon, menu and tooltip."""
478
        return {'Pixmap': "Draft_Arc_3Points",
479
                'Accel': "A,T",
480
                'MenuText': QT_TRANSLATE_NOOP("Draft_Arc_3Points", "Arc by 3 points"),
481
                'ToolTip': QT_TRANSLATE_NOOP("Draft_Arc_3Points", "Creates a circular arc by picking 3 points.\nCTRL to snap, SHIFT to constrain.")}
482

483
    def Activated(self):
484
        """Execute when the command is called."""
485
        if App.activeDraftCommand:
486
            App.activeDraftCommand.finish()
487
        App.activeDraftCommand = self
488
        self.featureName = "Arc_3Points"
489

490
        # Reset the values
491
        self.points = []
492
        self.normal = None
493
        self.tracker = trackers.arcTracker()
494
        self.tracker.autoinvert = False
495

496
        # Set up the working plane and launch the Snapper
497
        # with the indicated callbacks: one for when the user clicks
498
        # on the 3D view, and another for when the user moves the pointer.
499
        import WorkingPlane
500
        WorkingPlane.get_working_plane()
501

502
        Gui.Snapper.getPoint(callback=self.getPoint,
503
                             movecallback=self.drawArc)
504
        Gui.Snapper.ui.sourceCmd = self
505
        Gui.Snapper.ui.setTitle(title=translate("draft", "Arc by 3 points"),
506
                                icon="Draft_Arc_3Points")
507
        Gui.Snapper.ui.continueCmd.show()
508

509
    def getPoint(self, point, info):
510
        """Get the point by clicking on the 3D view.
511

512
        Every time the user clicks on the 3D view this method is run.
513
        In this case, a point is appended to the list of points,
514
        and the tracker is updated.
515
        The object is finally created when three points are picked.
516

517
        Parameters
518
        ----------
519
        point: Base::Vector
520
            The point selected in the 3D view.
521

522
        info: str
523
            Some information obtained about the point passed by the Snapper.
524
        """
525
        # If there is not point, the command was cancelled
526
        # so the command exits.
527
        if not point:
528
            return None
529

530
        # Avoid adding the same point twice
531
        if point not in self.points:
532
            self.points.append(point)
533

534
        if len(self.points) < 3:
535
            # If one or two points were picked, set up again the Snapper
536
            # to get further points, but update the `last` property
537
            # with the last selected point.
538
            #
539
            # When two points are selected then we can turn on
540
            # the arc tracker to show the preview of the final curve.
541
            if len(self.points) == 2:
542
                self.tracker.on()
543
            Gui.Snapper.getPoint(last=self.points[-1],
544
                                 callback=self.getPoint,
545
                                 movecallback=self.drawArc)
546
            Gui.Snapper.ui.sourceCmd = self
547
            Gui.Snapper.ui.setTitle(title=translate("draft", "Arc by 3 points"),
548
                                    icon="Draft_Arc_3Points")
549
            Gui.Snapper.ui.continueCmd.show()
550

551
        else:
552
            # If three points were already picked in the 3D view
553
            # proceed with creating the final object.
554
            # Draw a simple `Part::Feature` if the parameter is `True`.
555
            Gui.addModule("Draft")
556
            _cmd = "Draft.make_arc_3points(["
557
            _cmd += "FreeCAD." + str(self.points[0])
558
            _cmd += ", FreeCAD." + str(self.points[1])
559
            _cmd += ", FreeCAD." + str(self.points[2])
560
            _cmd += "], primitive=" + str(params.get_param("UsePartPrimitives")) + ")"
561
            _cmd_list = ["circle = " + _cmd,
562
                         "Draft.autogroup(circle)"]
563
            if params.get_param("UsePartPrimitives"):
564
                _cmd_list.append("Draft.select(circle)")
565
            _cmd_list.append("FreeCAD.ActiveDocument.recompute()")
566
            self.commit(translate("draft", "Create Arc by 3 points"), _cmd_list)
567
            self.finish(cont=None)
568

569
    def drawArc(self, point, info):
570
        """Draw preview arc when we move the pointer in the 3D view.
571

572
        It uses the `gui_trackers.arcTracker.setBy3Points` method.
573

574
        Parameters
575
        ----------
576
        point: Base::Vector
577
            The dynamic point passed by the callback
578
            as we move the pointer in the 3D view.
579

580
        info: str
581
            Some information obtained from the point by the Snapper.
582
        """
583
        if len(self.points) == 2:
584
            if point.sub(self.points[1]).Length > 0.001:
585
                self.tracker.setBy3Points(self.points[0],
586
                                          self.points[1],
587
                                          point)
588

589
    def finish(self, cont=False):
590
        """Terminate the operation.
591

592
        Parameters
593
        ----------
594
        cont: bool or None, optional
595
            Restart (continue) the command if `True`, or if `None` and
596
            `ui.continueMode` is `True`.
597
        """
598
        App.activeDraftCommand = None
599
        self.tracker.finalize()
600
        super().finish()
601
        if cont or (cont is None and Gui.Snapper.ui and Gui.Snapper.ui.continueMode):
602
            self.Activated()
603

604

605
Draft_Arc_3Points = Arc_3Points
606
Gui.addCommand('Draft_Arc_3Points', Arc_3Points())
607

608

609
class ArcGroup:
610
    """Gui Command group for the Arc tools."""
611

612
    def GetResources(self):
613
        """Set icon, menu and tooltip."""
614
        return {'MenuText': QT_TRANSLATE_NOOP("Draft_ArcTools", "Arc tools"),
615
                'ToolTip': QT_TRANSLATE_NOOP("Draft_ArcTools", "Create various types of circular arcs.")}
616

617
    def GetCommands(self):
618
        """Return a tuple of commands in the group."""
619
        return ('Draft_Arc', 'Draft_Arc_3Points')
620

621
    def IsActive(self):
622
        """Return True when this command should be available.
623

624
        It is `True` when there is a document.
625
        """
626
        if Gui.ActiveDocument:
627
            return True
628
        else:
629
            return False
630

631

632
Gui.addCommand('Draft_ArcTools', ArcGroup())
633

634
## @}
635

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

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

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

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