示例#1
0
 def findPivotIntersection(self, pivot, pivotEdge, edge, refPt, d, color):
     PathLog.track("(%.2f, %.2f)^%.2f  - [(%.2f, %.2f), (%.2f, %.2f)]" %
                   (pivotEdge.Curve.Center.x, pivotEdge.Curve.Center.y,
                    pivotEdge.Curve.Radius, edge.Vertexes[0].Point.x,
                    edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x,
                    edge.Vertexes[1].Point.y))
     ppt = None
     pptDistance = 0
     for pt in DraftGeomUtils.findIntersection(edge, pivotEdge, dts=False):
         #debugMarker(pt, "pti.%d-%s.in" % (self.boneId, d), color, 0.2)
         distance = (pt - refPt).Length
         PathLog.debug("        -->  (%.2f, %.2f): %.2f" %
                       (pt.x, pt.y, distance))
         if not ppt or pptDistance < distance:
             ppt = pt
             pptDistance = distance
     if not ppt:
         tangent = DraftGeomUtils.findDistance(pivot, edge)
         if tangent:
             PathLog.debug("Taking tangent as intersect %s" % tangent)
             ppt = pivot + tangent
         else:
             PathLog.debug("Taking chord start as intersect %s" %
                           inChordStart)
             ppt = inChord.Start
         #debugMarker(ppt, "ptt.%d-%s.in" % (self.boneId, d), color, 0.2)
         PathLog.debug("        -->  (%.2f, %.2f)" % (ppt.x, ppt.y))
     return ppt
示例#2
0
 def calc(self):
     import Part
     if (self.p1 != None) and (self.p2 != None):
         points = [DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True),\
                       DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True)]
         if self.p3 != None:
             p1 = self.p1
             p4 = self.p2
             if DraftVecUtils.equals(p1, p4):
                 proj = None
             else:
                 base = Part.LineSegment(p1, p4).toShape()
                 proj = DraftGeomUtils.findDistance(self.p3, base)
             if not proj:
                 p2 = p1
                 p3 = p4
             else:
                 p2 = p1.add(proj.negative())
                 p3 = p4.add(proj.negative())
             points = [
                 DraftVecUtils.tup(p1),
                 DraftVecUtils.tup(p2),
                 DraftVecUtils.tup(p3),
                 DraftVecUtils.tup(p4)
             ]
         self.coords.point.setValues(0, 4, points)
示例#3
0
    def calc(self):
        import Part

        if (self.p1 != None) and (self.p2 != None):
            points = [
                DraftVecUtils.tup(self.p1, True),
                DraftVecUtils.tup(self.p2, True),
                DraftVecUtils.tup(self.p1, True),
                DraftVecUtils.tup(self.p2, True),
            ]
            if self.p3 != None:
                p1 = self.p1
                p4 = self.p2
                if DraftVecUtils.equals(p1, p4):
                    proj = None
                else:
                    base = Part.Line(p1, p4).toShape()
                    proj = DraftGeomUtils.findDistance(self.p3, base)
                if not proj:
                    p2 = p1
                    p3 = p4
                else:
                    p2 = p1.add(proj.negative())
                    p3 = p4.add(proj.negative())
                points = [DraftVecUtils.tup(p1), DraftVecUtils.tup(p2), DraftVecUtils.tup(p3), DraftVecUtils.tup(p4)]
            self.coords.point.setValues(0, 4, points)
