From 77ea3a1a86d5a8bd8f440387f46d65859998d603 Mon Sep 17 00:00:00 2001 From: carlopav Date: Sun, 26 Apr 2020 11:54:09 +0200 Subject: [PATCH] Draft: split join functions from Draft.py --- src/Mod/Draft/CMakeLists.txt | 1 + src/Mod/Draft/Draft.py | 53 ++-------------- src/Mod/Draft/draftfunctions/join.py | 91 ++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 48 deletions(-) create mode 100644 src/Mod/Draft/draftfunctions/join.py diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 80b0c24b46..cf7f28aada 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -60,6 +60,7 @@ SET(Draft_utilities SET(Draft_functions draftfunctions/__init__.py + draftfunctions/join.py draftfunctions/move.py draftfunctions/rotate.py ) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index d8e4d3ef3f..6309d8070c 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -182,6 +182,11 @@ from draftutils.gui_utils import load_texture from draftfunctions.move import move from draftfunctions.rotate import rotate +from draftfunctions.join import join_wires +from draftfunctions.join import join_wires as joinWires +from draftfunctions.join import join_two_wires +from draftfunctions.join import join_two_wires as joinTwoWires + #--------------------------------------------------------------------------- # Draft objects #--------------------------------------------------------------------------- @@ -491,54 +496,6 @@ def extrude(obj,vector,solid=False): return newobj -def joinWires(wires, joinAttempts = 0): - """joinWires(objects): merges a set of wires where possible, if any of those - wires have a coincident start and end point""" - if joinAttempts > len(wires): - return - joinAttempts += 1 - for wire1Index, wire1 in enumerate(wires): - for wire2Index, wire2 in enumerate(wires): - if wire2Index <= wire1Index: - continue - if joinTwoWires(wire1, wire2): - wires.pop(wire2Index) - break - joinWires(wires, joinAttempts) - -def joinTwoWires(wire1, wire2): - """joinTwoWires(object, object): joins two wires if they share a common - point as a start or an end. - - BUG: it occasionally fails to join lines even if the lines - visually share a point. - This is a rounding error in the comparison of the shared point; - a small difference will result in the points being considered different - and thus the lines not joining. - Test properly using `DraftVecUtils.equals` because then it will consider - the precision set in the Draft preferences. - """ - wire1AbsPoints = [wire1.Placement.multVec(point) for point in wire1.Points] - wire2AbsPoints = [wire2.Placement.multVec(point) for point in wire2.Points] - if (wire1AbsPoints[0] == wire2AbsPoints[-1] and wire1AbsPoints[-1] == wire2AbsPoints[0]) \ - or (wire1AbsPoints[0] == wire2AbsPoints[0] and wire1AbsPoints[-1] == wire2AbsPoints[-1]): - wire2AbsPoints.pop() - wire1.Closed = True - elif wire1AbsPoints[0] == wire2AbsPoints[0]: - wire1AbsPoints = list(reversed(wire1AbsPoints)) - elif wire1AbsPoints[0] == wire2AbsPoints[-1]: - wire1AbsPoints = list(reversed(wire1AbsPoints)) - wire2AbsPoints = list(reversed(wire2AbsPoints)) - elif wire1AbsPoints[-1] == wire2AbsPoints[-1]: - wire2AbsPoints = list(reversed(wire2AbsPoints)) - elif wire1AbsPoints[-1] == wire2AbsPoints[0]: - pass - else: - return False - wire2AbsPoints.pop(0) - wire1.Points = [wire1.Placement.inverse().multVec(point) for point in wire1AbsPoints] + [wire1.Placement.inverse().multVec(point) for point in wire2AbsPoints] - FreeCAD.ActiveDocument.removeObject(wire2.Name) - return True def split(wire, newPoint, edgeIndex): if getType(wire) != "Wire": diff --git a/src/Mod/Draft/draftfunctions/join.py b/src/Mod/Draft/draftfunctions/join.py new file mode 100644 index 0000000000..a2e94b073e --- /dev/null +++ b/src/Mod/Draft/draftfunctions/join.py @@ -0,0 +1,91 @@ +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * Copyright (c) 2020 FreeCAD Developers * +# * * +# * 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. * +# * * +# * This program 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 this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""This module provides the code for Draft join functions. +""" +## @package join +# \ingroup DRAFT +# \brief This module provides the code for Draft join functions. + +import FreeCAD as App + + +def join_wires(wires, joinAttempts = 0): + """joinWires(objects): merges a set of wires where possible, if any of those + wires have a coincident start and end point""" + if joinAttempts > len(wires): + return + joinAttempts += 1 + for wire1Index, wire1 in enumerate(wires): + for wire2Index, wire2 in enumerate(wires): + if wire2Index <= wire1Index: + continue + if joinTwoWires(wire1, wire2): + wires.pop(wire2Index) + break + joinWires(wires, joinAttempts) + + +joinWires = join_wires + + +def join_two_wires(wire1, wire2): + """joinTwoWires(object, object): joins two wires if they share a common + point as a start or an end. + + BUG: it occasionally fails to join lines even if the lines + visually share a point. + This is a rounding error in the comparison of the shared point; + a small difference will result in the points being considered different + and thus the lines not joining. + Test properly using `DraftVecUtils.equals` because then it will consider + the precision set in the Draft preferences. + """ + wire1AbsPoints = [wire1.Placement.multVec(point) for point in wire1.Points] + wire2AbsPoints = [wire2.Placement.multVec(point) for point in wire2.Points] + if ((wire1AbsPoints[0] == wire2AbsPoints[-1] and + wire1AbsPoints[-1] == wire2AbsPoints[0]) or + (wire1AbsPoints[0] == wire2AbsPoints[0] and + wire1AbsPoints[-1] == wire2AbsPoints[-1])): + wire2AbsPoints.pop() + wire1.Closed = True + elif wire1AbsPoints[0] == wire2AbsPoints[0]: + wire1AbsPoints = list(reversed(wire1AbsPoints)) + elif wire1AbsPoints[0] == wire2AbsPoints[-1]: + wire1AbsPoints = list(reversed(wire1AbsPoints)) + wire2AbsPoints = list(reversed(wire2AbsPoints)) + elif wire1AbsPoints[-1] == wire2AbsPoints[-1]: + wire2AbsPoints = list(reversed(wire2AbsPoints)) + elif wire1AbsPoints[-1] == wire2AbsPoints[0]: + pass + else: + return False + wire2AbsPoints.pop(0) + wire1.Points = ([wire1.Placement.inverse().multVec(point) + for point in wire1AbsPoints] + + [wire1.Placement.inverse().multVec(point) + for point in wire2AbsPoints]) + App.ActiveDocument.removeObject(wire2.Name) + return True + + +joinTwoWires = join_two_wires \ No newline at end of file