Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Draft: Allow to draw lines by length & angle - fixes #1383
* Added a Length property to Draft line objects
* Added length & angle parameters to the line drawing tool
  • Loading branch information
yorikvanhavre committed Jan 13, 2015
1 parent 5289967 commit 7d0dc06
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 5 deletions.
12 changes: 12 additions & 0 deletions src/Mod/Draft/Draft.py
Expand Up @@ -4079,6 +4079,7 @@ def __init__(self, obj):
obj.addProperty("App::PropertyLink","Tool","Draft","The tool object is the wire is formed from 2 objects")
obj.addProperty("App::PropertyVector","Start","Draft","The start point of this line")
obj.addProperty("App::PropertyVector","End","Draft","The end point of this line")
obj.addProperty("App::PropertyLength","Length","Draft","The length of this line")
obj.addProperty("App::PropertyLength","FilletRadius","Draft","Radius to use to fillet the corners")
obj.addProperty("App::PropertyLength","ChamferSize","Draft","Size of the chamfer to give to the corners")
obj.addProperty("App::PropertyBool","MakeFace","Draft","Create a face if this object is closed")
Expand Down Expand Up @@ -4153,6 +4154,8 @@ def execute(self, obj):
shape = w
if shape:
obj.Shape = shape
if hasattr(obj,"Length"):
obj.Length = shape.Length
obj.Placement = plm
self.onChanged(obj,"Placement")

Expand All @@ -4173,6 +4176,14 @@ def onChanged(self, obj, prop):
if pts[-1] != realfpend:
pts[-1] = realfpend
obj.Points = pts
elif prop == "Length":
if obj.Shape:
if obj.Length.Value != obj.Shape.Length:
if len(obj.Points) == 2:
v = obj.Points[-1].sub(obj.Points[0])
v = DraftVecUtils.scaleTo(v,obj.Length.Value)
obj.Points = [obj.Points[0],obj.Points[0].add(v)]

elif prop == "Placement":
pl = FreeCAD.Placement(obj.Placement)
if len(obj.Points) >= 2:
Expand All @@ -4185,6 +4196,7 @@ def onChanged(self, obj, prop):
if len(obj.Points) > 2:
obj.setEditorMode('Start',2)
obj.setEditorMode('End',2)
obj.setEditorMode('Length',2)