示例#4
0
 def findPivotIntersection(self, pivot, pivotEdge, edge, refPt, d, color):
     debugPrint(
         "Intersection (%.2f, %.2f)^%.2f  - [(%.2f, %.2f), (%.2f, %.2f)]"
         % (
             pivotEdge.Curve.Center.x,
             pivotEdge.Curve.Center.y,
             pivotEdge.Curve.Radius,
             edge.Vertexes[0].Point.x,
             edge.Vertexes[0].Point.y,
             edge.Vertexes[1].Point.x,
             edge.Vertexes[1].Point.y,
         )
     )
     ppt = None
     pptDistance = 0
     for pt in DraftGeomUtils.findIntersection(edge, pivotEdge, dts=False):
         # debugMarker(pt, "pti.%d-%s.in" % (self.boneId, d), color, 0.2)
         distance = (pt - refPt).Length
         debugPrint("        -->  (%.2f, %.2f): %.2f" % (pt.x, pt.y, distance))
         if not ppt or pptDistance < distance:
             ppt = pt
             pptDistance = distance
     if not ppt:
         tangent = DraftGeomUtils.findDistance(pivot, edge)
         if tangent:
             debugPrint("Taking tangent as intersect %s" % tangent)
             ppt = pivot + tangent
         else:
             debugPrint("Taking chord start as intersect %s" % inChordStart)
             ppt = inChord.Start
         # debugMarker(ppt, "ptt.%d-%s.in" % (self.boneId, d), color, 0.2)
         debugPrint("        -->  (%.2f, %.2f)" % (ppt.x, ppt.y))
     return ppt
示例#5
0
文件: fCmd.py 项目: vocx-fc/dodo
def rotjoinTheBeam(beam=None, e1=None, e2=None):
    if not (beam and e1 and e2):
        beam = beams()[1]
        e1, e2 = edges()
    rot = FreeCAD.Rotation(e2.tangentAt(0), e1.tangentAt(0))
    dist = dgu.findDistance(beam.Placement.Base, e1)
    delta = beam.Placement.Base - e2.CenterOfMass
    beam.Placement.Rotation = rot.multiply(beam.Placement.Rotation)
    beam.Placement.move(rounded(dist + rot.multVec(delta)))
示例#6
0
def rotjoinTheBeam(beam=None,e1=None,e2=None):
  if not (beam and e1 and e2):
    beam=beams()[1]
    e1,e2=edges()
  rot=FreeCAD.Rotation(e2.tangentAt(0),e1.tangentAt(0))
  dist=dgu.findDistance(beam.Placement.Base,e1)
  delta=beam.Placement.Base-e2.CenterOfMass
  beam.Placement.Rotation=rot.multiply(beam.Placement.Rotation)
  beam.Placement.move(rounded(dist+rot.multVec(delta)))
