diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 99dcd459b..f3f3d89fc 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2887,6 +2887,7 @@ class _Rectangle(_DraftObject): obj.addProperty("App::PropertyDistance","Length","Base","Length of the rectangle") obj.addProperty("App::PropertyDistance","Height","Base","Height of the rectange") obj.addProperty("App::PropertyDistance","FilletRadius","Base","Radius to use to fillet the corners") + obj.addProperty("App::PropertyDistance","ChamferSize","Base","Size of the chamfer to give to the corners") obj.Length=1 obj.Height=1 @@ -2905,6 +2906,11 @@ class _Rectangle(_DraftObject): p3 = Vector(p1.x+fp.Length,p1.y+fp.Height,p1.z) p4 = Vector(p1.x,p1.y+fp.Height,p1.z) shape = Part.makePolygon([p1,p2,p3,p4,p1]) + if "ChamferSize" in fp.PropertiesList: + if fp.ChamferSize != 0: + w = DraftGeomUtils.filletWire(shape,fp.ChamferSize,chamfer=True) + if w: + shape = w if "FilletRadius" in fp.PropertiesList: if fp.FilletRadius != 0: w = DraftGeomUtils.filletWire(shape,fp.FilletRadius) @@ -2989,6 +2995,7 @@ class _Wire(_DraftObject): obj.addProperty("App::PropertyVector","End","Base", "The end point of this line") obj.addProperty("App::PropertyDistance","FilletRadius","Base","Radius to use to fillet the corners") + obj.addProperty("App::PropertyDistance","ChamferSize","Base","Size of the chamfer to give to the corners") obj.Closed = False def execute(self, fp): @@ -3076,6 +3083,11 @@ class _Wire(_DraftObject): edges.append(Part.Line(lp,p).toShape()) lp = p shape = Part.Wire(edges) + if "ChamferSize" in fp.PropertiesList: + if fp.ChamferSize != 0: + w = DraftGeomUtils.filletWire(shape,fp.ChamferSize,chamfer=True) + if w: + shape = w if "FilletRadius" in fp.PropertiesList: if fp.FilletRadius != 0: w = DraftGeomUtils.filletWire(shape,fp.FilletRadius) @@ -3132,6 +3144,7 @@ class _Polygon(_DraftObject): obj.addProperty("App::PropertyDistance","Radius","Base","Radius of the control circle") obj.addProperty("App::PropertyEnumeration","DrawMode","Base","How the polygon must be drawn from the control circle") obj.addProperty("App::PropertyDistance","FilletRadius","Base","Radius to use to fillet the corners") + obj.addProperty("App::PropertyDistance","ChamferSize","Base","Size of the chamfer to give to the corners") obj.DrawMode = ['inscribed','circumscribed'] obj.FacesNumber = 3 obj.Radius = 1 @@ -3157,6 +3170,11 @@ class _Polygon(_DraftObject): pts.append(Vector(delta*math.cos(ang),delta*math.sin(ang),0)) pts.append(pts[0]) shape = Part.makePolygon(pts) + if "ChamferSize" in fp.PropertiesList: + if fp.ChamferSize != 0: + w = DraftGeomUtils.filletWire(shape,fp.ChamferSize,chamfer=True) + if w: + shape = w if "FilletRadius" in fp.PropertiesList: if fp.FilletRadius != 0: w = DraftGeomUtils.filletWire(shape,fp.FilletRadius) diff --git a/src/Mod/Draft/DraftGeomUtils.py b/src/Mod/Draft/DraftGeomUtils.py index b1b834cea..e3543aa86 100755 --- a/src/Mod/Draft/DraftGeomUtils.py +++ b/src/Mod/Draft/DraftGeomUtils.py @@ -1348,7 +1348,7 @@ def arcFromSpline(edge): # Fillet code graciously donated by Jacques-Antoine Gaudin -def fillet(lEdges,r): +def fillet(lEdges,r,chamfer=False): ''' Take a list of two Edges & a float as argument, Returns a list of sorted edges describing a round corner''' @@ -1363,7 +1363,7 @@ def fillet(lEdges,r): else : raise Exception("Edge's curve must be either Line or Arc") return existingCurveType - + rndEdges = lEdges[0:2] rndEdges = sortEdges(rndEdges) @@ -1387,6 +1387,11 @@ def fillet(lEdges,r): U2 = lVertexes[2].Point.sub(lVertexes[1].Point) ; U2.normalize() alpha = U1.getAngle(U2) + if chamfer: + # correcting r value so the size of the chamfer = r + beta = math.pi - alpha/2 + r = (r/2)/math.cos(beta) + if round(alpha,precision()) == 0 or round(alpha - math.pi,precision()) == 0: # Edges have same direction print "DraftGeomUtils.fillet : Warning : edges have same direction. Did nothing" return rndEdges @@ -1406,8 +1411,10 @@ def fillet(lEdges,r): if (dToTangent>lEdges[0].Length) or (dToTangent>lEdges[1].Length) : print "DraftGeomUtils.fillet : Error : radius value ", r," is too high" return rndEdges - - rndEdges[1] = Part.Edge(Part.Arc(arcPt1,arcPt2,arcPt3)) + if chamfer: + rndEdges[1] = Part.Edge(Part.Line(arcPt1,arcPt3)) + else: + rndEdges[1] = Part.Edge(Part.Arc(arcPt1,arcPt2,arcPt3)) rndEdges[0] = Part.Edge(Part.Line(lVertexes[0].Point,arcPt1)) rndEdges += [Part.Edge(Part.Line(arcPt3,lVertexes[2].Point))] @@ -1497,7 +1504,10 @@ def fillet(lEdges,r): rndEdges[not arcFirst] = arcAsEdge rndEdges[arcFirst] = lineAsEdge - rndEdges[1:1] = [Part.Edge(Part.Arc(arcPt[- arcFirst],arcPt[1],arcPt[- myTrick]))] + if chamfer: + rndEdges[1:1] = [Part.Edge(Part.Line(arcPt[- arcFirst],arcPt[- myTrick]))] + else: + rndEdges[1:1] = [Part.Edge(Part.Arc(arcPt[- arcFirst],arcPt[1],arcPt[- myTrick]))] return rndEdges @@ -1596,30 +1606,34 @@ def fillet(lEdges,r): rndEdges[0] = arcAsEdge[0] rndEdges[1] = arcAsEdge[1] - rndEdges[1:1] = [Part.Edge(Part.Arc(arcPt[0],arcPt[1],arcPt[2]))] + if chamfer: + rndEdges[1:1] = [Part.Edge(Part.Line(arcPt[0],arcPt[2]))] + else: + rndEdges[1:1] = [Part.Edge(Part.Arc(arcPt[0],arcPt[1],arcPt[2]))] return rndEdges -def filletWire(aWire,r,makeClosed=True): - ''' Fillets each angle of a wire with r as radius value''' +def filletWire(aWire,r,chamfer=False): + ''' Fillets each angle of a wire with r as radius value + if chamfer is true, a chamfer is made instead and r is the + size of the chamfer''' edges = aWire.Edges edges = sortEdges(edges) filEdges = [edges[0]] for i in range(len(edges)-1): - result = fillet([filEdges[-1],edges[i+1]],r) + result = fillet([filEdges[-1],edges[i+1]],r,chamfer) if len(result)>2: filEdges[-1:] = result[0:3] else : filEdges[-1:] = result[0:2] - if isReallyClosed(aWire) and makeClosed : - result = fillet([filEdges[-1],filEdges[0]],r) + if isReallyClosed(aWire): + result = fillet([filEdges[-1],filEdges[0]],r,chamfer) if len(result)>2: filEdges[-1:] = result[0:2] filEdges[0] = result[2] return Part.Wire(filEdges) - # circle functions ********************************************************* def getBoundaryAngles(angle,alist):