class _ViewProviderWire(_ViewProviderDraft):
Expand Down
89 changes: 84 additions & 5 deletions src/Mod/Draft/DraftGui.py
Expand Up @@ -31,7 +31,7 @@
Report to Draft.py for info
'''

import FreeCAD, FreeCADGui, os, Draft, sys
import FreeCAD, FreeCADGui, os, Draft, sys, DraftVecUtils, math

try:
from PySide import QtCore,QtGui,QtSvg
Expand Down Expand Up @@ -230,6 +230,7 @@ def __init__(self):
self.isTaskOn = False
self.fillmode = Draft.getParam("fillmode",False)
self.mask = None
self.alock = False
self.DECIMALS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2)
self.FORMAT = makeFormatSpec(self.DECIMALS,'Length')
self.AFORMAT = makeFormatSpec(self.DECIMALS,'Angle')
Expand Down Expand Up @@ -387,7 +388,24 @@ def setupToolBar(self,task=False):
self.labelz = self._label("labelz", zl)
self.zValue = self._inputfield("zValue", zl)
self.zValue.setText(self.FORMAT % 0)

# text

self.textValue = self._lineedit("textValue", self.layout)

# additional line controls

ll = QtGui.QHBoxLayout()
al = QtGui.QHBoxLayout()
self.layout.addLayout(ll)
self.layout.addLayout(al)
self.labellength = self._label("labellength", ll)
self.lengthValue = self._inputfield("lengthValue", ll)
self.lengthValue.setText(self.FORMAT % 0)
self.labelangle = self._label("labelangle", al)
self.angleLock = self._checkbox("angleLock",al,checked=self.alock)
self.angleValue = self._inputfield("angleValue", al)
self.angleValue.setText(self.AFORMAT % 0)

# shapestring

Expand All @@ -408,6 +426,7 @@ def setupToolBar(self,task=False):
self.STrack = 0

# options

fl = QtGui.QHBoxLayout()
self.layout.addLayout(fl)
self.numFacesLabel = self._label("numfaceslabel", fl)
Expand Down Expand Up @@ -451,16 +470,21 @@ def setupToolBar(self,task=False):
QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("valueChanged(double)"),self.changeXValue)
QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("valueChanged(double)"),self.changeYValue)
QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("valueChanged(double)"),self.changeZValue)
QtCore.QObject.connect(self.lengthValue,QtCore.SIGNAL("valueChanged(double)"),self.changeLengthValue)
QtCore.QObject.connect(self.angleValue,QtCore.SIGNAL("valueChanged(double)"),self.changeAngleValue)
QtCore.QObject.connect(self.angleLock,QtCore.SIGNAL("stateChanged(int)"),self.toggleAngle)
QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("valueChanged(double)"),self.changeRadiusValue)
QtCore.QObject.connect(self.offsetValue,QtCore.SIGNAL("valueChanged(double)"),self.changeOffsetValue)
QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("returnPressed()"),self.checkx)
QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("returnPressed()"),self.checky)
QtCore.QObject.connect(self.lengthValue,QtCore.SIGNAL("returnPressed()"),self.checkangle)
QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
QtCore.QObject.connect(self.angleValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("textChanged(QString)"),self.storeCurrentText)
QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("returnPressed()"),self.sendText)
#QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("escaped()"),self.escape)
Expand Down Expand Up @@ -512,9 +536,9 @@ def setupToolBar(self,task=False):
#QtCore.QObject.connect(self.STrackValue,QtCore.SIGNAL("escaped()"),self.escape)
#QtCore.QObject.connect(self.SStringValue,QtCore.SIGNAL("escaped()"),self.escape)

# if Ui changed to have Size & Track visible at same time, use this
# QtCore.QObject.connect(self.SSizeValue,QtCore.SIGNAL("returnPressed()"),self.checkSSize)
# QtCore.QObject.connect(self.STrackValue,QtCore.SIGNAL("returnPressed()"),self.checkSTrack)
# if Ui changed to have Size & Track visible at same time, use this
#QtCore.QObject.connect(self.SSizeValue,QtCore.SIGNAL("returnPressed()"),self.checkSSize)
#QtCore.QObject.connect(self.STrackValue,QtCore.SIGNAL("returnPressed()"),self.checkSTrack)

def setupTray(self):
"sets draft tray buttons up"
Expand Down Expand Up @@ -578,6 +602,12 @@ def retranslateUi(self, widget=None):
self.labelz.setText(translate("draft", "Z"))
self.yValue.setToolTip(translate("draft", "Y coordinate of next point"))
self.zValue.setToolTip(translate("draft", "Z coordinate of next point"))
self.labellength.setText(translate("draft", "Length"))
self.labelangle.setText(translate("draft", "Angle"))
self.lengthValue.setToolTip(translate("draft", "Length of current segment"))
self.angleValue.setToolTip(translate("draft", "Angle of current segment"))
#self.angleLock.setText(translate("draft", "&Lock"))
self.angleLock.setToolTip(translate("draft", "Check this to lock the current angle (l)"))
self.labelRadius.setText(translate("draft", "Radius"))
self.radiusValue.setToolTip(translate("draft", "Radius of Circle"))
self.isRelative.setText(translate("draft", "&Relative"))
Expand Down Expand Up @@ -705,21 +735,35 @@ def selectPlaneUi(self):
self.resetPlaneButton.show()
self.offsetLabel.show()
self.offsetValue.show()

def extraLineUi(self):
'''shows length and angle controls'''
self.labellength.show()
self.lengthValue.show()
self.labelangle.show()
self.angleValue.show()
self.angleLock.show()

def hideXYZ(self):
''' turn off all the point entry widgets '''
self.labelx.hide()
self.labely.hide()
self.labelz.hide()
self.labellength.hide()
self.labelangle.hide()
self.xValue.hide()
self.yValue.hide()
self.zValue.hide()
self.lengthValue.hide()
self.angleValue.hide()
self.angleLock.hide()

def lineUi(self,title=None):
if title:
self.pointUi(title,icon="Draft_Line")
else:
self.pointUi(translate("draft", "Line"),icon="Draft_Line")
self.extraLineUi()
self.xValue.setEnabled(True)
self.yValue.setEnabled(True)
self.isRelative.show()
Expand Down Expand Up @@ -1105,6 +1149,10 @@ def checky(self):
self.zValue.selectAll()
else:
self.validatePoint()

def checkangle(self):
self.angleValue.setFocus()
self.angleValue.selectAll()

def validatePoint(self):
"function for checking and sending numbers entered manually"
Expand Down Expand Up @@ -1441,6 +1489,13 @@ def displayPoint(self, point=None, last=None, plane=None, mask=None):
self.zValue.setEnabled(True)
self.xValue.setFocus()
self.xValue.selectAll()

# set length and angle
if last and dp and plane:
self.lengthValue.setText(displayExternal(dp.Length,self.DECIMALS,'Length'))
a = math.degrees(-DraftVecUtils.angle(dp,plane.u,plane.axis))
self.angleValue.setText(displayExternal(a,self.DECIMALS,'Angle'))


def getDefaultColor(self,type,rgb=False):
"gets color from the preferences or toolbar"
Expand Down Expand Up @@ -1606,7 +1661,8 @@ def toggleradius(self,val):

def constrain(self,val):
if val == "angle":
FreeCADGui.Snapper.setAngle()
self.alock = not(self.alock)
self.angleLock.setChecked(self.alock)
elif self.mask == val:
self.mask = None
if hasattr(FreeCADGui,"Snapper"):
Expand Down Expand Up @@ -1636,6 +1692,29 @@ def changeSSizeValue(self,d):

def changeSTrackValue(self,d):
self.STrack = d

def changeLengthValue(self,d):
v = FreeCAD.Vector(self.x,self.y,self.z)
v = DraftVecUtils.scaleTo(v,d)
self.xValue.setText(displayExternal(v.x,self.DECIMALS,'Length'))
self.yValue.setText(displayExternal(v.y,self.DECIMALS,'Length'))
self.zValue.setText(displayExternal(v.z,self.DECIMALS,'Length'))

def changeAngleValue(self,d):
print d
v = FreeCAD.Vector(self.x,self.y,self.z)
a = DraftVecUtils.angle(v,FreeCAD.DraftWorkingPlane.u,FreeCAD.DraftWorkingPlane.axis)
a = math.radians(d)+a
v=DraftVecUtils.rotate(v,a,FreeCAD.DraftWorkingPlane.axis)
self.xValue.setText(displayExternal(v.x,self.DECIMALS,'Length'))
self.yValue.setText(displayExternal(v.y,self.DECIMALS,'Length'))
self.zValue.setText(displayExternal(v.z,self.DECIMALS,'Length'))

def toggleAngle(self,bool):
self.alock = self.angleLock.isChecked()
FreeCADGui.Snapper.setAngle()



#---------------------------------------------------------------------------
# TaskView operations
Expand Down

0 comments on commit 7d0dc06

Please sign in to comment.