| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| """ |
| Provides the TechDraw AxoLengthDimension GuiCommand. |
| 00.01 2023/02/01 Basic version |
| 00.02 2023/12/07 Calculate real 3D values if parallel to coordinate axis |
| """ |
|
|
| __title__ = "TechDrawTools.CommandAxoLengthDimension" |
| __author__ = "edi" |
| __url__ = "https://www.freecad.org" |
| __version__ = "00.02" |
| __date__ = "2023/12/07" |
|
|
| from PySide.QtCore import QT_TRANSLATE_NOOP |
|
|
| import FreeCAD as App |
| import FreeCADGui as Gui |
|
|
| import TechDrawTools.TDToolsUtil as Utils |
|
|
| import TechDraw |
| import math |
|
|
| |
| |
| |
| def makePlumb(dimensionLineAngle): |
| HalfPi = math.pi / 2.0 |
| |
| AngularTolerance = 0.01 |
| |
|
|
| if math.isclose(dimensionLineAngle, HalfPi, abs_tol=AngularTolerance): |
| return HalfPi |
| elif math.isclose(dimensionLineAngle, -HalfPi, abs_tol=AngularTolerance): |
| return -HalfPie |
| |
| return dimensionLineAngle |
| |
|
|
| class CommandAxoLengthDimension: |
| """Creates a 3D length dimension.""" |
|
|
| def __init__(self): |
| """Initialize variables for the command that must exist at all times.""" |
| pass |
|
|
| def GetResources(self): |
| """Return a dictionary with data that will be used by the button or menu item.""" |
| return {'Pixmap': 'actions/TechDraw_AxoLengthDimension.svg', |
| 'Accel': "", |
| 'MenuText': QT_TRANSLATE_NOOP("TechDraw_AxoLengthDimension", "Axonometric Length Dimension"), |
| 'ToolTip': QT_TRANSLATE_NOOP("TechDraw_AxoLengthDimension", "Creates a length dimension in with " |
| "axonometric view, using selected edges or vertex pairs to define direction and measurement")} |
|
|
| def Activated(self): |
| """Run the following code when the command is activated (button press).""" |
|
|
| App.setActiveTransaction("Create axonometric length dimension") |
| vertexes = [] |
| edges = [] |
|
|
| if not Utils.getSelEdges(2): |
| return |
| |
| edges = Utils.getSelEdges(2) |
| vertexes = Utils.getSelVertexes(0) |
|
|
| vertNames = list() |
| edgeNames = list() |
| if len(vertexes)<2: |
| vertexes.append(edges[0].Vertexes[0]) |
| vertexes.append(edges[0].Vertexes[1]) |
| edgeNames = Utils.getSelEdgeNames(2) |
| else: |
| vertNames = Utils.getSelVertexNames(2) |
|
|
| view = Utils.getSelView() |
| page = view.findParentPage() |
| scale = view.getScale() |
|
|
| StartPt, EndPt = edges[1].Vertexes[0].Point, edges[1].Vertexes[1].Point |
| extLineVec = EndPt.sub(StartPt) |
| StartPt, EndPt = edges[0].Vertexes[0].Point, edges[0].Vertexes[1].Point |
| dimLineVec = EndPt.sub(StartPt) |
|
|
| xAxis = App.Vector(1,0,0) |
| extAngle = math.degrees(extLineVec.getAngle(xAxis)) |
| lineAngle = math.degrees(makePlumb(dimLineVec.getAngle(xAxis))) |
|
|
| if extLineVec.y < 0.0: |
| extAngle = 180-extAngle |
| if dimLineVec.y < 0.0: |
| lineAngle = 180-lineAngle |
|
|
| if abs(extAngle-lineAngle)>0.1: |
| |
| |
| |
| |
| |
| |
| distanceDim = view.Document.addObject("TechDraw::DrawViewDimension", "Dimension") |
| distanceDim.Type = "Distance" |
| distanceDim.MeasureType = "Projected" |
| self.setReferences(distanceDim, view, edgeNames, vertNames) |
| page.addView(distanceDim) |
|
|
| distanceDim.AngleOverride = True |
| distanceDim.LineAngle = lineAngle |
| distanceDim.ExtensionAngle = extAngle |
|
|
| distanceDim.recompute() |
|
|
| |
| linearPoints = distanceDim.getLinearPoints() |
| mid = (linearPoints[0] + linearPoints[1]) / 2 |
| distanceDim.X = mid.x |
| distanceDim.Y = -mid.y |
|
|
| (px,py,pz) = Utils.getCoordinateVectors(view) |
| arrowTips = distanceDim.getArrowPositions() |
| value2D = (arrowTips[1].sub(arrowTips[0])).Length |
| value3D = 1.0 |
| if px.isParallel(dimLineVec,0.1): |
| value3D = value2D/px.Length |
| elif py.isParallel(dimLineVec,0.1): |
| value3D = value2D/py.Length |
| elif pz.isParallel(dimLineVec,0.1): |
| value3D = value2D/pz.Length |
| if value3D != 1.0: |
| fomatted3DValue = self._formatValueToSpec(value3D,distanceDim.FormatSpec) |
| distanceDim.Arbitrary = True |
| distanceDim.Label = distanceDim.Label.replace('Dimension','Dimension3D') |
| distanceDim.FormatSpec = fomatted3DValue |
|
|
| distanceDim.recompute() |
| view.requestPaint() |
|
|
| Gui.Selection.clearSelection() |
| App.closeActiveTransaction() |
| view.touch() |
|
|
| def IsActive(self): |
| """Return True when the command should be active or False when it should be disabled (greyed).""" |
| if App.ActiveDocument: |
| return Utils.havePage() and Utils.haveView() |
| else: |
| return False |
|
|
| def _formatValueToSpec(self, value, formatSpec): |
| '''Calculate value using "%.nf" or "%.nw" formatSpec''' |
| formatSpec = '{'+formatSpec+'}' |
| formatSpec = formatSpec.replace('%',':') |
| if formatSpec.find('w') > 0: |
| formatSpec = formatSpec.replace('w','f') |
| numDig = formatSpec.find(":.") |
| if numDig != -1: |
| numDig = numDig+2 |
| charList = list(formatSpec) |
| digits = int(charList[numDig]) |
| value = round(value,digits) |
| strValue = formatSpec.format(value) |
| strValueList = list(strValue) |
| while strValueList[-1] == '0': |
| strValueList.pop() |
| if strValueList[-1] == '.': |
| strValueList.pop() |
| return ''.join(strValueList) |
| else: |
| return formatSpec.format(value) |
|
|
| def setReferences(self, dimension, view, edgeNameList, vertexNameList): |
| references = list() |
| if vertexNameList: |
| for vert in vertexNameList: |
| references.append((view, vert)) |
| else: |
| references.append((view, edgeNameList[0])) |
|
|
| dimension.References2D = references |
|
|
| |
| |
| Gui.addCommand('TechDraw_AxoLengthDimension', CommandAxoLengthDimension()) |
|
|