示例#7
0
    def updateData(self, obj, prop):
        """called when the base object is changed"""
        import DraftGui
        if prop in ["Start", "End", "Dimline", "Direction"]:

            if obj.Start == obj.End:
                return

            if not hasattr(self, "node"):
                return

            import Part, DraftGeomUtils
            from pivy import coin

            # calculate the 4 points
            self.p1 = obj.Start
            self.p4 = obj.End
            base = None
            if hasattr(obj, "Direction"):
                if not DraftVecUtils.isNull(obj.Direction):
                    v2 = self.p1.sub(obj.Dimline)
                    v3 = self.p4.sub(obj.Dimline)
                    v2 = DraftVecUtils.project(v2, obj.Direction)
                    v3 = DraftVecUtils.project(v3, obj.Direction)
                    self.p2 = obj.Dimline.add(v2)
                    self.p3 = obj.Dimline.add(v3)
                    if DraftVecUtils.equals(self.p2, self.p3):
                        base = None
                        proj = None
                    else:
                        base = Part.LineSegment(self.p2, self.p3).toShape()
                        proj = DraftGeomUtils.findDistance(self.p1, base)
                        if proj:
                            proj = proj.negative()
            if not base:
                if DraftVecUtils.equals(self.p1, self.p4):
                    base = None
                    proj = None
                else:
                    base = Part.LineSegment(self.p1, self.p4).toShape()
                    proj = DraftGeomUtils.findDistance(obj.Dimline, base)
                if proj:
                    self.p2 = self.p1.add(proj.negative())
                    self.p3 = self.p4.add(proj.negative())
                else:
                    self.p2 = self.p1
                    self.p3 = self.p4
            if proj:
                if hasattr(obj.ViewObject, "ExtLines") and hasattr(
                        obj.ViewObject, "ScaleMultiplier"):
                    dmax = obj.ViewObject.ExtLines.Value * obj.ViewObject.ScaleMultiplier
                    if dmax and (proj.Length > dmax):
                        if (dmax > 0):
                            self.p1 = self.p2.add(
                                DraftVecUtils.scaleTo(proj, dmax))
                            self.p4 = self.p3.add(
                                DraftVecUtils.scaleTo(proj, dmax))
                        else:
                            rest = proj.Length + dmax
                            self.p1 = self.p2.add(
                                DraftVecUtils.scaleTo(proj, rest))
                            self.p4 = self.p3.add(
                                DraftVecUtils.scaleTo(proj, rest))
            else:
                proj = (self.p3.sub(self.p2)).cross(App.Vector(0, 0, 1))

            # calculate the arrows positions
            self.trans1.translation.setValue((self.p2.x, self.p2.y, self.p2.z))
            self.coord1.point.setValue((self.p2.x, self.p2.y, self.p2.z))
            self.trans2.translation.setValue((self.p3.x, self.p3.y, self.p3.z))
            self.coord2.point.setValue((self.p3.x, self.p3.y, self.p3.z))

            # calculate dimension and extension lines overshoots positions
            self.transDimOvershoot1.translation.setValue(
                (self.p2.x, self.p2.y, self.p2.z))
            self.transDimOvershoot2.translation.setValue(
                (self.p3.x, self.p3.y, self.p3.z))
            self.transExtOvershoot1.translation.setValue(
                (self.p2.x, self.p2.y, self.p2.z))
            self.transExtOvershoot2.translation.setValue(
                (self.p3.x, self.p3.y, self.p3.z))

            # calculate the text position and orientation
            if hasattr(obj, "Normal"):
                if DraftVecUtils.isNull(obj.Normal):
                    if proj:
                        norm = (self.p3.sub(self.p2).cross(proj)).negative()
                    else:
                        norm = App.Vector(0, 0, 1)
                else:
                    norm = App.Vector(obj.Normal)
            else:
                if proj:
                    norm = (self.p3.sub(self.p2).cross(proj)).negative()
                else:
                    norm = App.Vector(0, 0, 1)
            if not DraftVecUtils.isNull(norm):
                norm.normalize()
            u = self.p3.sub(self.p2)
            u.normalize()
            v1 = norm.cross(u)
            rot1 = App.Placement(DraftVecUtils.getPlaneRotation(
                u, v1, norm)).Rotation.Q
            self.transDimOvershoot1.rotation.setValue(
                (rot1[0], rot1[1], rot1[2], rot1[3]))
            self.transDimOvershoot2.rotation.setValue(
                (rot1[0], rot1[1], rot1[2], rot1[3]))
            if hasattr(obj.ViewObject, "FlipArrows"):
                if obj.ViewObject.FlipArrows:
                    u = u.negative()
            v2 = norm.cross(u)
            rot2 = App.Placement(DraftVecUtils.getPlaneRotation(
                u, v2, norm)).Rotation.Q
            self.trans1.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3]))
            self.trans2.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3]))
            if self.p1 != self.p2:
                u3 = self.p1.sub(self.p2)
                u3.normalize()
                v3 = norm.cross(u3)
                rot3 = App.Placement(
                    DraftVecUtils.getPlaneRotation(u3, v3, norm)).Rotation.Q
                self.transExtOvershoot1.rotation.setValue(
                    (rot3[0], rot3[1], rot3[2], rot3[3]))
                self.transExtOvershoot2.rotation.setValue(
                    (rot3[0], rot3[1], rot3[2], rot3[3]))
            if hasattr(obj.ViewObject, "TextSpacing") and hasattr(
                    obj.ViewObject, "ScaleMultiplier"):
                ts = obj.ViewObject.TextSpacing.Value * obj.ViewObject.ScaleMultiplier
                offset = DraftVecUtils.scaleTo(v1, ts)
            else:
                offset = DraftVecUtils.scaleTo(v1, 0.05)
            rott = rot1
            if hasattr(obj.ViewObject, "FlipText"):
                if obj.ViewObject.FlipText:
                    rott = App.Rotation(*rott).multiply(App.Rotation(
                        norm, 180)).Q
                    offset = offset.negative()
            # setting text
            try:
                m = obj.ViewObject.DisplayMode
            except:  # swallow all exceptions here since it always fails on first run (Displaymode enum no set yet)
                m = ["2D", "3D"][utils.get_param("dimstyle", 0)]
            if m == "3D":
                offset = offset.negative()
            self.tbase = (self.p2.add(
                (self.p3.sub(self.p2).multiply(0.5)))).add(offset)
            if hasattr(obj.ViewObject, "TextPosition"):
                if not DraftVecUtils.isNull(obj.ViewObject.TextPosition):
                    self.tbase = obj.ViewObject.TextPosition
            self.textpos.translation.setValue(
                [self.tbase.x, self.tbase.y, self.tbase.z])
            self.textpos.rotation = coin.SbRotation(rott[0], rott[1], rott[2],
                                                    rott[3])
            su = True
            if hasattr(obj.ViewObject, "ShowUnit"):
                su = obj.ViewObject.ShowUnit
            # set text value
            l = self.p3.sub(self.p2).Length
            unit = None
            if hasattr(obj.ViewObject, "UnitOverride"):
                unit = obj.ViewObject.UnitOverride
            # special representation if "Building US" scheme
            if App.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt(
                    "UserSchema", 0) == 5:
                s = App.Units.Quantity(l, App.Units.Length).UserString
                self.string = s.replace("' ", "'- ")
                self.string = s.replace("+", " ")
            elif hasattr(obj.ViewObject, "Decimals"):
                self.string = DraftGui.displayExternal(l,
                                                       obj.ViewObject.Decimals,
                                                       'Length', su, unit)
            else:
                self.string = DraftGui.displayExternal(l, None, 'Length', su,
                                                       unit)
            if hasattr(obj.ViewObject, "Override"):
                if obj.ViewObject.Override:
                    self.string = obj.ViewObject.Override.replace("$dim",\
                            self.string)
            self.text.string = self.text3d.string = utils.string_encode_coin(
                self.string)

            # set the lines
            if m == "3D":
                # calculate the spacing of the text
                textsize = (len(self.string) *
                            obj.ViewObject.FontSize.Value) / 4.0
                spacing = ((self.p3.sub(self.p2)).Length / 2.0) - textsize
                self.p2a = self.p2.add(
                    DraftVecUtils.scaleTo(self.p3.sub(self.p2), spacing))
                self.p2b = self.p3.add(
                    DraftVecUtils.scaleTo(self.p2.sub(self.p3), spacing))
                self.coords.point.setValues(
                    [[self.p1.x, self.p1.y, self.p1.z],
                     [self.p2.x, self.p2.y, self.p2.z],
                     [self.p2a.x, self.p2a.y, self.p2a.z],
                     [self.p2b.x, self.p2b.y, self.p2b.z],
                     [self.p3.x, self.p3.y, self.p3.z],
                     [self.p4.x, self.p4.y, self.p4.z]])
                #self.line.numVertices.setValues([3,3])
                self.line.coordIndex.setValues(0, 7, (0, 1, 2, -1, 3, 4, 5))
            else:
                self.coords.point.setValues([[self.p1.x, self.p1.y, self.p1.z],
                                             [self.p2.x, self.p2.y, self.p2.z],
                                             [self.p3.x, self.p3.y, self.p3.z],
                                             [self.p4.x, self.p4.y,
                                              self.p4.z]])
                #self.line.numVertices.setValue(4)
                self.line.coordIndex.setValues(0, 4, (0, 1, 2, 3))
