diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index ce27b9ebda..fea8a7f78c 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -109,6 +109,7 @@ SET(Draft_make_functions draftmake/make_circulararray.py draftmake/make_clone.py draftmake/make_copy.py + draftmake/make_dimension.py draftmake/make_drawingview.py draftmake/make_ellipse.py draftmake/make_facebinder.py diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 6a71082317..a955bbdc9b 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -383,21 +383,22 @@ if FreeCAD.GuiUp: # Draft annotation objects #--------------------------------------------------------------------------- -from draftobjects.dimension import make_dimension, make_angular_dimension -from draftobjects.dimension import LinearDimension, AngularDimension +from draftobjects.dimension import (LinearDimension, + _Dimension, + AngularDimension, + _AngularDimension) -makeDimension = make_dimension -makeAngularDimension = make_angular_dimension -_Dimension = LinearDimension -_AngularDimension = AngularDimension +from draftmake.make_dimension import (make_dimension, + makeDimension, + make_angular_dimension, + makeAngularDimension) -if gui: +if FreeCAD.GuiUp: from draftviewproviders.view_dimension import ViewProviderLinearDimension from draftviewproviders.view_dimension import ViewProviderAngularDimension _ViewProviderDimension = ViewProviderLinearDimension _ViewProviderAngularDimension = ViewProviderAngularDimension - from draftobjects.label import (Label, DraftLabel) diff --git a/src/Mod/Draft/draftguitools/gui_dimensions.py b/src/Mod/Draft/draftguitools/gui_dimensions.py index a47234e17e..a73637b24f 100644 --- a/src/Mod/Draft/draftguitools/gui_dimensions.py +++ b/src/Mod/Draft/draftguitools/gui_dimensions.py @@ -31,13 +31,13 @@ and circular arcs. And it can also be an angular dimension measuring the angle between two straight lines. """ -## @package gui_texts +## @package gui_dimensions # \ingroup DRAFT # \brief Provides tools for creating dimensions with the Draft Workbench. import math +import lazy_loader.lazy_loader as lz from PySide.QtCore import QT_TRANSLATE_NOOP -import sys import FreeCAD as App import FreeCADGui as Gui @@ -49,6 +49,8 @@ import draftguitools.gui_trackers as trackers from draftutils.translate import translate from draftutils.messages import _msg +DraftGeomUtils = lz.LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils") + # The module is used to prevent complaints from code checkers (flake8) True if Draft_rc.__name__ else False @@ -71,14 +73,24 @@ class Dimension(gui_base_original.Creator): def GetResources(self): """Set icon, menu and tooltip.""" - _tip = ("Creates a dimension. " - "Select a straight line to create a linear dimension.\n" - "Select an arc or circle to create a radius or diameter " - "dimension.\n" - "Select two straight lines to create an angular dimension " + _tip = ("Creates a dimension.\n" + "\n" + "- Pick three points to create a simple linear dimension.\n" + "- Select a straight line to create a linear dimension " + "linked to that line.\n" + "- Select an arc or circle to create a radius or diameter " + "dimension linked to that arc.\n" + "- Select two straight lines to create an angular dimension " "between them.\n" "CTRL to snap, SHIFT to constrain, " - "ALT to select an edge or arc.") + "ALT to select an edge or arc.\n" + "\n" + "You may select a single line or single circular arc " + "before launching this command\n" + "to create the corresponding linked dimension.\n" + "You may also select an 'App::MeasureDistance' object " + "before launching this command\n" + "to turn it into a 'Draft Dimension' object.") return {'Pixmap': 'Draft_Dimension', 'Accel': "D, I", @@ -123,8 +135,6 @@ class Dimension(gui_base_original.Creator): def setFromSelection(self): """Fill the nodes according to the selected geometry.""" - import DraftGeomUtils - sel = Gui.Selection.getSelectionEx() if len(sel) == 1: if len(sel[0].SubElementNames) == 1: @@ -180,23 +190,22 @@ class Dimension(gui_base_original.Creator): pt = _ch.getChildren()[3] p3 = App.Vector(pt.point.getValues()[2].getValue()) Gui.addModule("Draft") - _cmd = 'Draft.makeDimension' + _cmd = 'Draft.make_dimension' _cmd += '(' _cmd += DraftVecUtils.toString(p1) + ', ' _cmd += DraftVecUtils.toString(p2) + ', ' _cmd += DraftVecUtils.toString(p3) _cmd += ')' _rem = 'FreeCAD.ActiveDocument.removeObject("' + o.Name + '")' - _cmd_list = ['dim = ' + _cmd, + _cmd_list = ['_dim_ = ' + _cmd, _rem, - 'Draft.autogroup(dim)', + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) def createObject(self): """Create the actual object in the current document.""" - import DraftGeomUtils Gui.addModule("Draft") if self.angledata: @@ -206,92 +215,96 @@ class Dimension(gui_base_original.Creator): v2 = DraftGeomUtils.vec(self.edges[1]) normal = DraftVecUtils.toString((v1.cross(v2)).normalize()) - _cmd = 'Draft.makeAngularDimension(' + _cmd = 'Draft.make_angular_dimension' + _cmd += '(' _cmd += 'center=' + DraftVecUtils.toString(self.center) + ', ' _cmd += 'angles=' _cmd += '[' - _cmd += str(self.angledata[0]) + ', ' - _cmd += str(self.angledata[1]) + _cmd += str(math.degrees(self.angledata[1])) + ', ' + _cmd += str(math.degrees(self.angledata[0])) _cmd += '], ' - _cmd += 'p3=' + DraftVecUtils.toString(self.node[-1]) + ', ' + _cmd += 'dim_line=' + DraftVecUtils.toString(self.node[-1]) + ', ' _cmd += 'normal=' + normal _cmd += ')' - _cmd_list = ['dim = ' + _cmd, - 'Draft.autogroup(dim)', + _cmd_list = ['_dim_ = ' + _cmd, + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) + elif self.link and not self.arcmode: - ops = [] # Linear dimension, linked if self.force == 1: - _cmd = 'Draft.makeDimension' + _cmd = 'Draft.make_dimension' _cmd += '(' _cmd += 'FreeCAD.ActiveDocument.' + self.link[0].Name + ', ' _cmd += str(self.link[1]) + ', ' _cmd += str(self.link[2]) + ', ' _cmd += DraftVecUtils.toString(self.node[2]) _cmd += ')' - _cmd_list = ['dim = ' + _cmd, - 'dim.Direction = FreeCAD.Vector(0, 1, 0)', - 'Draft.autogroup(dim)', + _cmd_list = ['_dim_ = ' + _cmd, + '_dim_.Direction = FreeCAD.Vector(0, 1, 0)', + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) elif self.force == 2: - _cmd = 'Draft.makeDimension' + _cmd = 'Draft.make_dimension' _cmd += '(' _cmd += 'FreeCAD.ActiveDocument.' + self.link[0].Name + ', ' _cmd += str(self.link[1]) + ', ' _cmd += str(self.link[2]) + ', ' _cmd += DraftVecUtils.toString(self.node[2]) _cmd += ')' - _cmd_list = ['dim = ' + _cmd, - 'dim.Direction = FreeCAD.Vector(1, 0, 0)', - 'Draft.autogroup(dim)', + _cmd_list = ['_dim_ = ' + _cmd, + '_dim_.Direction = FreeCAD.Vector(1, 0, 0)', + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) else: - _cmd = 'Draft.makeDimension' + _cmd = 'Draft.make_dimension' _cmd += '(' _cmd += 'FreeCAD.ActiveDocument.' + self.link[0].Name + ', ' _cmd += str(self.link[1]) + ', ' _cmd += str(self.link[2]) + ', ' _cmd += DraftVecUtils.toString(self.node[2]) _cmd += ')' - _cmd_list = ['dim = ' + _cmd, - 'Draft.autogroup(dim)', + _cmd_list = ['_dim_ = ' + _cmd, + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) + elif self.arcmode: # Radius or dimeter dimension, linked - _cmd = 'Draft.makeDimension' + _cmd = 'Draft.make_dimension' _cmd += '(' _cmd += 'FreeCAD.ActiveDocument.' + self.link[0].Name + ', ' _cmd += str(self.link[1]) + ', ' _cmd += '"' + str(self.arcmode) + '", ' _cmd += DraftVecUtils.toString(self.node[2]) _cmd += ')' - _cmd_list = ['dim = ' + _cmd, - 'Draft.autogroup(dim)', + _cmd_list = ['_dim_ = ' + _cmd, + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) + else: # Linear dimension, non-linked - _cmd = 'Draft.makeDimension' + _cmd = 'Draft.make_dimension' _cmd += '(' _cmd += DraftVecUtils.toString(self.node[0]) + ', ' _cmd += DraftVecUtils.toString(self.node[1]) + ', ' _cmd += DraftVecUtils.toString(self.node[2]) _cmd += ')' - _cmd_list = ['dim = ' + _cmd, - 'Draft.autogroup(dim)', + _cmd_list = ['_dim_ = ' + _cmd, + 'Draft.autogroup(_dim_)', 'FreeCAD.ActiveDocument.recompute()'] self.commit(translate("draft", "Create Dimension"), _cmd_list) + if self.ui.continueMode: self.cont = self.node[2] if not self.dir: @@ -323,7 +336,6 @@ class Dimension(gui_base_original.Creator): if arg["Key"] == "ESCAPE": self.finish() elif arg["Type"] == "SoLocation2Event": # mouse movement detection - import DraftGeomUtils shift = gui_tool_utils.hasMod(arg, gui_tool_utils.MODCONSTRAIN) if self.arcmode or self.point2: gui_tool_utils.setMod(arg, gui_tool_utils.MODCONSTRAIN, False) @@ -423,7 +435,6 @@ class Dimension(gui_base_original.Creator): gui_tool_utils.redraw3DView() elif arg["Type"] == "SoMouseButtonEvent": if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"): - import DraftGeomUtils if self.point: self.ui.redraw() if (not self.node) and (not self.support): diff --git a/src/Mod/Draft/draftmake/make_dimension.py b/src/Mod/Draft/draftmake/make_dimension.py new file mode 100644 index 0000000000..b3016c14ea --- /dev/null +++ b/src/Mod/Draft/draftmake/make_dimension.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * Copyright (c) 2020 Eliud Cabrera Castillo * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""Provides functions to crate dimension objects.""" +## @package make_dimension +# \ingroup DRAFT +# \brief Provides functions to crate dimension objects. + +import math + +import FreeCAD as App +import draftutils.utils as utils +import draftutils.gui_utils as gui_utils + +from draftutils.messages import _msg, _wrn, _err +from draftutils.translate import _tr +from draftobjects.dimension import (LinearDimension, + AngularDimension) + +if App.GuiUp: + from draftviewproviders.view_dimension import ViewProviderLinearDimension + from draftviewproviders.view_dimension import ViewProviderAngularDimension + + +def make_dimension(p1, p2, p3=None, p4=None): + """Create one of three types of dimension objects. + + In all dimensions the p3 parameter defines a point through which + the dimension line will go through. + + The current line width and color will be used. + + Linear dimension + ---------------- + - (p1, p2, p3): a simple linear dimension from p1 to p2 + + - (object, i1, i2, p3): creates a linked dimension to the provided + object (edge), measuring the distance between its vertices + indexed i1 and i2 + + Circular dimension + ------------------ + - (arc, i1, mode, p3): creates a linked dimension to the given arc + object, i1 is the index of the arc edge that will be measured; + mode is either "radius" or "diameter". + """ + if not App.ActiveDocument: + _err("No active document. Aborting") + return None + + new_obj = App.ActiveDocument.addObject("App::FeaturePython", + "Dimension") + LinearDimension(new_obj) + + if App.GuiUp: + ViewProviderLinearDimension(new_obj.ViewObject) + + if isinstance(p1, App.Vector) and isinstance(p2, App.Vector): + # Measure a straight distance between p1 and p2 + new_obj.Start = p1 + new_obj.End = p2 + if not p3: + p3 = p2.sub(p1) + p3.multiply(0.5) + p3 = p1.add(p3) + + elif isinstance(p2, int) and isinstance(p3, int): + # p1 is an object, and measure the distance between vertices p2 and p3 + # of this object + linked = [] + idx = (p2, p3) + linked.append((p1, "Vertex" + str(p2 + 1))) + linked.append((p1, "Vertex" + str(p3 + 1))) + new_obj.LinkedGeometry = linked + new_obj.Support = p1 + + # p4, and now p3, is the point through which the dimension line + # will go through + p3 = p4 + if not p3: + # When used from the GUI command, this will never run + # because p4 will always be assinged to a vector, + # so p3 will never be `None`. + # Moreover, `new_obj.Base` doesn't exist, and certainly `Shape` + # doesn't exist, so if this ever runs it will be an error. + v1 = new_obj.Base.Shape.Vertexes[idx[0]].Point + v2 = new_obj.Base.Shape.Vertexes[idx[1]].Point + p3 = v2.sub(v1) + p3.multiply(0.5) + p3 = v1.add(p3) + + elif isinstance(p3, str): + # If the original p3 is a string, we are measuring a circular arc + # p2 should be an integer number starting from 0 + linked = [] + linked.append((p1, "Edge" + str(p2 + 1))) + + if p3 == "radius": + # linked.append((p1, "Center")) + if App.GuiUp: + new_obj.ViewObject.Override = "R $dim" + new_obj.Diameter = False + elif p3 == "diameter": + # linked.append((p1, "Diameter")) + if App.GuiUp: + new_obj.ViewObject.Override = "Ø $dim" + new_obj.Diameter = True + new_obj.LinkedGeometry = linked + new_obj.Support = p1 + + # p4, and now p3, is the point through which the dimension line + # will go through + p3 = p4 + if not p3: + p3 = p1.Shape.Edges[p2].Curve.Center.add(App.Vector(1, 0, 0)) + + # This p3 is the point through which the dimension line will pass, + # but this may not be the original p3, it could have been p4 + # depending on the first three parameter values + new_obj.Dimline = p3 + + if hasattr(App, "DraftWorkingPlane"): + normal = App.DraftWorkingPlane.axis + else: + normal = App.Vector(0, 0, 1) + + if App.GuiUp: + # invert the normal if we are viewing it from the back + vnorm = gui_utils.get3DView().getViewDirection() + + if vnorm.getAngle(normal) < math.pi/2: + normal = normal.negative() + + new_obj.Normal = normal + + if App.GuiUp: + gui_utils.format_object(new_obj) + gui_utils.select(new_obj) + + return new_obj + + +def makeDimension(p1, p2, p3=None, p4=None): + """Create a dimension. DEPRECATED. Use 'make_dimension'.""" + _wrn(_tr("This function is deprecated. " + "Do not use this function directly.")) + _wrn(_tr("Use one of 'make_linear_dimension', or " + "'make_linear_dimension_obj'.")) + + return make_dimension(p1, p2, p3, p4) + + +def make_angular_dimension(center=App.Vector(0, 0, 0), + angles=[0, 90], + dim_line=App.Vector(3, 3, 0), normal=None): + """Create an angular dimension from the given center and angles. + + Parameters + ---------- + center: Base::Vector3, optional + It defaults to the origin `Vector(0, 0, 0)`. + Center of the dimension line, which is a circular arc. + + angles: list of two floats, optional + It defaults to `[0, 90]`. + It is a list of two angles, given in degrees, that determine + the apperture of the dimension line, that is, of the circular arc. + It is drawn counter-clockwise. + :: + angles = [0 90] + angles = [330 60] # the arc crosses the X axis + angles = [-30 60] # same angle + + dim_line: Base::Vector3, optional + It defaults to `Vector(3, 3, 0)`. + Point through which the dimension line will pass. + This defines the radius of the dimension line, the circular arc. + + normal: Base::Vector3, optional + It defaults to `None`, in which case the `normal` is taken + from the currently active `App.DraftWorkingPlane.axis`. + + If the working plane is not available, then the `normal` + defaults to +Z or `Vector(0, 0, 1)`. + + Returns + ------- + App::FeaturePython + A scripted object of type `'AngularDimension'`. + This object does not have a `Shape` attribute, as the text and lines + are created on screen by Coin (pivy). + + None + If there is a problem it will return `None`. + """ + _name = "make_angular_dimension" + utils.print_header(_name, "Angular dimension") + + found, doc = utils.find_doc(App.activeDocument()) + if not found: + _err(_tr("No active document. Aborting.")) + return None + + _msg("center: {}".format(center)) + try: + utils.type_check([(center, App.Vector)], name=_name) + except TypeError: + _err(_tr("Wrong input: must be a vector.")) + return None + + _msg("angles: {}".format(angles)) + try: + utils.type_check([(angles, (tuple, list))], name=_name) + + if len(angles) != 2: + _err(_tr("Wrong input: must be a list with two angles.")) + return None + + ang1, ang2 = angles + utils.type_check([(ang1, (int, float)), + (ang2, (int, float))], name=_name) + except TypeError: + _err(_tr("Wrong input: must be a list with two angles.")) + return None + + # If the angle is larger than 360 degrees, make sure + # it is smaller than 360 + for n in range(len(angles)): + if angles[n] > 360: + angles[n] = angles[n] - 360 + + _msg("dim_line: {}".format(dim_line)) + try: + utils.type_check([(dim_line, App.Vector)], name=_name) + except TypeError: + _err(_tr("Wrong input: must be a vector.")) + return None + + _msg("normal: {}".format(normal)) + if normal: + try: + utils.type_check([(dim_line, App.Vector)], name=_name) + except TypeError: + _err(_tr("Wrong input: must be a vector.")) + return None + + if not normal: + if hasattr(App, "DraftWorkingPlane"): + normal = App.DraftWorkingPlane.axis + else: + normal = App.Vector(0, 0, 1) + + new_obj = App.ActiveDocument.addObject("App::FeaturePython", + "Dimension") + AngularDimension(new_obj) + + new_obj.Center = center + new_obj.FirstAngle = angles[0] + new_obj.LastAngle = angles[1] + new_obj.Dimline = dim_line + + if App.GuiUp: + ViewProviderAngularDimension(new_obj.ViewObject) + + # Invert the normal if we are viewing it from the back. + # This is determined by the angle between the current + # 3D view and the provided normal being below 90 degrees + vnorm = gui_utils.get3DView().getViewDirection() + if vnorm.getAngle(normal) < math.pi/2: + normal = normal.negative() + + new_obj.Normal = normal + + if App.GuiUp: + gui_utils.format_object(new_obj) + gui_utils.select(new_obj) + + return new_obj + + +def makeAngularDimension(center, angles, p3, normal=None): + """Create an angle dimension. DEPRECATED. Use 'make_angular_dimension'.""" + utils.use_instead("make_angular_dimension") + + ang1, ang2 = angles + angles = [math.degrees(ang2), math.degrees(ang1)] + + return make_angular_dimension(center=center, angles=angles, + dim_line=p3, normal=normal) diff --git a/src/Mod/Draft/draftobjects/dimension.py b/src/Mod/Draft/draftobjects/dimension.py index fbd1961753..914d3e6696 100644 --- a/src/Mod/Draft/draftobjects/dimension.py +++ b/src/Mod/Draft/draftobjects/dimension.py @@ -22,152 +22,32 @@ # * USA * # * * # *************************************************************************** -"""This module provides the object code for Draft Dimension. -""" +"""This module provides the object code for Draft Dimension.""" ## @package dimension # \ingroup DRAFT # \brief This module provides the object code for Draft Dimension. -import FreeCAD as App -import math from PySide.QtCore import QT_TRANSLATE_NOOP -import DraftGeomUtils, DraftVecUtils -import draftutils.gui_utils as gui_utils + +import FreeCAD as App +import DraftVecUtils +import DraftGeomUtils import draftutils.utils as utils + from draftobjects.draft_annotation import DraftAnnotation -if App.GuiUp: - from draftviewproviders.view_dimension import ViewProviderDimensionBase - from draftviewproviders.view_dimension import ViewProviderLinearDimension - from draftviewproviders.view_dimension import ViewProviderAngularDimension - -def make_dimension(p1,p2,p3=None,p4=None): - """makeDimension(p1,p2,[p3]) or makeDimension(object,i1,i2,p3) - or makeDimension(objlist,indices,p3): Creates a Dimension object with - the dimension line passign through p3.The current line width and color - will be used. There are multiple ways to create a dimension, depending on - the arguments you pass to it: - - (p1,p2,p3): creates a standard dimension from p1 to p2 - - (object,i1,i2,p3): creates a linked dimension to the given object, - measuring the distance between its vertices indexed i1 and i2 - - (object,i1,mode,p3): creates a linked dimension - to the given object, i1 is the index of the (curved) edge to measure, - and mode is either "radius" or "diameter". - """ - if not App.ActiveDocument: - App.Console.PrintError("No active document. Aborting\n") - return - obj = App.ActiveDocument.addObject("App::FeaturePython","Dimension") - LinearDimension(obj) - if App.GuiUp: - ViewProviderLinearDimension(obj.ViewObject) - if isinstance(p1,App.Vector) and isinstance(p2,App.Vector): - obj.Start = p1 - obj.End = p2 - if not p3: - p3 = p2.sub(p1) - p3.multiply(0.5) - p3 = p1.add(p3) - elif isinstance(p2,int) and isinstance(p3,int): - l = [] - idx = (p2,p3) - l.append((p1,"Vertex"+str(p2+1))) - l.append((p1,"Vertex"+str(p3+1))) - obj.LinkedGeometry = l - obj.Support = p1 - p3 = p4 - if not p3: - v1 = obj.Base.Shape.Vertexes[idx[0]].Point - v2 = obj.Base.Shape.Vertexes[idx[1]].Point - p3 = v2.sub(v1) - p3.multiply(0.5) - p3 = v1.add(p3) - elif isinstance(p3,str): - l = [] - l.append((p1,"Edge"+str(p2+1))) - if p3 == "radius": - #l.append((p1,"Center")) - if App.GuiUp: - obj.ViewObject.Override = "R $dim" - obj.Diameter = False - elif p3 == "diameter": - #l.append((p1,"Diameter")) - if App.GuiUp: - obj.ViewObject.Override = "Ø $dim" - obj.Diameter = True - obj.LinkedGeometry = l - obj.Support = p1 - p3 = p4 - if not p3: - p3 = p1.Shape.Edges[p2].Curve.Center.add(App.Vector(1,0,0)) - obj.Dimline = p3 - if hasattr(App,"DraftWorkingPlane"): - normal = App.DraftWorkingPlane.axis - else: - normal = App.Vector(0,0,1) - if App.GuiUp: - # invert the normal if we are viewing it from the back - vnorm = gui_utils.get3DView().getViewDirection() - if vnorm.getAngle(normal) < math.pi/2: - normal = normal.negative() - obj.Normal = normal - - if App.GuiUp: - gui_utils.format_object(obj) - gui_utils.select(obj) - - return obj - - -def make_angular_dimension(center,angles,p3,normal=None): - """makeAngularDimension(center,angle1,angle2,p3,[normal]): creates an angular Dimension - from the given center, with the given list of angles, passing through p3. - """ - if not App.ActiveDocument: - App.Console.PrintError("No active document. Aborting\n") - return - obj = App.ActiveDocument.addObject("App::FeaturePython","Dimension") - AngularDimension(obj) - if App.GuiUp: - ViewProviderAngularDimension(obj.ViewObject) - obj.Center = center - for a in range(len(angles)): - if angles[a] > 2*math.pi: - angles[a] = angles[a]-(2*math.pi) - obj.FirstAngle = math.degrees(angles[1]) - obj.LastAngle = math.degrees(angles[0]) - obj.Dimline = p3 - if not normal: - if hasattr(App,"DraftWorkingPlane"): - normal = App.DraftWorkingPlane.axis - else: - normal = App.Vector(0,0,1) - if App.GuiUp: - # invert the normal if we are viewing it from the back - vnorm = gui_utils.get3DView().getViewDirection() - if vnorm.getAngle(normal) < math.pi/2: - normal = normal.negative() - - obj.Normal = normal - - if App.GuiUp: - gui_utils.format_object(obj) - gui_utils.select(obj) - - return obj - - class DimensionBase(DraftAnnotation): - """ - The Draft Dimension Base object + """The base objects for dimension objects. + + This class inherits `DraftAnnotation` to define the basic properties + of all annotation type objects, like a scaling multiplier. + This class is not used directly, but inherited by all dimension objects. """ - def __init__(self, obj, tp = "Dimension"): - """Add common dimension properties to the object and set them""" - + def __init__(self, obj, tp="Dimension"): super(DimensionBase, self).__init__(obj, tp) # Draft @@ -190,21 +70,12 @@ class DimensionBase(DraftAnnotation): def onDocumentRestored(self, obj): super(DimensionBase, self).onDocumentRestored(obj) - def execute(self, obj): - '''Do something when recompute object''' - - return - - - def onChanged(self,obj,prop): - '''Do something when a property has changed''' - - return - class LinearDimension(DimensionBase): - """ - The Draft Linear Dimension object + """The linear dimension object. + + This inherits `DimensionBase` to provide the basic functionality of + a dimension. """ def __init__(self, obj): @@ -238,7 +109,6 @@ class LinearDimension(DimensionBase): obj.Start = App.Vector(0,0,0) obj.End = App.Vector(1,0,0) - def onDocumentRestored(self, obj): super(LinearDimension, self).onDocumentRestored(obj) @@ -251,7 +121,6 @@ class LinearDimension(DimensionBase): if hasattr(obj, "Support"): obj.setEditorMode('Support', 2) - def execute(self, obj): """ Set start point and end point according to the linked geometry""" if obj.LinkedGeometry: @@ -308,20 +177,21 @@ class LinearDimension(DimensionBase): obj.ViewObject.update() +# Alias for compatibility with v0.18 and earlier +_Dimension = LinearDimension + class AngularDimension(DimensionBase): - """ - The Draft AngularDimension object + """The angular dimension object. + + This inherits `DimensionBase` to provide the basic functionality of + a dimension. """ def __init__(self, obj): - super(AngularDimension, self).__init__(obj, "AngularDimension") - self.init_properties(obj) - - obj.Proxy = self - + obj.Proxy = self def init_properties(self, obj): """Add Angular Dimension specific properties to the object and set them""" @@ -352,7 +222,6 @@ class AngularDimension(DimensionBase): if fp.ViewObject: fp.ViewObject.update() - def onChanged(self,obj,prop): '''Do something when a property has changed''' super(AngularDimension, self).onChanged(obj, prop) @@ -362,3 +231,7 @@ class AngularDimension(DimensionBase): obj.setEditorMode('Normal',2) if hasattr(obj,"Support"): obj.setEditorMode('Support',2) + + +# Alias for compatibility with v0.18 and earlier +_AngularDimension = AngularDimension diff --git a/src/Mod/Draft/drafttests/draft_test_objects.py b/src/Mod/Draft/drafttests/draft_test_objects.py index a734e38771..913c01395a 100644 --- a/src/Mod/Draft/drafttests/draft_test_objects.py +++ b/src/Mod/Draft/drafttests/draft_test_objects.py @@ -39,7 +39,6 @@ Or load it as a module and use the defined function. # @{ import datetime -import math import os import FreeCAD as App @@ -260,8 +259,8 @@ def _create_objects(doc=None, _msg("Angular dimension") Draft.make_line(Vector(10500, 300, 0), Vector(11500, 1000, 0)) Draft.make_line(Vector(10500, 300, 0), Vector(11500, 0, 0)) - angle1 = math.radians(40) - angle2 = math.radians(-20) + angle1 = -20 + angle2 = 40 dimension_a = Draft.make_angular_dimension(Vector(10500, 300, 0), [angle1, angle2], Vector(11500, 300, 0)) diff --git a/src/Mod/Draft/drafttests/test_creation.py b/src/Mod/Draft/drafttests/test_creation.py index 59e864002e..3fb41cbcf2 100644 --- a/src/Mod/Draft/drafttests/test_creation.py +++ b/src/Mod/Draft/drafttests/test_creation.py @@ -24,7 +24,6 @@ """Unit test for the Draft Workbench, object creation tests.""" import unittest -import math import FreeCAD as App import Draft @@ -210,14 +209,13 @@ class DraftCreation(unittest.TestCase): _msg(" Test '{}'".format(operation)) _msg(" Occasionally crashes") center = Vector(0, 0, 0) - angle1 = math.radians(60) - angle2 = math.radians(10) - p3 = Vector(3, 1, 0) + angle1 = 20 + angle2 = 70 + dim_line = Vector(3, 1, 0) _msg(" center={}".format(center)) - _msg(" angle1={0}, angle2={1}".format(math.degrees(angle1), - math.degrees(angle2))) - _msg(" point={}".format(p3)) - obj = Draft.make_angular_dimension(center, [angle1, angle2], p3) + _msg(" angle1={0}, angle2={1}".format(angle1, angle2)) + _msg(" dim_line={}".format(dim_line)) + obj = Draft.make_angular_dimension(center, [angle1, angle2], dim_line) self.assertTrue(obj, "'{}' failed".format(operation)) def test_bspline(self):