From af31394e2101eed899c00303bbc9f06f9f63042b Mon Sep 17 00:00:00 2001 From: carlopav Date: Sun, 26 Apr 2020 12:28:41 +0200 Subject: [PATCH] Draft: split scale related functions from Draft.py . --- src/Mod/Draft/CMakeLists.txt | 1 + src/Mod/Draft/Draft.py | 104 +------------- src/Mod/Draft/draftfunctions/scale.py | 187 ++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 99 deletions(-) create mode 100644 src/Mod/Draft/draftfunctions/scale.py diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index cf7f28aada..a253a4cf70 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -63,6 +63,7 @@ SET(Draft_functions draftfunctions/join.py draftfunctions/move.py draftfunctions/rotate.py + draftfunctions/scale.py ) SET(Draft_make_functions diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 6309d8070c..96c51f5605 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.scale import scale +from draftfunctions.scale import scale_vertex, scaleVertex +from draftfunctions.scale import scale_edge, scaleEdge +from draftfunctions.scale import copy_scaled_edges, copyScaledEdges + from draftfunctions.join import join_wires from draftfunctions.join import join_wires as joinWires from draftfunctions.join import join_two_wires @@ -711,106 +716,7 @@ def rotateEdge(object, edge_index, angle, center, axis): rotateVertex(object, edge_index+1, angle, center, axis) -def scaleVectorFromCenter(vector, scale, center): - return vector.sub(center).scale(scale.x, scale.y, scale.z).add(center) -def scaleVertex(object, vertex_index, scale, center): - points = object.Points - points[vertex_index] = object.Placement.inverse().multVec( - scaleVectorFromCenter( - object.Placement.multVec(points[vertex_index]), - scale, center)) - object.Points = points - -def scaleEdge(object, edge_index, scale, center): - scaleVertex(object, edge_index, scale, center) - if isClosedEdge(edge_index, object): - scaleVertex(object, 0, scale, center) - else: - scaleVertex(object, edge_index+1, scale, center) - -def copyScaledEdges(arguments): - copied_edges = [] - for argument in arguments: - copied_edges.append(copyScaledEdge(argument[0], argument[1], - argument[2], argument[3])) - joinWires(copied_edges) - -def copyScaledEdge(object, edge_index, scale, center): - vertex1 = scaleVectorFromCenter( - object.Placement.multVec(object.Points[edge_index]), - scale, center) - if isClosedEdge(edge_index, object): - vertex2 = scaleVectorFromCenter( - object.Placement.multVec(object.Points[0]), - scale, center) - else: - vertex2 = scaleVectorFromCenter( - object.Placement.multVec(object.Points[edge_index+1]), - scale, center) - return makeLine(vertex1, vertex2) - -def scale(objectslist,scale=Vector(1,1,1),center=Vector(0,0,0),copy=False): - """scale(objects,vector,[center,copy,legacy]): Scales the objects contained - in objects (that can be a list of objects or an object) of the given scale - factors defined by the given vector (in X, Y and Z directions) around - given center. If copy is True, the actual objects are not moved, but copies - are created instead. The objects (or their copies) are returned.""" - if not isinstance(objectslist, list): - objectslist = [objectslist] - newobjlist = [] - for obj in objectslist: - if copy: - newobj = makeCopy(obj) - else: - newobj = obj - if hasattr(obj,'Shape'): - scaled_shape = obj.Shape.copy() - m = FreeCAD.Matrix() - m.move(obj.Placement.Base.negative()) - m.move(center.negative()) - m.scale(scale.x,scale.y,scale.z) - m.move(center) - m.move(obj.Placement.Base) - scaled_shape = scaled_shape.transformGeometry(m) - if getType(obj) == "Rectangle": - p = [] - for v in scaled_shape.Vertexes: - p.append(v.Point) - pl = obj.Placement.copy() - pl.Base = p[0] - diag = p[2].sub(p[0]) - bb = p[1].sub(p[0]) - bh = p[3].sub(p[0]) - nb = DraftVecUtils.project(diag,bb) - nh = DraftVecUtils.project(diag,bh) - if obj.Length < 0: l = -nb.Length - else: l = nb.Length - if obj.Height < 0: h = -nh.Length - else: h = nh.Length - newobj.Length = l - newobj.Height = h - tr = p[0].sub(obj.Shape.Vertexes[0].Point) - newobj.Placement = pl - elif getType(obj) == "Wire" or getType(obj) == "BSpline": - for index, point in enumerate(newobj.Points): - scaleVertex(newobj, index, scale, center) - elif hasattr(obj,'Shape'): - newobj.Shape = scaled_shape - elif (obj.TypeId == "App::Annotation"): - factor = scale.y * obj.ViewObject.FontSize - newobj.ViewObject.FontSize = factor - d = obj.Position.sub(center) - newobj.Position = center.add(Vector(d.x*scale.x,d.y*scale.y,d.z*scale.z)) - if copy: - formatObject(newobj,obj) - newobjlist.append(newobj) - if copy and getParam("selectBaseObjects",False): - select(objectslist) - else: - select(newobjlist) - if len(newobjlist) == 1: return newobjlist[0] - return newobjlist def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): """offset(object,delta,[copymode],[bind]): offsets the given wire by diff --git a/src/Mod/Draft/draftfunctions/scale.py b/src/Mod/Draft/draftfunctions/scale.py new file mode 100644 index 0000000000..0da5c08d63 --- /dev/null +++ b/src/Mod/Draft/draftfunctions/scale.py @@ -0,0 +1,187 @@ +# *************************************************************************** +# * 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 scale function. +""" +## @package scale +# \ingroup DRAFT +# \brief This module provides the code for Draft scale function. + +import math + +import FreeCAD as App + +import DraftVecUtils + +import draftutils.gui_utils as gui_utils +import draftutils.utils as utils + +from draftfunctions.join import join_wires + +from draftmake.make_copy import make_copy + + +def scale(objectslist, scale=App.Vector(1,1,1), + center=App.Vector(0,0,0), copy=False): + """scale(objects, scale, [center], copy) + + Scales the objects contained in objects (that can be a list of objects or + an object) of the given around given center. + + Parameters + ---------- + objectlist : list + + scale : Base.Vector + Scale factors defined by a given vector (in X, Y, Z directions). + + objectlist : Base.Vector + Center of the scale operation. + + copy : bool + If copy is True, the actual objects are not scaled, but copies + are created instead. + + Return + ---------- + The objects (or their copies) are returned. + """ + if not isinstance(objectslist, list): + objectslist = [objectslist] + newobjlist = [] + for obj in objectslist: + if copy: + newobj = make_copy(obj) + else: + newobj = obj + if hasattr(obj,'Shape'): + scaled_shape = obj.Shape.copy() + m = App.Matrix() + m.move(obj.Placement.Base.negative()) + m.move(center.negative()) + m.scale(scale.x,scale.y,scale.z) + m.move(center) + m.move(obj.Placement.Base) + scaled_shape = scaled_shape.transformGeometry(m) + if utils.get_type(obj) == "Rectangle": + p = [] + for v in scaled_shape.Vertexes: + p.append(v.Point) + pl = obj.Placement.copy() + pl.Base = p[0] + diag = p[2].sub(p[0]) + bb = p[1].sub(p[0]) + bh = p[3].sub(p[0]) + nb = DraftVecUtils.project(diag,bb) + nh = DraftVecUtils.project(diag,bh) + if obj.Length < 0: l = -nb.Length + else: l = nb.Length + if obj.Height < 0: h = -nh.Length + else: h = nh.Length + newobj.Length = l + newobj.Height = h + tr = p[0].sub(obj.Shape.Vertexes[0].Point) # unused? + newobj.Placement = pl + elif utils.get_type(obj) == "Wire" or utils.get_type(obj) == "BSpline": + for index, point in enumerate(newobj.Points): + scale_vertex(newobj, index, scale, center) + elif hasattr(obj,'Shape'): + newobj.Shape = scaled_shape + elif (obj.TypeId == "App::Annotation"): + factor = scale.y * obj.ViewObject.FontSize + newobj.ViewObject.FontSize = factor + d = obj.Position.sub(center) + newobj.Position = center.add(App.Vector(d.x * scale.x, + d.y * scale.y, + d.z * scale.z)) + if copy: + gui_utils.format_object(newobj,obj) + newobjlist.append(newobj) + if copy and utils.get_param("selectBaseObjects",False): + gui_utils.select(objectslist) + else: + gui_utils.select(newobjlist) + if len(newobjlist) == 1: return newobjlist[0] + return newobjlist + + +def scale_vertex(obj, vertex_index, scale, center): + points = obj.Points + points[vertex_index] = obj.Placement.inverse().multVec( + scaleVectorFromCenter( + obj.Placement.multVec(points[vertex_index]), + scale, center)) + obj.Points = points + + +scaleVertex = scale_vertex + + +def scale_vector_from_center(vector, scale, center): + return vector.sub(center).scale(scale.x, scale.y, scale.z).add(center) + + +scaleVectorFromCenter = scale_vector_from_center + + +# code needed for subobject modifiers + + +def scale_edge(obj, edge_index, scale, center): + scaleVertex(obj, edge_index, scale, center) + if utils.isClosedEdge(edge_index, obj): + scaleVertex(obj, 0, scale, center) + else: + scaleVertex(obj, edge_index+1, scale, center) + + +scaleEdge = scale_edge + + +def copy_scaled_edge(obj, edge_index, scale, center): + import Part + vertex1 = scaleVectorFromCenter( + obj.Placement.multVec(obj.Points[edge_index]), + scale, center) + if utils.isClosedEdge(edge_index, obj): + vertex2 = scaleVectorFromCenter( + obj.Placement.multVec(obj.Points[0]), + scale, center) + else: + vertex2 = scaleVectorFromCenter( + obj.Placement.multVec(obj.Points[edge_index+1]), + scale, center) + return Part.makeLine(vertex1, vertex2) + + +copyScaledEdge = copy_scaled_edge + + +def copy_scaled_edges(arguments): + copied_edges = [] + for argument in arguments: + copied_edges.append(copyScaledEdge(argument[0], argument[1], + argument[2], argument[3])) + join_wires(copied_edges) + + +copyScaledEdges = copy_scaled_edges \ No newline at end of file