diff --git a/src/Mod/Draft/draftfunctions/dxf.py b/src/Mod/Draft/draftfunctions/dxf.py index c5ec52ae69..1236c4fdef 100644 --- a/src/Mod/Draft/draftfunctions/dxf.py +++ b/src/Mod/Draft/draftfunctions/dxf.py @@ -77,8 +77,8 @@ def get_dxf(obj, direction=None): if direction and isinstance(direction, App.Vector): if direction != App.Vector(0, 0, 0): - plane = WorkingPlane.Plane() - plane.alignToPointAndAxis(App.Vector(0, 0, 0), direction) + plane = WorkingPlane.PlaneBase() + plane.align_to_point_and_axis(App.Vector(0, 0, 0), direction) if utils.get_type(obj) in ("Dimension", "LinearDimension"): p1 = _get_proj(obj.Start, plane=plane) diff --git a/src/Mod/Draft/draftfunctions/mirror.py b/src/Mod/Draft/draftfunctions/mirror.py index 206cd5dce2..ba62fde797 100644 --- a/src/Mod/Draft/draftfunctions/mirror.py +++ b/src/Mod/Draft/draftfunctions/mirror.py @@ -33,9 +33,10 @@ It just creates a `Part::Mirroring` object, and sets the appropriate ## \addtogroup draftfunctions # @{ import FreeCAD as App -import draftutils.utils as utils -import draftutils.gui_utils as gui_utils +import WorkingPlane +from draftutils import gui_utils +from draftutils import utils from draftutils.messages import _err from draftutils.translate import translate @@ -48,14 +49,7 @@ def mirror(objlist, p1, p2): It creates a `Part::Mirroring` object from the given `objlist` using a plane that is defined by the two given points `p1` and `p2`, - and either - - - the Draft working plane normal, or - - the negative normal provided by the camera direction - if the working plane normal does not exist and the graphical interface - is available. - - If neither of these two is available, it uses as normal the +Z vector. + and the Draft working plane normal. Parameters ---------- @@ -67,7 +61,7 @@ def mirror(objlist, p1, p2): of the resulting object. p2: Base::Vector3 - Point 1 of the mirror plane. + Point 2 of the mirror plane. Returns ------- @@ -97,13 +91,7 @@ def mirror(objlist, p1, p2): if not isinstance(objlist, list): objlist = [objlist] - if hasattr(App, "DraftWorkingPlane"): - norm = App.DraftWorkingPlane.getNormal() - elif App.GuiUp: - norm = Gui.ActiveDocument.ActiveView.getViewDirection().negative() - else: - norm = App.Vector(0, 0, 1) - + norm = WorkingPlane.get_working_plane(update=False).axis pnorm = p2.sub(p1).cross(norm).normalize() result = [] diff --git a/src/Mod/Draft/draftfunctions/svg.py b/src/Mod/Draft/draftfunctions/svg.py index 2a900f9231..cc55fef12c 100644 --- a/src/Mod/Draft/draftfunctions/svg.py +++ b/src/Mod/Draft/draftfunctions/svg.py @@ -396,7 +396,7 @@ def get_svg(obj, direction: Base::Vector3, optional It defaults to `None`. - It is an arbitrary projection vector or a `WorkingPlane.Plane` + It is an arbitrary projection vector or a `WorkingPlane.PlaneBase` instance. linestyle: optional @@ -462,13 +462,13 @@ def get_svg(obj, if direction: if isinstance(direction, App.Vector): if direction != App.Vector(0, 0, 0): - plane = WorkingPlane.plane() - plane.alignToPointAndAxis_SVG(App.Vector(0, 0, 0), - direction.negative().negative(), - 0) + plane = WorkingPlane.PlaneBase() + plane.align_to_point_and_axis_svg(App.Vector(0, 0, 0), + direction.negative().negative(), + 0) else: raise ValueError("'direction' cannot be: Vector(0, 0, 0)") - elif isinstance(direction, WorkingPlane.plane): + elif isinstance(direction, WorkingPlane.PlaneBase): plane = direction stroke = "#000000" diff --git a/src/Mod/Draft/draftfunctions/svgshapes.py b/src/Mod/Draft/draftfunctions/svgshapes.py index 33df138a70..eace6c12c1 100644 --- a/src/Mod/Draft/draftfunctions/svgshapes.py +++ b/src/Mod/Draft/draftfunctions/svgshapes.py @@ -32,6 +32,7 @@ import lazy_loader.lazy_loader as lz import FreeCAD as App import DraftVecUtils +import WorkingPlane import draftutils.utils as utils from draftutils.messages import _msg, _wrn @@ -58,8 +59,8 @@ def get_proj(vec, plane=None): vec: Base::Vector3 An arbitrary vector that will be projected on the U and V directions. - plane: WorkingPlane.Plane - An object of type `WorkingPlane`. + plane: WorkingPlane.PlaneBase + Working plane. """ if not plane: return vec @@ -124,13 +125,10 @@ def _get_path_circ_ellipse(plane, edge, verts, edata, iscircle, isellipse, fill, stroke, linewidth, lstyle): """Get the edge data from a path that is a circle or ellipse.""" - if hasattr(App, "DraftWorkingPlane"): - drawing_plane_normal = App.DraftWorkingPlane.axis - else: - drawing_plane_normal = App.Vector(0, 0, 1) - if plane: drawing_plane_normal = plane.axis + else: + drawing_plane_normal = WorkingPlane.get_working_plane(update=False).axis center = edge.Curve ax = center.Axis @@ -272,13 +270,10 @@ def get_circle(plane, cen = get_proj(edge.Curve.Center, plane) rad = edge.Curve.Radius - if hasattr(App, "DraftWorkingPlane"): - drawing_plane_normal = App.DraftWorkingPlane.axis - else: - drawing_plane_normal = App.Vector(0, 0, 1) - if plane: drawing_plane_normal = plane.axis + else: + drawing_plane_normal = WorkingPlane.get_working_plane(update=False).axis if round(edge.Curve.Axis.getAngle(drawing_plane_normal), 2) in [0, 3.14]: # Perpendicular projection: circle diff --git a/src/Mod/Draft/draftgeoutils/wires.py b/src/Mod/Draft/draftgeoutils/wires.py index 45dec6d4bc..47541857ed 100644 --- a/src/Mod/Draft/draftgeoutils/wires.py +++ b/src/Mod/Draft/draftgeoutils/wires.py @@ -35,6 +35,7 @@ import WorkingPlane from draftgeoutils.general import geomType, vec, precision from draftgeoutils.geometry import get_normal +from draftgeoutils.geometry import project_point_on_plane from draftgeoutils.edges import findMidpoint, isLine # Delay import of module until first use because it is heavy @@ -169,9 +170,7 @@ def flattenWire(wire, origin=None, normal=None): if origin is None: origin = wire.Vertexes[0].Point - plane = WorkingPlane.plane() - plane.alignToPointAndAxis(origin, normal, 0) - points = [plane.projectPoint(vert.Point) for vert in wire.Vertexes] + points = [project_point_on_plane(vert.Point, origin, normal) vert in wire.Vertexes] if wire.isClosed(): points.append(points[0]) new_wire = Part.makePolygon(points) diff --git a/src/Mod/Draft/draftguitools/__init__.py b/src/Mod/Draft/draftguitools/__init__.py index a269186771..e5ae062e57 100644 --- a/src/Mod/Draft/draftguitools/__init__.py +++ b/src/Mod/Draft/draftguitools/__init__.py @@ -46,19 +46,16 @@ as they normally require graphical input in the task panel or a selection in the 3D view (`Gui.Selection`). Most of these GUI tools require certain components of Draft to exist -like the `gui_snapper.Snapper`, the `WorkingPlane.Plane`, -and the `DraftGui.DraftToolBar` classes. -These classes are normally installed in the global `App` or `Gui` -namespaces, so they are accessible at all times. +like the `gui_snapper.Snapper`and the `DraftGui.DraftToolBar` classes. +These classes are normally installed in the global `Gui` namespace, +so they are accessible at all times. :: import DraftGui import draftguitools.gui_snapper - import WorkingPlane Gui.draftToolBar = DraftGui.DraftToolBar() Gui.Snapper = draftguitools.gui_snapper.Snapper() - App.DraftWorkingPlane = WorkingPlane.Plane() These classes can be imported and initialized individually but it is easier to set them up just by importing `DraftTools`. diff --git a/src/Mod/Draft/draftmake/make_dimension.py b/src/Mod/Draft/draftmake/make_dimension.py index aecd4b48c5..95823151ac 100644 --- a/src/Mod/Draft/draftmake/make_dimension.py +++ b/src/Mod/Draft/draftmake/make_dimension.py @@ -36,13 +36,14 @@ This includes linear dimensions, radial dimensions, and angular dimensions. import math import FreeCAD as App -import draftutils.utils as utils -import draftutils.gui_utils as gui_utils +import WorkingPlane +from draftutils import gui_utils +from draftutils import utils from draftutils.messages import _msg, _wrn, _err from draftutils.translate import translate -from draftobjects.dimension import (LinearDimension, - AngularDimension) + +from draftobjects.dimension import LinearDimension, AngularDimension if App.GuiUp: from draftviewproviders.view_dimension \ @@ -147,10 +148,7 @@ def make_dimension(p1, p2, p3=None, p4=None): # 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) + normal = WorkingPlane.get_working_plane(update=False).axis if App.GuiUp: # invert the normal if we are viewing it from the back @@ -536,11 +534,8 @@ def make_angular_dimension(center=App.Vector(0, 0, 0), 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)`. + It defaults to `None`, in which case the axis of the current working + plane is used. Returns ------- @@ -607,11 +602,8 @@ def make_angular_dimension(center=App.Vector(0, 0, 0), _err(translate("draft","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) + if normal is not None: + normal = WorkingPlane.get_working_plane(update=False).axis new_obj = App.ActiveDocument.addObject("App::FeaturePython", "Dimension") diff --git a/src/Mod/Draft/draftviewproviders/view_wire.py b/src/Mod/Draft/draftviewproviders/view_wire.py index 1b33202180..c8297c871e 100644 --- a/src/Mod/Draft/draftviewproviders/view_wire.py +++ b/src/Mod/Draft/draftviewproviders/view_wire.py @@ -39,6 +39,7 @@ from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD as App import FreeCADGui as Gui import DraftVecUtils +import WorkingPlane import draftgeoutils.wires as wires import draftutils.utils as utils import draftutils.gui_utils as gui_utils @@ -152,20 +153,10 @@ class ViewProviderWire(ViewProviderDraft): if not hasattr(self, "Object"): return - if hasattr(App, "DraftWorkingPlane"): - App.DraftWorkingPlane.setup() - origin = App.DraftWorkingPlane.position - normal = App.DraftWorkingPlane.axis - # Align the grid for visual feedback: - if hasattr(Gui, "Snapper"): - Gui.Snapper.setTrackers() - else: - origin = App.Vector(0, 0, 0) - normal = App.Vector(0, 0, 1) - + wp = WorkingPlane.get_working_plane() flat_wire = wires.flattenWire(self.Object.Shape.Wires[0], - origin=origin, - normal=normal) + origin=wp.position, + normal=wp.axis) doc = App.ActiveDocument doc.openTransaction(translate("draft", "Flatten")) diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index 4ffd1a2622..c146e9a8ca 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -65,11 +65,6 @@ from Draft import _Dimension from FreeCAD import Vector from FreeCAD import Console as FCC -# sets the default working plane if Draft hasn't been started yet -if not hasattr(FreeCAD, "DraftWorkingPlane"): - plane = WorkingPlane.plane() - FreeCAD.DraftWorkingPlane = plane - gui = FreeCAD.GuiUp draftui = None if gui: @@ -739,10 +734,10 @@ def placementFromDXFOCS(ent): what is needed is a 3D vector defining the Z axis of the OCS, and the elevation value over it. - It uses `WorkingPlane.alignToPointAndAxis()` to align the working plane + It uses `WorkingPlane.align_to_point_and_axis()` to align the working plane to the origin and to `ent.extrusion` (the plane's `axis`). Then it gets the global coordinates of the entity - by using `WorkingPlane.getGlobalCoords()` + by using `WorkingPlane.get_global_coords()` and either `ent.elevation` (Z coordinate) or `ent.loc` a `(x,y,z)` tuple. Parameters @@ -760,11 +755,11 @@ def placementFromDXFOCS(ent): See also -------- - WorkingPlane.alignToPointAndAxis, WorkingPlane.getGlobalCoords + WorkingPlane.align_to_point_and_axis, WorkingPlane.get_global_coords """ - draftWPlane = FreeCAD.DraftWorkingPlane - draftWPlane.alignToPointAndAxis(Vector(0.0, 0.0, 0.0), - vec(ent.extrusion), 0.0) + draftWPlane = WorkingPlane.PlaneBase() + draftWPlane.align_to_point_and_axis(Vector(0.0, 0.0, 0.0), + vec(ent.extrusion), 0.0) # Object Coordinate Systems (OCS) # http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7941.htm # Arbitrary Axis Algorithm @@ -787,14 +782,12 @@ def placementFromDXFOCS(ent): draftWPlane.v = draftWPlane.axis.cross(draftWPlane.u) draftWPlane.v.normalize() draftWPlane.position = Vector(0.0, 0.0, 0.0) - draftWPlane.weak = False - pl = FreeCAD.Placement() - pl = draftWPlane.getPlacement() + pl = draftWPlane.get_placement() if ((ent.type == "lwpolyline") or (ent.type == "polyline")): - pl.Base = draftWPlane.getGlobalCoords(vec([0.0, 0.0, ent.elevation])) + pl.Base = draftWPlane.get_global_coords(vec([0.0, 0.0, ent.elevation])) else: - pl.Base = draftWPlane.getGlobalCoords(vec(ent.loc)) + pl.Base = draftWPlane.get_global_coords(vec(ent.loc)) return pl @@ -2305,7 +2298,7 @@ def processdxf(document, filename, getShapes=False, reComputeFlag=True): edges.extend(s.Edges) if len(edges) > (100): FCC.PrintMessage(str(len(edges)) + " edges to join\n") - if FreeCAD.GuiUp: + if gui: d = QtGui.QMessageBox() d.setText("Warning: High number of entities to join (>100)") d.setInformativeText("This might take a long time " @@ -2528,7 +2521,7 @@ def processdxf(document, filename, getShapes=False, reComputeFlag=True): newob = doc.addObject("App::FeaturePython", "Dimension") lay.addObject(newob) _Dimension(newob) - if FreeCAD.GuiUp: + if gui: from Draft import _ViewProviderDimension _ViewProviderDimension(newob.ViewObject) newob.Start = p1 @@ -3526,8 +3519,7 @@ def export(objectslist, filename, nospline=False, lwPoly=False): getDXFlibs() if dxfLibrary: global exportList - exportList = objectslist - exportList = Draft.get_group_contents(exportList) + exportList = Draft.get_group_contents(objectslist, spaces=True) nlist = [] exportLayers = [] @@ -3609,36 +3601,30 @@ def export(objectslist, filename, nospline=False, lwPoly=False): elif obtype == "PanelCut": writePanelCut(ob, dxf, nospline, lwPoly) - elif obtype == "Space": + elif obtype == "Space" and gui: vobj = ob.ViewObject - c = utils.get_rgb(vobj.TextColor) - n = vobj.FontName - a = 0 - if rotation != 0: - a = math.radians(rotation) + rotation = math.degrees(ob.Placement.Rotation.Angle) t1 = "".join(vobj.Proxy.text1.string.getValues()) t2 = "".join(vobj.Proxy.text2.string.getValues()) - scale = vobj.FirstLine.Value/vobj.FontSize.Value - f1 = fontsize * scale - if round(FreeCAD.DraftWorkingPlane.axis.getAngle(App.Vector(0,0,1)),2) not in [0,3.14]: - # if not in XY view, place the label at center - p2 = obj.Shape.CenterOfMass - else: - _v = vobj.Proxy.coords.translation.getValue().getValue() - p2 = obj.Placement.multVec(App.Vector(_v)) + h1 = vobj.FirstLine.Value + h2 = vobj.FontSize.Value + _v = vobj.Proxy.coords.translation.getValue().getValue() _h = vobj.Proxy.header.translation.getValue().getValue() + p2 = FreeCAD.Vector(_v) lspc = FreeCAD.Vector(_h) - p1 = p2 + lspc - dxf.append(dxfLibrary.Text(t1, p1, height=f1, + p1 = ob.Placement.multVec(p2 + lspc) + dxf.append(dxfLibrary.Text(t1, p1, height=h1 * 0.8, + rotation=rotation, color=getACI(ob, text=True), style='STANDARD', layer=getStrGroup(ob))) if t2: ofs = FreeCAD.Vector(0, -lspc.Length, 0) - if a: + if rotation: Z = FreeCAD.Vector(0, 0, 1) - ofs = FreeCAD.Rotation(Z, -rotation).multVec(ofs) - dxf.append(dxfLibrary.Text(t2, p1.add(ofs), height=f1, + ofs = FreeCAD.Rotation(Z, rotation).multVec(ofs) + dxf.append(dxfLibrary.Text(t2, p1.add(ofs), height=h2 * 0.8, + rotation=rotation, color=getACI(ob, text=True), style='STANDARD', layer=getStrGroup(ob))) @@ -3653,7 +3639,7 @@ def export(objectslist, filename, nospline=False, lwPoly=False): color=getACI(ob), layer=getStrGroup(ob))) h = 1 - if FreeCAD.GuiUp: + if gui: vobj = ob.ViewObject h = float(ob.ViewObject.FontSize) for text in vobj.Proxy.getTextData(): @@ -4059,7 +4045,7 @@ def readPreferences(): """ # reading parameters p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") - if FreeCAD.GuiUp and p.GetBool("dxfShowDialog", False): + if gui and p.GetBool("dxfShowDialog", False): FreeCADGui.showPreferences("Import-Export", 3) global dxfCreatePart, dxfCreateDraft, dxfCreateSketch global dxfDiscretizeCurves, dxfStarBlocks