From 0c3006e77cf87fceaf39952f1091c39f5d7e805d Mon Sep 17 00:00:00 2001 From: J-Dunn Date: Tue, 28 Jul 2020 14:12:11 +0100 Subject: [PATCH] prevent added paths creating tool crash #4260 #3028 In this path dressup a bogus machine position is used to get an initial edge, this results in a path element which does reflect the input path data and can lead to a tool crash. This PR checks whether X and Y actually come from the input path data and prevent new path elements being added until true machine position has been set. Forum thread: https://forum.freecadweb.org/viewtopic.php?f=15&t=42820 --- .../PathScripts/PathDressupPathBoundary.py | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupPathBoundary.py b/src/Mod/Path/PathScripts/PathDressupPathBoundary.py index 488734d972..246eb6a536 100644 --- a/src/Mod/Path/PathScripts/PathDressupPathBoundary.py +++ b/src/Mod/Path/PathScripts/PathDressupPathBoundary.py @@ -85,11 +85,11 @@ class DressupPathBoundary(object): return [] cmds = [] if begin.z < self.safeHeight: - cmds.append(Path.Command('G1', {'Z': self.safeHeight, 'F': verticalFeed})) + cmds.append(self.strG1ZsafeHeight) if begin.z < self.clearanceHeight: - cmds.append(Path.Command('G0', {'Z': self.clearanceHeight})) + cmds.append(self.strG0ZclearanceHeight) if end: - cmds.append(Path.Command('G0', {'X': end.x, 'Y': end.y})) + cmds.append(Path.Command('G0', {'X': end.x, 'Y': end.y})) if end.z < self.clearanceHeight: cmds.append(Path.Command('G0', {'Z': max(self.safeHeight, end.z)})) if end.z < self.safeHeight: @@ -105,29 +105,38 @@ class DressupPathBoundary(object): if len(obj.Base.Path.Commands) > 0: self.safeHeight = float(PathUtil.opProperty(obj.Base, 'SafeHeight')) self.clearanceHeight = float(PathUtil.opProperty(obj.Base, 'ClearanceHeight')) + self.strG1ZsafeHeight = Path.Command('G1', {'Z': self.safeHeight, 'F': tc.VertFeed.Value}) + self.strG0ZclearanceHeight = Path.Command('G0', {'Z': self.clearanceHeight}) boundary = obj.Stock.Shape - cmd = obj.Base.Path.Commands[0] - pos = cmd.Placement.Base + cmd = obj.Base.Path.Commands[0] + pos = cmd.Placement.Base # bogus m/c postion to create first edge + bogusX = True + bogusY = True commands = [cmd] lastExit = None for cmd in obj.Base.Path.Commands[1:]: if cmd.Name in PathGeom.CmdMoveAll: + if bogusX == True : + bogusX = ( 'X' not in cmd.Parameters ) + if bogusY : + bogusY = ( 'Y' not in cmd.Parameters ) edge = PathGeom.edgeForCmd(cmd, pos) if edge: inside = edge.common(boundary).Edges outside = edge.cut(boundary).Edges - if not obj.Inside: - t = inside + if not obj.Inside: # UI "inside boundary" param + tmp = inside inside = outside - outside = t + outside = tmp # it's really a shame that one cannot trust the sequence and/or # orientation of edges if 1 == len(inside) and 0 == len(outside): PathLog.track(_vstr(pos), _vstr(lastExit), ' + ', cmd) # cmd fully included by boundary if lastExit: - commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value)) + if not ( bogusX or bogusY ) : # don't insert false paths based on bogus m/c position + commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value)) lastExit = None commands.append(cmd) pos = PathGeom.commandEndPoint(cmd, pos) @@ -145,16 +154,17 @@ class DressupPathBoundary(object): PathLog.track(ie) if ie: e = ie[0] - ptL = e.valueAt(e.LastParameter) - flip = PathGeom.pointsCoincide(pos, ptL) - newPos = e.valueAt(e.FirstParameter) if flip else ptL + LastPt = e.valueAt(e.LastParameter) + flip = PathGeom.pointsCoincide(pos, LastPt) + newPos = e.valueAt(e.FirstParameter) if flip else LastPt # inside edges are taken at this point (see swap of inside/outside # above - so we can just connect the dots ... if lastExit: - commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value)) + if not ( bogusX or bogusY ) : commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value)) lastExit = None PathLog.track(e, flip) - commands.extend(PathGeom.cmdsForEdge(e, flip, False, 50, tc.HorizFeed.Value, tc.VertFeed.Value)) # add missing HorizFeed to G2 paths + if not ( bogusX or bogusY ) : # don't insert false paths based on bogus m/c position + commands.extend(PathGeom.cmdsForEdge(e, flip, False, 50, tc.HorizFeed.Value, tc.VertFeed.Value)) inside.remove(e) pos = newPos lastExit = newPos