Draft: Updates related to the PlaneGui class (step 2)

Related issue:
#5603.

Additionally:
Fixed the issue where the texts of Arch_Space objects were not exported to DXF.
This commit is contained in:
Roy-043
2023-10-20 12:46:52 +02:00
parent 03aa8309db
commit ca06e87a38
9 changed files with 67 additions and 119 deletions

View File

@@ -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)

View File

@@ -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 = []

View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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`.

View File

@@ -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")

View File

@@ -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"))

View File

@@ -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