示例#8
0
    def action(self, arg):
        """Handle the 3D scene events.

        This is installed as an EventCallback in the Inventor view.

        Parameters
        ----------
        arg: dict
            Dictionary with strings that indicates the type of event received
            from the 3D view.
        """
        import DraftGeomUtils

        if arg["Type"] == "SoKeyboardEvent":
            if arg["Key"] == "ESCAPE":
                self.finish()
        elif arg["Type"] == "SoLocation2Event":  # mouse movement detection
            self.point, ctrlPoint, info = gui_tool_utils.getPoint(self, arg)

            # this is to make sure radius is what you see on screen
            if self.center and DraftVecUtils.dist(self.point, self.center) > 0:
                viewdelta = DraftVecUtils.project(self.point.sub(self.center),
                                                  App.DraftWorkingPlane.axis)
                if not DraftVecUtils.isNull(viewdelta):
                    self.point = self.point.add(viewdelta.negative())
            if self.step == 0:  # choose center
                if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    if not self.altdown:
                        self.altdown = True
                        self.ui.switchUi(True)
                else:
                    if self.altdown:
                        self.altdown = False
                        self.ui.switchUi(False)
            else:  # choose radius
                if len(self.tangents) == 2:
                    cir = DraftGeomUtils.circleFrom2tan1pt(
                        self.tangents[0], self.tangents[1], self.point)
                    _c = DraftGeomUtils.findClosestCircle(self.point, cir)
                    self.center = _c.Center
                    self.arctrack.setCenter(self.center)
                elif self.tangents and self.tanpoints:
                    cir = DraftGeomUtils.circleFrom1tan2pt(
                        self.tangents[0], self.tanpoints[0], self.point)
                    _c = DraftGeomUtils.findClosestCircle(self.point, cir)
                    self.center = _c.Center
                    self.arctrack.setCenter(self.center)
                if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    if not self.altdown:
                        self.altdown = True
                    snapped = self.view.getObjectInfo(
                        (arg["Position"][0], arg["Position"][1]))
                    if snapped:
                        ob = self.doc.getObject(snapped['Object'])
                        num = int(snapped['Component'].lstrip('Edge')) - 1
                        ed = ob.Shape.Edges[num]
                        if len(self.tangents) == 2:
                            cir = DraftGeomUtils.circleFrom3tan(
                                self.tangents[0], self.tangents[1], ed)
                            cl = DraftGeomUtils.findClosestCircle(
                                self.point, cir)
                            self.center = cl.Center
                            self.rad = cl.Radius
                            self.arctrack.setCenter(self.center)
                        else:
                            self.rad = self.center.add(
                                DraftGeomUtils.findDistance(
                                    self.center, ed).sub(self.center)).Length
                    else:
                        self.rad = DraftVecUtils.dist(self.point, self.center)
                else:
                    if self.altdown:
                        self.altdown = False
                    self.rad = DraftVecUtils.dist(self.point, self.center)
                self.ui.setRadiusValue(self.rad, 'Length')
                self.arctrack.setRadius(self.rad)

            gui_tool_utils.redraw3DView()

        elif (arg["Type"] == "SoMouseButtonEvent" and arg["State"] == "DOWN"
              and arg["Button"] == "BUTTON1"):  # mouse click
            if self.point:
                if self.step == 0:  # choose center
                    if (not self.node) and (not self.support):
                        gui_tool_utils.getSupport(arg)
                        (self.point, ctrlPoint,
                         info) = gui_tool_utils.getPoint(self, arg)
                    if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                        snapped = self.view.getObjectInfo(
                            (arg["Position"][0], arg["Position"][1]))
                        if snapped:
                            ob = self.doc.getObject(snapped['Object'])
                            num = int(snapped['Component'].lstrip('Edge')) - 1
                            ed = ob.Shape.Edges[num]
                            self.tangents.append(ed)
                            if len(self.tangents) == 2:
                                self.arctrack.on()
                                self.ui.radiusUi()
                                self.step = 1
                                _msg(translate("draft", "Pick radius"))
                    else:
                        if len(self.tangents) == 1:
                            self.tanpoints.append(self.point)
                        else:
                            self.center = self.point
                            self.node = [self.point]
                            self.arctrack.setCenter(self.center)
                        self.arctrack.on()
                        self.ui.radiusUi()
                        self.step = 1
                        _msg(translate("draft", "Pick radius"))
                        if self.planetrack:
                            self.planetrack.set(self.point)
                elif self.step == 1:  # choose radius
                    self.drawPolygon()
