Skip to content

Commit

Permalink
Draft Bezier Curves: Add functionality to mockup
Browse files Browse the repository at this point in the history
     - Split poles to multiple bezier segments
     - set degree of bezier curve
     - Close Draft bezier curves
     - set Degree at creation
     - implement addPoint for piecewise Bezier curves

Draft BezCurve bugfixes
    - fix Close button for BexCurve Edit
    - fix tracker behaviour in for BezCurve.undoLast

Draft Bezier Curve: use circle trackers for control points

Draft: prepare functions to make bezier knots tangent or symmetric
  • Loading branch information
5263 authored and yorikvanhavre committed Feb 23, 2014
1 parent 2d43d61 commit 69b0944
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 100 deletions.
63 changes: 45 additions & 18 deletions src/Mod/Draft/Draft.py
Expand Up @@ -831,7 +831,7 @@ def makeBSpline(pointslist,closed=False,placement=None,face=True,support=None):
FreeCAD.ActiveDocument.recompute()
return obj
#######################################
def makeBezCurve(pointslist,placement=None,support=None):
def makeBezCurve(pointslist,closed=False,placement=None,support=None,Degree=None):
'''makeBezCurve(pointslist,[closed],[placement]): Creates a Bezier Curve object
from the given list of vectors. Instead of a pointslist, you can also pass a Part Wire.'''
if not isinstance(pointslist,list):
Expand All @@ -845,7 +845,13 @@ def makeBezCurve(pointslist,placement=None,support=None):
obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",fname)
_BezCurve(obj)
obj.Points = pointslist
# obj.Closed = closed
if Degree:
obj.Degree = Degree
else:
import Part
obj.Degree = min((len(pointslist)-(1 * (not closed))),\
Part.BezierCurve().MaxDegree)
obj.Closed = closed
obj.Support = support
if placement: obj.Placement = placement
if gui:
Expand Down Expand Up @@ -3963,41 +3969,62 @@ def __init__(self, obj):
_DraftObject.__init__(self,obj,"BezCurve")
obj.addProperty("App::PropertyVectorList","Points","Draft",
"The points of the Bezier curve")
# obj.addProperty("App::PropertyBool","Closed","Draft",
# "If the Bezier curve is closed or not")
obj.addProperty("App::PropertyInteger","Degree","Draft",
"The degree of the Bezier function")
obj.addProperty("App::PropertyBool","Closed","Draft",
"If the Bezier curve is closed or not(??)")
"If the Bezier curve should be closed or not")
obj.Closed = False
obj.Degree = 3

def execute(self, fp):
self.createGeometry(fp)

def onChanged(self, fp, prop):
if prop in ["Points","Degree"]:
if prop in ["Points","Degree", "Closed"]:
self.createGeometry(fp)

def createGeometry(self,fp):
import Part
plm = fp.Placement
if fp.Points:
# if fp.Points[0] == fp.Points[-1]:
# if not fp.Closed: fp.Closed = True
# fp.Points.pop()
# if fp.Closed and (len(fp.Points) > 2):
c = Part.BezierCurve()
c.setPoles(fp.Points)
e = Part.Edge(c)
w = Part.Wire(e)
startpoint=fp.Points[0]
poles=fp.Points[1:]
if fp.Closed and (len(fp.Points) > 2):
poles.append(fp.Points[0])
segpoleslst=[poles[x:x+fp.Degree] for x in \
xrange(0, len(poles), fp.Degree)]
edges = []
for segpoles in segpoleslst:
# if len(segpoles) == fp.Degree # would skip additional poles
c = Part.BezierCurve() #last segment may have lower degree
c.increase(len(segpoles))
c.setPoles([startpoint]+segpoles)
edges.append(Part.Edge(c))
startpoint = segpoles[-1]
w = Part.Wire(edges)
fp.Shape = w
# else:
# spline = Part.BezCurveCurve()
# spline.interpolate(fp.Points, False)
# fp.Shape = spline.toShape()
fp.Placement = plm

