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

Related issue:
#5603.

For gui_snapper.py and gui_trackers.py an intermediate solution has been adopted. They still rely on App.DraftWorkingPlane, but now use a small function to retreive it.

Simply switching to the PlaneGui class is problematic for the trackers as this results in an endless recursion (wp->grid->wp->...). Using the old App.DraftWorkingPlane (which is kept up-to-date by PlaneGui) solves this for now. I will try to return to this later (which may be after the next release though).
This commit is contained in:
Roy-043
2023-10-28 18:34:30 +02:00
committed by Yorik van Havre
parent 9a7163f533
commit a2e85a4ae1
2 changed files with 63 additions and 74 deletions

View File

@@ -189,6 +189,10 @@ class Snapper:
('special', ':/icons/Draft_Snap_Special.svg')])
def _get_wp(self):
return App.DraftWorkingPlane
def init_active_snaps(self):
"""
set self.active_snaps according to user prefs
@@ -512,8 +516,7 @@ class Snapper:
def toWP(self, point):
"""Project the given point on the working plane, if needed."""
if self.isEnabled("WorkingPlane"):
if hasattr(App, "DraftWorkingPlane"):
return App.DraftWorkingPlane.projectPoint(point)
return self._get_wp().project_point(point)
return point
@@ -522,14 +525,13 @@ class Snapper:
view = Draft.get3DView()
pt = view.getPoint(x, y)
if self.mask != "z":
if hasattr(App,"DraftWorkingPlane"):
if view.getCameraType() == "Perspective":
camera = view.getCameraNode()
p = camera.getField("position").getValue()
dv = pt.sub(App.Vector(p[0], p[1], p[2]))
else:
dv = view.getViewDirection()
return App.DraftWorkingPlane.projectPoint(pt, dv)
if view.getCameraType() == "Perspective":
camera = view.getCameraNode()
p = camera.getField("position").getValue()
dv = pt.sub(App.Vector(p[0], p[1], p[2]))
else:
dv = view.getViewDirection()
return self._get_wp().project_point(pt, dv)
return pt
@@ -696,14 +698,8 @@ class Snapper:
if self.isEnabled('Ortho') and (not self.mask):
if last:
vecs = []
if hasattr(App,"DraftWorkingPlane"):
ax = [App.DraftWorkingPlane.u,
App.DraftWorkingPlane.v,
App.DraftWorkingPlane.axis]
else:
ax = [App.Vector(1, 0, 0),
App.Vector(0, 1, 0),
App.Vector(0, 0, 1)]
wp = self._get_wp()
ax = [wp.u, wp.v, wp.axis]
for a in self.polarAngles:
if a == 90:
vecs.extend([ax[0], ax[0].negative()])
@@ -892,12 +888,9 @@ class Snapper:
"""
if not self.holdPoints:
return None
if hasattr(App, "DraftWorkingPlane"):
u = App.DraftWorkingPlane.u
v = App.DraftWorkingPlane.v
else:
u = App.Vector(1, 0, 0)
v = App.Vector(0, 1, 0)
wp = self._get_wp()
u = wp.u
v = wp.v
if len(self.holdPoints) > 1:
# first try mid points
if self.isEnabled("Midpoint"):
@@ -1285,10 +1278,6 @@ class Snapper:
must be constrained. If no basepoint is given, the current point is
used as basepoint.
"""
# without the Draft module fully loaded, no axes system!"
if not hasattr(App, "DraftWorkingPlane"):
return point
point = App.Vector(point)
# setup trackers if needed
@@ -1307,25 +1296,26 @@ class Snapper:
delta = point.sub(self.basepoint)
# setting constraint axis
wp = self._get_wp()
if self.mask:
self.affinity = self.mask
if not self.affinity:
self.affinity = App.DraftWorkingPlane.getClosestAxis(delta)
self.affinity = wp.get_closest_axis(delta)
if isinstance(axis, App.Vector):
self.constraintAxis = axis
elif axis == "x":
self.constraintAxis = App.DraftWorkingPlane.u
self.constraintAxis = wp.u
elif axis == "y":
self.constraintAxis = App.DraftWorkingPlane.v
self.constraintAxis = wp.v
elif axis == "z":
self.constraintAxis = App.DraftWorkingPlane.axis
self.constraintAxis = wp.axis
else:
if self.affinity == "x":
self.constraintAxis = App.DraftWorkingPlane.u
self.constraintAxis = wp.u
elif self.affinity == "y":
self.constraintAxis = App.DraftWorkingPlane.v
self.constraintAxis = wp.v
elif self.affinity == "z":
self.constraintAxis = App.DraftWorkingPlane.axis
self.constraintAxis = wp.axis
elif isinstance(self.affinity, App.Vector):
self.constraintAxis = self.affinity
else:
@@ -1411,10 +1401,9 @@ class Snapper:
shift = event.wasShiftDown()
self.pt = Gui.Snapper.snap(mousepos, lastpoint=last,
active=ctrl, constrain=shift)
if hasattr(App, "DraftWorkingPlane"):
self.ui.displayPoint(self.pt, last,
plane=App.DraftWorkingPlane,
mask=Gui.Snapper.affinity)
self.ui.displayPoint(self.pt, last,
plane=self._get_wp(),
mask=Gui.Snapper.affinity)
if movecallback:
movecallback(self.pt, self.snapInfo)
@@ -1422,9 +1411,10 @@ class Snapper:
"""Get the global coordinates from a point."""
# Same algorithm as in validatePoint in DraftGui.py.
ref = App.Vector(0, 0, 0)
if global_mode is False and hasattr(App, "DraftWorkingPlane"):
point = App.DraftWorkingPlane.getGlobalRot(point)
ref = App.DraftWorkingPlane.getGlobalCoords(ref)
if global_mode is False:
wp = self._get_wp()
point = wp.get_global_coords(point, as_vector=True)
ref = wp.get_global_coords(ref)
if relative_mode is True and last is not None:
ref = last
self.pt = point + ref

View File

@@ -140,6 +140,9 @@ class Tracker:
sg.removeChild(self.switch)
sg.insertChild(self.switch, 0)
def _get_wp(self):
return FreeCAD.DraftWorkingPlane
class snapTracker(Tracker):
"""Define Snap Mark tracker, used by tools that support snapping."""
@@ -237,8 +240,9 @@ class rectangleTracker(Tracker):
super().__init__(dotted, scolor, swidth,
[self.coords, line],
name="rectangleTracker")
self.u = FreeCAD.DraftWorkingPlane.u
self.v = FreeCAD.DraftWorkingPlane.v
wp = self._get_wp()
self.u = wp.u
self.v = wp.v
def setorigin(self, point):
"""Set the base point of the rectangle."""
@@ -265,7 +269,7 @@ class rectangleTracker(Tracker):
if v:
self.v = v
else:
norm = FreeCAD.DraftWorkingPlane.u.cross(FreeCAD.DraftWorkingPlane.v)
norm = self._get_wp().axis
self.v = self.u.cross(norm)
def p1(self, point=None):
@@ -538,7 +542,7 @@ class arcTracker(Tracker):
self.trans.translation.setValue([0, 0, 0])
self.sep = coin.SoSeparator()
self.autoinvert = True
self.normal = FreeCAD.DraftWorkingPlane.axis
self.normal = self._get_wp().axis
self.recompute()
super().__init__(dotted, scolor, swidth,
[self.trans, self.sep], name="arcTracker")
@@ -922,11 +926,9 @@ class PlaneTracker(Tracker):
def set(self, pos=None):
"""Set the translation to the position."""
if pos:
Q = FreeCAD.DraftWorkingPlane.getRotation().Rotation.Q
else:
plm = FreeCAD.DraftWorkingPlane.getPlacement()
Q = plm.Rotation.Q
plm = self._get_wp().get_placement()
Q = plm.Rotation.Q
if pos is None:
pos = plm.Base
self.trans.translation.setValue([pos.x, pos.y, pos.z])
self.trans.rotation.setValue([Q[0], Q[1], Q[2], Q[3]])
@@ -1162,10 +1164,8 @@ class gridTracker(Tracker):
self.coords3.point.setValues(apts)
#self.lines3.numVertices.setValues(aidx)
self.pts = pts
self.displayHumanFigure()
self.setAxesColor()
def displayHumanFigure(self):
def displayHumanFigure(self, wp):
""" Display the human figure at the grid corner.
The silhouette is displayed only if:
- BIM Workbench is available;
@@ -1178,7 +1178,7 @@ class gridTracker(Tracker):
pidx = []
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
if param.GetBool("gridShowHuman", True) and \
FreeCAD.DraftWorkingPlane.axis.getAngle(FreeCAD.Vector(0,0,1)) < 0.001:
wp.axis.getAngle(FreeCAD.Vector(0,0,1)) < 0.001:
try:
import BimProject
loc = FreeCAD.Vector(-bound+self.space/2,-bound+self.space/2,0)
@@ -1192,11 +1192,10 @@ class gridTracker(Tracker):
self.coords_human.point.setValues(pts)
self.human.numVertices.setValues(pidx)
def setAxesColor(self):
def setAxesColor(self, wp):
"""set axes color"""
cols = [0,0]
if Draft.getParam("coloredGridAxes",True) and hasattr(FreeCAD,"DraftWorkingPlane"):
wp = FreeCAD.DraftWorkingPlane
if Draft.getParam("coloredGridAxes",True):
if round(wp.u.getAngle(FreeCAD.Vector(1,0,0)),2) in (0,3.14):
cols[0] = 1
elif round(wp.u.getAngle(FreeCAD.Vector(0,1,0)),2) in (0,3.14):
@@ -1239,23 +1238,23 @@ class gridTracker(Tracker):
def set(self,tool=False):
"""Move and rotate the grid according to the current working plane."""
self.reset()
Q = FreeCAD.DraftWorkingPlane.getRotation().Rotation.Q
P = FreeCAD.DraftWorkingPlane.position
wp = self._get_wp()
Q = wp.get_placement().Rotation.Q
P = wp.position
self.trans.rotation.setValue([Q[0], Q[1], Q[2], Q[3]])
self.trans.translation.setValue([P.x, P.y, P.z])
self.displayHumanFigure()
self.setAxesColor()
self.displayHumanFigure(wp)
self.setAxesColor(wp)
if tool:
self.on()
def getClosestNode(self, point):
"""Return the closest node from the given point."""
# get the 2D coords.
# point = FreeCAD.DraftWorkingPlane.projectPoint(point)
pt = FreeCAD.DraftWorkingPlane.getLocalCoords(point)
wp = self._get_wp()
pt = wp.get_local_coords(point)
pu = round(pt.x / self.space, 0) * self.space
pv = round(pt.y / self.space, 0) * self.space
pt = FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(pu, pv, 0))
pt = wp.get_global_coords(Vector(pu, pv, 0))
return pt
@@ -1287,7 +1286,7 @@ class boxTracker(Tracker):
"""Update the tracker."""
import DraftGeomUtils
if not normal:
normal = FreeCAD.DraftWorkingPlane.axis
normal = self._get_wp().axis
if line:
if isinstance(line, list):
bp = line[0]
@@ -1403,10 +1402,10 @@ class archDimTracker(Tracker):
def setString(self, text=None):
"""Set the dim string to the given value or auto value."""
plane = FreeCAD.DraftWorkingPlane
plane = self._get_wp()
p1 = Vector(self.pnts.getValues()[0].getValue())
p2 = Vector(self.pnts.getValues()[-1].getValue())
self.norm.setValue(plane.getNormal())
self.norm.setValue(plane.axis)
# set the offset sign to prevent the dim line from intersecting the curve near the cursor
sign_dx = math.copysign(1, (p2.sub(p1)).x)
sign_dy = math.copysign(1, (p2.sub(p1)).y)
@@ -1421,7 +1420,7 @@ class archDimTracker(Tracker):
self.Distance = (p2.sub(p1)).Length
text = FreeCAD.Units.Quantity(self.Distance, FreeCAD.Units.Length).UserString
self.matrix.setValue(*plane.getPlacement().Matrix.transposed().A)
self.matrix.setValue(*plane.get_placement().Matrix.transposed().A)
self.string.setValue(text.encode('utf8'))
# change the text position to external depending on the distance and scale values
volume = self.camera.getViewVolume()
@@ -1444,9 +1443,9 @@ class archDimTracker(Tracker):
def p1(self, point=None):
"""Set or get the first point of the dim."""
plane = FreeCAD.DraftWorkingPlane
plane = self._get_wp()
if point:
p1_proj = plane.projectPoint(point)
p1_proj = plane.project_point(point)
p1_proj_u = (p1_proj - plane.position).dot(plane.u.normalize())
p1_proj_v = (p1_proj - plane.position).dot(plane.v.normalize())
self.pnts.set1Value(0, p1_proj_u, p1_proj_v, 0)
@@ -1456,9 +1455,9 @@ class archDimTracker(Tracker):
def p2(self, point=None):
"""Set or get the second point of the dim."""
plane = FreeCAD.DraftWorkingPlane
plane = self._get_wp()
if point:
p2_proj = plane.projectPoint(point)
p2_proj = plane.project_point(point)
p2_proj_u = (p2_proj - plane.position).dot(plane.u.normalize())
p2_proj_v = (p2_proj - plane.position).dot(plane.v.normalize())
self.pnts.set1Value(1, p2_proj_u, p2_proj_v, 0)