示例#9
0
    def action(self, arg):
        """Handle the 3D scene events.

        This is installed as an EventCallback in the Inventor view.

        Parameters
        ----------
        arg: dict
            Dictionary with strings that indicates the type of event received
            from the 3D view.
        """
        import DraftGeomUtils
        plane = App.DraftWorkingPlane

        if arg["Type"] == "SoKeyboardEvent":
            if arg["Key"] == "ESCAPE":
                self.finish()
        elif arg["Type"] == "SoLocation2Event":  # mouse movement detection
            self.point, ctrlPoint, info = gui_tool_utils.getPoint(self, arg)
            # this is to make sure radius is what you see on screen
            if self.center and DraftVecUtils.dist(self.point, self.center) > 0:
                viewdelta = DraftVecUtils.project(self.point.sub(self.center),
                                                  plane.axis)
                if not DraftVecUtils.isNull(viewdelta):
                    self.point = self.point.add(viewdelta.negative())
            if self.step == 0:  # choose center
                if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    if not self.altdown:
                        self.altdown = True
                        self.ui.switchUi(True)
                    else:
                        if self.altdown:
                            self.altdown = False
                            self.ui.switchUi(False)
            elif self.step == 1:  # choose radius
                if len(self.tangents) == 2:
                    cir = DraftGeomUtils.circleFrom2tan1pt(self.tangents[0],
                                                           self.tangents[1],
                                                           self.point)
                    _c = DraftGeomUtils.findClosestCircle(self.point, cir)
                    self.center = _c.Center
                    self.arctrack.setCenter(self.center)
                elif self.tangents and self.tanpoints:
                    cir = DraftGeomUtils.circleFrom1tan2pt(self.tangents[0],
                                                           self.tanpoints[0],
                                                           self.point)
                    _c = DraftGeomUtils.findClosestCircle(self.point, cir)
                    self.center = _c.Center
                    self.arctrack.setCenter(self.center)
                if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    if not self.altdown:
                        self.altdown = True
                    if info:
                        ob = self.doc.getObject(info['Object'])
                        num = int(info['Component'].lstrip('Edge')) - 1
                        ed = ob.Shape.Edges[num]
                        if len(self.tangents) == 2:
                            cir = DraftGeomUtils.circleFrom3tan(self.tangents[0],
                                                                self.tangents[1],
                                                                ed)
                            cl = DraftGeomUtils.findClosestCircle(self.point, cir)
                            self.center = cl.Center
                            self.rad = cl.Radius
                            self.arctrack.setCenter(self.center)
                        else:
                            self.rad = self.center.add(DraftGeomUtils.findDistance(self.center, ed).sub(self.center)).Length
                    else:
                        self.rad = DraftVecUtils.dist(self.point, self.center)
                else:
                    if self.altdown:
                        self.altdown = False
                    self.rad = DraftVecUtils.dist(self.point, self.center)
                self.ui.setRadiusValue(self.rad, "Length")
                self.arctrack.setRadius(self.rad)
                self.linetrack.p1(self.center)
                self.linetrack.p2(self.point)
                self.linetrack.on()
            elif (self.step == 2):  # choose first angle
                currentrad = DraftVecUtils.dist(self.point, self.center)
                if currentrad != 0:
                    angle = DraftVecUtils.angle(plane.u, self.point.sub(self.center), plane.axis)
                else:
                    angle = 0
                self.linetrack.p2(DraftVecUtils.scaleTo(self.point.sub(self.center), self.rad).add(self.center))
                self.ui.setRadiusValue(math.degrees(angle), unit="Angle")
                self.firstangle = angle
            else:
                # choose second angle
                currentrad = DraftVecUtils.dist(self.point, self.center)
                if currentrad != 0:
                    angle = DraftVecUtils.angle(plane.u, self.point.sub(self.center), plane.axis)
                else:
                    angle = 0
                self.linetrack.p2(DraftVecUtils.scaleTo(self.point.sub(self.center), self.rad).add(self.center))
                self.updateAngle(angle)
                self.ui.setRadiusValue(math.degrees(self.angle), unit="Angle")
                self.arctrack.setApertureAngle(self.angle)

            gui_tool_utils.redraw3DView()

        elif arg["Type"] == "SoMouseButtonEvent":  # mouse click
            if arg["State"] == "DOWN" and arg["Button"] == "BUTTON1":
                if self.point:
                    if self.step == 0:  # choose center
                        if not self.support:
                            gui_tool_utils.getSupport(arg)
                            (self.point,
                             ctrlPoint, info) = gui_tool_utils.getPoint(self, arg)
                        if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                            snapped = self.view.getObjectInfo((arg["Position"][0],
                                                               arg["Position"][1]))
                            if snapped:
                                ob = self.doc.getObject(snapped['Object'])
                                num = int(snapped['Component'].lstrip('Edge')) - 1
                                ed = ob.Shape.Edges[num]
                                self.tangents.append(ed)
                                if len(self.tangents) == 2:
                                    self.arctrack.on()
                                    self.ui.radiusUi()
                                    self.step = 1
                                    self.ui.setNextFocus()
                                    self.linetrack.on()
                                    _msg(translate("draft", "Pick radius"))
                        else:
                            if len(self.tangents) == 1:
                                self.tanpoints.append(self.point)
                            else:
                                self.center = self.point
                                self.node = [self.point]
                                self.arctrack.setCenter(self.center)
                                self.linetrack.p1(self.center)
                                self.linetrack.p2(self.view.getPoint(arg["Position"][0],
                                                                     arg["Position"][1]))
                            self.arctrack.on()
                            self.ui.radiusUi()
                            self.step = 1
                            self.ui.setNextFocus()
                            self.linetrack.on()
                            _msg(translate("draft", "Pick radius"))
                            if self.planetrack:
                                self.planetrack.set(self.point)
                    elif self.step == 1:  # choose radius
                        if self.closedCircle:
                            self.drawArc()
                        else:
                            self.ui.labelRadius.setText(translate("draft", "Start angle"))
                            self.ui.radiusValue.setToolTip(translate("draft", "Start angle"))
                            self.ui.radiusValue.setText(U.Quantity(0, U.Angle).UserString)
                            self.linetrack.p1(self.center)
                            self.linetrack.on()
                            self.step = 2
                            _msg(translate("draft", "Pick start angle"))
                    elif self.step == 2:  # choose first angle
                        self.ui.labelRadius.setText(translate("draft", "Aperture angle"))
                        self.ui.radiusValue.setToolTip(translate("draft", "Aperture angle"))
                        self.step = 3
                        # scale center->point vector for proper display
                        # u = DraftVecUtils.scaleTo(self.point.sub(self.center), self.rad) obsolete?
                        self.arctrack.setStartAngle(self.firstangle)
                        _msg(translate("draft", "Pick aperture"))
                    else:  # choose second angle
                        self.step = 4
                        self.drawArc()