@staticmethod
def symmetricpoles(knot, p1, p2):
"""make two poles symmetric respective to the knot"""
p1h=FreeCAD.Vector(p1)
p2h=FreeCAD.Vector(p2)
p1h.multiply(0.5)
p2h.multiply(0.5)
return ( knot+p1-p2 , knot+p2-p1)

@staticmethod
def tangentpoles(knot, p1, p2):
"""make two poles have the same tangent at knot"""
p12n=p2.sub(p1)
p12n.normalize()
p1k=knot-p1
p1k_= FreeCAD.Vector(p12n)
p1k_.multiply(p1k*p12n)
pk_k=knot-p1-p1k_
return (p1+pk_k,p2+pk_k)

# for compatibility with older versions ???????
_ViewProviderBezCurve = _ViewProviderWire
#######################################
Expand Down
17 changes: 12 additions & 5 deletions src/Mod/Draft/DraftGeomUtils.py
Expand Up @@ -193,6 +193,8 @@ def geomType(edge):
return "Circle"
elif isinstance(edge.Curve,Part.BSplineCurve):
return "BSplineCurve"
elif isinstance(edge.Curve,Part.BezierCurve):
return "BezierCurve"
elif isinstance(edge.Curve,Part.Ellipse):
return "Ellipse"
else:
Expand Down Expand Up @@ -610,7 +612,8 @@ def lookfor(aVertex, inEdges):
elif geomType(result[3]) == "Circle":
mp = findMidpoint(result[3])
return [Part.Arc(aVertex.Point,mp,result[3].Vertexes[0].Point).toShape()]
elif geomType(result[3]) == "BSplineCurve":
elif geomType(result[3]) == "BSplineCurve" or\
geomType(result[3]) == "BezierCurve":
if isLine(result[3].Curve):
return [Part.Line(aVertex.Point,result[3].Vertexes[0].Point).toShape()]
else:
Expand Down Expand Up @@ -648,7 +651,8 @@ def lookfor(aVertex, inEdges):
mp = findMidpoint(result[3])
newedge = Part.Arc(aVertex.Point,mp,result[3].Vertexes[0].Point).toShape()
olEdges += [newedge] + next
elif geomType(result[3]) == "BSplineCurve":
elif geomType(result[3]) == "BSplineCurve" or \
geomType(result[3]) == "BezierCurve":
if isLine(result[3].Curve):
newedge = Part.Line(aVertex.Point,result[3].Vertexes[0].Point).toShape()
olEdges += [newedge] + next
Expand Down Expand Up @@ -1099,7 +1103,8 @@ def findDistance(point,edge,strict=False):
return None
else:
return dist
elif geomType(edge) == "BSplineCurve":
elif geomType(edge) == "BSplineCurve" or \
geomType(edge) == "BezierCurve":
try:
pr = edge.Curve.parameter(point)
np = edge.Curve.value(pr)
Expand Down Expand Up @@ -1214,7 +1219,8 @@ def getTangent(edge,frompoint=None):
'''
if geomType(edge) == "Line":
return vec(edge)
elif geomType(edge) == "BSplineCurve":
elif geomType(edge) == "BSplineCurve" or \
geomType(edge) == "BezierCurve":
if not frompoint:
return None
cp = edge.Curve.parameter(frompoint)
Expand Down Expand Up @@ -1817,7 +1823,8 @@ def cleanProjection(shape,tessellate=False):
newedges.append(a)
else:
newedges.append(e.Curve.toShape())
elif geomType(e) == "BSplineCurve":
elif geomType(e) == "BSplineCurve" or \
geomType(e) == "BezierCurve":
if tessellate:
newedges.append(Part.Wire(curvetowire(e,e.Curve.NbPoles)))
else:
Expand Down

0 comments on commit 69b0944

Please sign in to comment.