Skip to content

Commit

Permalink
Draft Bezier Curve: implemented Continuity Property
Browse files Browse the repository at this point in the history
Draft: allow continuity on closed Bezier curves

Draft: BezCurve bugfixes
    - smoothBezCurve
    - edit mode
    - avoid splitting points into segments as long as degree is zero
    - increase the continuity when closing curve
    - closed berzier curves
    - Catch modifications of continuity of first and last knot on open curves
  • Loading branch information
5263 authored and yorikvanhavre committed Feb 23, 2014
1 parent 6f8c1c6 commit 2dfabfd
Show file tree
Hide file tree
Showing 6 changed files with 491 additions and 55,039 deletions.
49 changes: 40 additions & 9 deletions src/Mod/Draft/Draft.py
Expand Up @@ -853,6 +853,7 @@ def makeBezCurve(pointslist,closed=False,placement=None,support=None,Degree=None
Part.BezierCurve().MaxDegree)
obj.Closed = closed
obj.Support = support
obj.Proxy.resetcontinuity(obj)
if placement: obj.Placement = placement
if gui:
_ViewProviderWire(obj.ViewObject)
Expand Down Expand Up @@ -3971,30 +3972,60 @@ def __init__(self, obj):
"The points of the Bezier curve")
obj.addProperty("App::PropertyInteger","Degree","Draft",
"The degree of the Bezier function")
obj.addProperty("App::PropertyIntegerList","Continuity","Draft",
"Continuity")
obj.addProperty("App::PropertyBool","Closed","Draft",
"If the Bezier curve should be closed or not")
obj.Closed = False
obj.Degree = 3
obj.Continuity = []
#obj.setEditorMode("Degree",2)#hide
obj.setEditorMode("Continuity",1)#ro

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


def _segpoleslst(self,fp):
"""split the points into segments"""
if not fp.Closed and len(fp.Points) >= 2: #allow lower degree segement
poles=fp.Points[1:]
elif fp.Closed and len(fp.Points) >= fp.Degree: #drawable
#poles=fp.Points[1:(fp.Degree*(len(fp.Points)//fp.Degree))]+fp.Points[0:1]
poles=fp.Points[1:]+fp.Points[0:1]
else:
poles=[]
return [poles[x:x+fp.Degree] for x in \
xrange(0, len(poles), (fp.Degree or 1))]

def resetcontinuity(self,fp):
fp.Continuity = [0]*(len(self._segpoleslst(fp))-1+1*fp.Closed)
#nump= len(fp.Points)-1+fp.Closed*1
#numsegments = (nump // fp.Degree) + 1 * (nump % fp.Degree > 0) -1
#fp.Continuity = [0]*numsegments

