Skip to content

Commit

Permalink
Draft: added functions to edit tangent or symmetric bezier curves
Browse files Browse the repository at this point in the history
       changed icon Draft_BezTanNode
       bugfix in Draft BezCurve modifytangentpole
       move poles with knots for Bezier Curves with Degree >=3
       make bezier curves symmetric/tangent when clicking on poles by
           keeping the coordinates of the selected pole
  • Loading branch information
5263 authored and yorikvanhavre committed Feb 23, 2014
1 parent e60a77e commit 6f8c1c6
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 188 deletions.
36 changes: 28 additions & 8 deletions src/Mod/Draft/Draft.py
Expand Up @@ -4005,25 +4005,45 @@ def createGeometry(self,fp):
fp.Shape = w
fp.Placement = plm

@staticmethod
def symmetricpoles(knot, p1, p2):
@classmethod
def symmetricpoles(cls,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)
return ( knot+p1h-p2h , knot+p2h-p1h)

@staticmethod
def tangentpoles(knot, p1, p2):
@classmethod
def tangentpoles(cls,knot, p1, p2,allowsameside=False):
"""make two poles have the same tangent at knot"""
p12n=p2.sub(p1)
p12n.normalize()
p1k=knot-p1
p2k=knot-p2
p1k_= FreeCAD.Vector(p12n)
p1k_.multiply(p1k*p12n)
pk_k=knot-p1-p1k_
return (p1+pk_k,p2+pk_k)
kon12=(p1k*p12n)
if allowsameside or not (kon12 < 0 or p2k*p12n > 0):# instead of moving
p1k_.multiply(kon12)
pk_k=knot-p1-p1k_
return (p1+pk_k,p2+pk_k)
else:
return cls.symmetricpoles(knot, p1, p2)

@staticmethod
def modifysymmetricpole(knot,p1):
"""calculate the coordinates of the opposite pole
of a symmetric knot"""
return knot+knot-p1

@staticmethod
def modifytangentpole(knot,p1,oldp2):
"""calculate the coordinates of the opposite pole
of a tangent knot"""
pn=knot-p1
pn.normalize()
pn.multiply((knot-oldp2).Length)
return pn+knot

# for compatibility with older versions ???????
_ViewProviderBezCurve = _ViewProviderWire
Expand Down
46 changes: 37 additions & 9 deletions src/Mod/Draft/DraftTools.py
Expand Up @@ -3354,6 +3354,14 @@ def update(self,v):
self.obj.Closed = True
# DNC: fix error message if edited point coinsides with one of the existing points
if ( editPnt in pts ) == False:
if Draft.getType(self.obj) in ["BezCurve"] and self.obj.Degree >=3 and \
(self.editing % self.obj.Degree) == 0: #it's a knot
if self.editing >= 1: #move left pole
pts[self.editing-1] = pts[self.editing-1] + editPnt - pts[self.editing]
self.trackers[self.editing-1].set(pts[self.editing-1])
if self.editing < len(pts)-1: #move right pole
pts[self.editing+1] = pts[self.editing+1] + editPnt - pts[self.editing]
self.trackers[self.editing+1].set(pts[self.editing+1])
pts[self.editing] = editPnt
self.obj.Points = pts
self.trackers[self.editing].set(v)
Expand Down Expand Up @@ -3511,18 +3519,38 @@ def smoothBezPoint(self,point, info=None, style='Symmetric'):
return # didn't click control point
pts = self.obj.Points
deg = self.obj.Degree
if point not in range(0, len(pts), deg):
msg(translate("draft", "Selection is not a Node\n"),'warning')
return
if (point == 0) or (point == (len(pts)-1)):
if point % deg != 0:
if deg >=3: #allow to select poles
if point > 2 and point % deg == 1: #right pole
knot = point -1
keepp = point
changep = point -2
elif point -3 < len(pts): #left pole
knot = point +1
keepp = point
changep = point +2
else:
msg(translate("draft", "Can't change Knot belonging to that pole\n"),'warning')
return
if knot:
if style == 'Tangent':
pts[changep] = self.obj.Proxy.modifytangentpole(pts[knot],pts[keepp],\
pts[changep])
else:
pts[changep] = self.obj.Proxy.modifysymmetricpole(pts[knot],pts[keepp])
else:
msg(translate("draft", "Selection is not a Pole\n"),'warning')
return
elif (point == 0) or (point == (len(pts)-1)):
msg(translate("draft", "Endpoint of BezCurve can't be smoothed\n"),'warning')
return
if style == 'Tangent':
prev, next = self.obj.Proxy.tangentpoles(pts[point],pts[point-1],pts[point+1])
else:
prev, next = self.obj.Proxy.symmetricpoles(pts[point],pts[point-1],pts[point+1])
pts[point-1] = prev
pts[point+1] = next
if style == 'Tangent':
prev, next = self.obj.Proxy.tangentpoles(pts[point],pts[point-1],pts[point+1])
else:
prev, next = self.obj.Proxy.symmetricpoles(pts[point],pts[point-1],pts[point+1])
pts[point-1] = prev
pts[point+1] = next
self.obj.Points = pts
self.doc.openTransaction("Edit "+self.obj.Name)
self.doc.commitTransaction()
Expand Down

0 comments on commit 6f8c1c6

Please sign in to comment.