diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index c767eb4c04..dc53b9ee34 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -1410,6 +1410,11 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): if sym is True, bind must be true too, and the offset is made on both sides, the total width being the given delta length.''' import Part, DraftGeomUtils + newwire = None + + if getType(obj) in ["Sketch","Part"]: + copy = True + print "the offset tool is currently unable to offset a non-Draft object directly - Creating a copy" def getRect(p,obj): "returns length,heigh,placement" @@ -1450,8 +1455,20 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): n1 = DraftGeomUtils.offsetWire(obj.Shape,d1) n2 = DraftGeomUtils.offsetWire(obj.Shape,d2) else: - newwire = DraftGeomUtils.offsetWire(obj.Shape,delta) - p = DraftGeomUtils.getVerts(newwire) + if isinstance(delta,float) and (len(obj.Shape.Edges) == 1): + # circle + c = obj.Shape.Edges[0].Curve + nc = Part.Circle(c.Center,c.Axis,delta) + if len(obj.Shape.Vertexes) > 1: + nc = Part.ArcOfCircle(nc,obj.Shape.Edges[0].FirstParameter,obj.Shape.Edges[0].LastParameter) + newwire = Part.Wire(nc.toShape()) + p = [] + else: + newwire = DraftGeomUtils.offsetWire(obj.Shape,delta) + if DraftGeomUtils.hasCurves(newwire) and copy: + p = [] + else: + p = DraftGeomUtils.getVerts(newwire) if occ: newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset") newobj.Shape = DraftGeomUtils.offsetWire(obj.Shape,delta,occ=True) @@ -1498,13 +1515,20 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): else: # try to offset anyway try: - newobj = makeWire(p) - newobj.Closed = obj.Shape.isClosed() + if p: + newobj = makeWire(p) + newobj.Closed = obj.Shape.isClosed() except: pass + if not(newobj) and newwire: + newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset") + newobj.Shape = newwire + else: + print "Unable to create an offset" if newobj: formatObject(newobj,obj) else: + newobj = None if sym: return None if getType(obj) == "Wire": if obj.Base or obj.Tool: diff --git a/src/Mod/Draft/DraftGeomUtils.py b/src/Mod/Draft/DraftGeomUtils.py index 3f9e796db9..71ab40eb18 100755 --- a/src/Mod/Draft/DraftGeomUtils.py +++ b/src/Mod/Draft/DraftGeomUtils.py @@ -58,6 +58,8 @@ def edg(p1,p2): def getVerts(shape): "getVerts(shape): returns a list containing vectors of each vertex of the shape" + if not hasattr(shape,"Vertexes"): + return [] p = [] for v in shape.Vertexes: p.append(v.Point) @@ -901,10 +903,12 @@ def offset(edge,vector): v1 = Vector.add(edge.Vertexes[0].Point, vector) v2 = Vector.add(edge.Vertexes[-1].Point, vector) return Part.Line(v1,v2).toShape() - else: + elif geomType(edge) == "Circle": rad = edge.Vertexes[0].Point.sub(edge.Curve.Center) newrad = Vector.add(rad,vector).Length - return Part.Circle(edge.Curve.Center,NORM,newrad).toShape() + return Part.Circle(edge.Curve.Center,edge.Curve.Axis,newrad).toShape() + else: + return None def isReallyClosed(wire): "checks if a wire is really closed" @@ -1001,6 +1005,8 @@ def offsetWire(wire,dvec,bind=False,occ=False): angle = DraftVecUtils.angle(vec(edges[0]),v,norm) delta = DraftVecUtils.rotate(delta,angle,norm) nedge = offset(curredge,delta) + if not nedge: + return None if isinstance(curredge.Curve,Part.Circle): nedge = Part.ArcOfCircle(nedge.Curve,curredge.FirstParameter,curredge.LastParameter).toShape() nedges.append(nedge) @@ -1098,6 +1104,8 @@ def findDistance(point,edge,strict=False): ve2 = None center = edge.Curve.Center segment = center.sub(point) + if segment.Length == 0: + return None ratio = (segment.Length - edge.Curve.Radius) / segment.Length dist = segment.multiply(ratio) newpoint = Vector.add(point, dist) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 63e1d75bf7..6232944891 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -2437,9 +2437,24 @@ class Offset(Modifier): elif Draft.getType(self.sel) == "BSpline": self.ghost = bsplineTracker(points=self.sel.Points) self.mode = "BSpline" + elif Draft.getType(self.sel) == "BezCurve": + msg(translate("draft", "Sorry, offset of Bezier curves is currently still not supported\n"),"warning") + self.finish() + return else: - self.ghost = wireTracker(self.shape) - self.mode = "Wire" + if len(self.sel.Shape.Edges) == 1: + import Part + if isinstance(self.sel.Shape.Edges[0].Curve,Part.Circle): + self.ghost = arcTracker() + self.mode = "Circle" + self.center = self.shape.Edges[0].Curve.Center + self.ghost.setCenter(self.center) + if len(self.sel.Shape.Vertexes) > 1: + self.ghost.setStartAngle(self.sel.Shape.Edges[0].FirstParameter) + self.ghost.setEndAngle(self.sel.Shape.Edges[0].LastParameter) + if not self.ghost: + self.ghost = wireTracker(self.shape) + self.mode = "Wire" self.call = self.view.addEventCallback("SoEvent",self.action) msg(translate("draft", "Pick distance:\n")) if self.planetrack: @@ -2506,7 +2521,8 @@ class Offset(Modifier): if self.npts: print "offset:npts=",self.npts self.commit(translate("draft","Offset"), - ['Draft.offset(FreeCAD.ActiveDocument.'+self.sel.Name+','+DraftVecUtils.toString(self.npts)+',copy='+str(copymode)+')']) + ['Draft.offset(FreeCAD.ActiveDocument.'+self.sel.Name+','+DraftVecUtils.toString(self.npts)+',copy='+str(copymode)+')', + 'FreeCAD.ActiveDocument.recompute()']) elif self.dvec: if isinstance(self.dvec,float): d = str(self.dvec)