def onChanged(self, fp, prop):
if prop in ["Points","Degree", "Closed"]:
if prop == 'Closed': # if remove the last entry when curve gets opened
oldlen = len(fp.Continuity)
newlen = (len(self._segpoleslst(fp))-1+1*fp.Closed)
if oldlen > newlen:
fp.Continuity = fp.Continuity[:newlen]
if oldlen < newlen:
fp.Continuity = fp.Continuity + [0]*(newlen-oldlen)
if hasattr(fp,'Closed') and fp.Closed and prop in ['Points','Degree','Closed'] and\
len(fp.Points) % fp.Degree: # the curve editing tools can't handle extra points
fp.Points=fp.Points[:(fp.Degree*(len(fp.Points)//fp.Degree))] #for closed curves
if prop in ["Degree"] and fp.Degree >= 1: #reset Continuity
self.resetcontinuity(fp)
if prop in ["Points","Degree","Continuity","Closed"]:
self.createGeometry(fp)

def createGeometry(self,fp):
import Part
plm = fp.Placement
if fp.Points:
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:
for segpoles in self._segpoleslst(fp):
# if len(segpoles) == fp.Degree # would skip additional poles
c = Part.BezierCurve() #last segment may have lower degree
c.increase(len(segpoles))
Expand Down
19 changes: 19 additions & 0 deletions src/Mod/Draft/DraftGui.py
Expand Up @@ -283,6 +283,7 @@ def setupToolBar(self,task=False):

self.addButton = self._pushbutton("addButton", self.layout, icon="Draft_AddPoint", width=22, checkable=True)
self.delButton = self._pushbutton("delButton", self.layout, icon="Draft_DelPoint", width=22, checkable=True)
self.sharpButton = self._pushbutton("sharpButton", self.layout, icon="Draft_BezSharpNode", width=22, checkable=True)
self.tangentButton = self._pushbutton("tangentButton", self.layout, icon="Draft_BezTanNode", width=22, checkable=True)
self.symmetricButton = self._pushbutton("symmetricButton", self.layout, icon="Draft_BezSymNode", width=22, checkable=True)

Expand Down Expand Up @@ -373,6 +374,7 @@ def setupToolBar(self,task=False):
QtCore.QObject.connect(self.offsetValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
QtCore.QObject.connect(self.addButton,QtCore.SIGNAL("toggled(bool)"),self.setAddMode)
QtCore.QObject.connect(self.delButton,QtCore.SIGNAL("toggled(bool)"),self.setDelMode)
QtCore.QObject.connect(self.sharpButton,QtCore.SIGNAL("toggled(bool)"),self.setSharpMode)
QtCore.QObject.connect(self.tangentButton,QtCore.SIGNAL("toggled(bool)"),self.setTangentMode)
QtCore.QObject.connect(self.symmetricButton,QtCore.SIGNAL("toggled(bool)"),self.setSymmetricMode)
QtCore.QObject.connect(self.finishButton,QtCore.SIGNAL("pressed()"),self.finish)
Expand Down Expand Up @@ -450,6 +452,7 @@ def setupStyle(self):
style = "#constrButton:Checked {background-color: "
style += self.getDefaultColor("constr",rgb=True)+" } "
style += "#addButton:Checked, #delButton:checked, "
style += "#sharpButton:Checked, "
style += "#tangentButton:Checked, #symmetricButton:checked {"
style += "background-color: rgb(20,100,250) }"
self.baseWidget.setStyleSheet(style)
Expand Down Expand Up @@ -482,6 +485,7 @@ def retranslateUi(self, widget=None):
self.occOffset.setText(translate("draft", "&OCC-style offset"))
self.addButton.setToolTip(translate("draft", "Add points to the current object"))
self.delButton.setToolTip(translate("draft", "Remove points from the current object"))
self.sharpButton.setToolTip(translate("draft", "Make Bezier node sharp"))
self.tangentButton.setToolTip(translate("draft", "Make Bezier node tangent"))
self.symmetricButton.setToolTip(translate("draft", "Make Bezier node symmetric"))
self.undoButton.setText(translate("draft", "&Undo"))
Expand Down Expand Up @@ -679,6 +683,7 @@ def offUi(self):
self.finishButton.hide()
self.addButton.hide()
self.delButton.hide()
self.sharpButton.hide()
self.tangentButton.hide()
self.symmetricButton.hide()
self.undoButton.hide()
Expand Down Expand Up @@ -810,13 +815,15 @@ def editUi(self, mode=None):
self.addButton.show()
self.delButton.show()
if mode == 'BezCurve':
self.sharpButton.show()
self.tangentButton.show()
self.symmetricButton.show()
self.finishButton.show()
self.closeButton.show()
# always start Edit with buttons unchecked
self.addButton.setChecked(False)
self.delButton.setChecked(False)
self.sharpButton.setChecked(False)
self.tangentButton.setChecked(False)
self.symmetricButton.setChecked(False)

Expand Down Expand Up @@ -848,6 +855,7 @@ def setEditButtons(self,mode):
self.delButton.setEnabled(mode)

def setBezEditButtons(self,mode):
self.sharpButton.setEnabled(mode)
self.tangentButton.setEnabled(mode)
self.symmetricButton.setEnabled(mode)

Expand Down Expand Up @@ -1378,22 +1386,33 @@ def setAddMode(self,bool):
if self.addButton.isChecked():
self.delButton.setChecked(False)
self.symmetricButton.setChecked(False)
self.sharpButton.setChecked(False)
self.tangentButton.setChecked(False)

def setDelMode(self,bool):
if self.delButton.isChecked():
self.addButton.setChecked(False)
self.symmetricButton.setChecked(False)
self.sharpButton.setChecked(False)
self.tangentButton.setChecked(False)

def setSharpMode(self,bool):
if self.sharpButton.isChecked():
self.tangentButton.setChecked(False)
self.symmetricButton.setChecked(False)
self.addButton.setChecked(False)
self.delButton.setChecked(False)

def setTangentMode(self,bool):
if self.tangentButton.isChecked():
self.sharpButton.setChecked(False)
self.symmetricButton.setChecked(False)
self.addButton.setChecked(False)
self.delButton.setChecked(False)

def setSymmetricMode(self,bool):
if self.symmetricButton.isChecked():
self.sharpButton.setChecked(False)
self.tangentButton.setChecked(False)
self.addButton.setChecked(False)
self.delButton.setChecked(False)
Expand Down

0 comments on commit 2dfabfd

Please sign in to comment.