diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 82dfa77c66..0e0cc5c184 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -65,6 +65,7 @@ SET(Draft_functions SET(Draft_make_functions draftmake/__init__.py draftmake/make_circle.py + draftmake/make_rectangle.py ) SET(Draft_objects @@ -78,6 +79,7 @@ SET(Draft_objects draftobjects/draft_annotation.py draftobjects/label.py draftobjects/dimension.py + draftobjects/rectangle.py draftobjects/text.py draftobjects/README.md ) @@ -91,6 +93,7 @@ SET(Draft_view_providers draftviewproviders/view_draft_annotation.py draftviewproviders/view_label.py draftviewproviders/view_dimension.py + draftviewproviders/view_rectangle.py draftviewproviders/view_text.py draftviewproviders/README.md ) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 3d2f0f032b..c14f1b2a92 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -195,6 +195,13 @@ from draftviewproviders.view_base import _ViewProviderDraftPart from draftmake.make_circle import make_circle, makeCircle from draftobjects.circle import Circle, _Circle +# rectangle +from draftmake.make_rectangle import make_rectangle, makeRectangle +from draftobjects.rectangle import Rectangle, _Rectangle +if FreeCAD.GuiUp: + from draftviewproviders.view_rectangle import ViewProviderRectangle + from draftviewproviders.view_rectangle import _ViewProviderRectangle + #--------------------------------------------------------------------------- @@ -265,31 +272,6 @@ def convertDraftTexts(textslist=[]): FreeCAD.ActiveDocument.removeObject(n) -def makeRectangle(length, height, placement=None, face=None, support=None): - """makeRectangle(length,width,[placement],[face]): Creates a Rectangle - object with length in X direction and height in Y direction. - If a placement is given, it is used. If face is False, the - rectangle is shown as a wireframe, otherwise as a face.""" - if not FreeCAD.ActiveDocument: - FreeCAD.Console.PrintError("No active document. Aborting\n") - return - if placement: typecheck([(placement,FreeCAD.Placement)], "makeRectangle") - obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Rectangle") - _Rectangle(obj) - - obj.Length = length - obj.Height = height - obj.Support = support - if face != None: - obj.MakeFace = face - if placement: obj.Placement = placement - if gui: - _ViewProviderRectangle(obj.ViewObject) - formatObject(obj) - select(obj) - - return obj - def makeWire(pointslist,closed=False,placement=None,face=None,support=None,bs2wire=False): """makeWire(pointslist,[closed],[placement]): Creates a Wire object from the given list of vectors. If closed is True or first @@ -3105,99 +3087,6 @@ class _ViewProviderDraftLink: return obj.ElementList -class _Rectangle(_DraftObject): - """The Rectangle object""" - - def __init__(self, obj): - _DraftObject.__init__(self,obj,"Rectangle") - obj.addProperty("App::PropertyDistance","Length","Draft",QT_TRANSLATE_NOOP("App::Property","Length of the rectangle")) - obj.addProperty("App::PropertyDistance","Height","Draft",QT_TRANSLATE_NOOP("App::Property","Height of the rectangle")) - obj.addProperty("App::PropertyLength","FilletRadius","Draft",QT_TRANSLATE_NOOP("App::Property","Radius to use to fillet the corners")) - obj.addProperty("App::PropertyLength","ChamferSize","Draft",QT_TRANSLATE_NOOP("App::Property","Size of the chamfer to give to the corners")) - obj.addProperty("App::PropertyBool","MakeFace","Draft",QT_TRANSLATE_NOOP("App::Property","Create a face")) - obj.addProperty("App::PropertyInteger","Rows","Draft",QT_TRANSLATE_NOOP("App::Property","Horizontal subdivisions of this rectangle")) - obj.addProperty("App::PropertyInteger","Columns","Draft",QT_TRANSLATE_NOOP("App::Property","Vertical subdivisions of this rectangle")) - obj.addProperty("App::PropertyArea","Area","Draft",QT_TRANSLATE_NOOP("App::Property","The area of this object")) - obj.MakeFace = getParam("fillmode",True) - obj.Length=1 - obj.Height=1 - obj.Rows=1 - obj.Columns=1 - - def execute(self, obj): - if (obj.Length.Value != 0) and (obj.Height.Value != 0): - import Part, DraftGeomUtils - plm = obj.Placement - shape = None - if hasattr(obj,"Rows") and hasattr(obj,"Columns"): - if obj.Rows > 1: - rows = obj.Rows - else: - rows = 1 - if obj.Columns > 1: - columns = obj.Columns - else: - columns = 1 - if (rows > 1) or (columns > 1): - shapes = [] - l = obj.Length.Value/columns - h = obj.Height.Value/rows - for i in range(columns): - for j in range(rows): - p1 = Vector(i*l,j*h,0) - p2 = Vector(p1.x+l,p1.y,p1.z) - p3 = Vector(p1.x+l,p1.y+h,p1.z) - p4 = Vector(p1.x,p1.y+h,p1.z) - p = Part.makePolygon([p1,p2,p3,p4,p1]) - if "ChamferSize" in obj.PropertiesList: - if obj.ChamferSize.Value != 0: - w = DraftGeomUtils.filletWire(p,obj.ChamferSize.Value,chamfer=True) - if w: - p = w - if "FilletRadius" in obj.PropertiesList: - if obj.FilletRadius.Value != 0: - w = DraftGeomUtils.filletWire(p,obj.FilletRadius.Value) - if w: - p = w - if hasattr(obj,"MakeFace"): - if obj.MakeFace: - p = Part.Face(p) - shapes.append(p) - if shapes: - shape = Part.makeCompound(shapes) - if not shape: - p1 = Vector(0,0,0) - p2 = Vector(p1.x+obj.Length.Value,p1.y,p1.z) - p3 = Vector(p1.x+obj.Length.Value,p1.y+obj.Height.Value,p1.z) - p4 = Vector(p1.x,p1.y+obj.Height.Value,p1.z) - shape = Part.makePolygon([p1,p2,p3,p4,p1]) - if "ChamferSize" in obj.PropertiesList: - if obj.ChamferSize.Value != 0: - w = DraftGeomUtils.filletWire(shape,obj.ChamferSize.Value,chamfer=True) - if w: - shape = w - if "FilletRadius" in obj.PropertiesList: - if obj.FilletRadius.Value != 0: - w = DraftGeomUtils.filletWire(shape,obj.FilletRadius.Value) - if w: - shape = w - if hasattr(obj,"MakeFace"): - if obj.MakeFace: - shape = Part.Face(shape) - else: - shape = Part.Face(shape) - obj.Shape = shape - if hasattr(obj,"Area") and hasattr(shape,"Area"): - obj.Area = shape.Area - obj.Placement = plm - obj.positionBySupport() - -class _ViewProviderRectangle(_ViewProviderDraft): - def __init__(self,vobj): - _ViewProviderDraft.__init__(self,vobj) - vobj.addProperty("App::PropertyFile","TextureImage","Draft",QT_TRANSLATE_NOOP("App::Property","Defines a texture image (overrides hatch patterns)")) - - class _Ellipse(_DraftObject): """The Circle object""" diff --git a/src/Mod/Draft/draftmake/make_rectangle.py b/src/Mod/Draft/draftmake/make_rectangle.py new file mode 100644 index 0000000000..af4f344191 --- /dev/null +++ b/src/Mod/Draft/draftmake/make_rectangle.py @@ -0,0 +1,85 @@ +# *************************************************************************** +# * 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 make_rectangle function. +""" +## @package make_rectangle +# \ingroup DRAFT +# \brief This module provides the code for Draft make_rectangle function. + +import FreeCAD as App + +from draftutils.gui_utils import format_object +from draftutils.gui_utils import select + +from draftutils.utils import type_check + +from draftobjects.rectangle import Rectangle +if App.GuiUp: + from draftviewproviders.view_rectangle import ViewProviderRectangle + + +def make_rectangle(length, height, placement=None, face=None, support=None): + """makeRectangle(length, width, [placement], [face]) + + Creates a Rectangle object with length in X direction and height in Y + direction. + + Parameters + ---------- + length, height : dimensions of the rectangle + + placement : Base.Placement + If a placement is given, it is used. + + face : Bool + If face is False, the rectangle is shown as a wireframe, + otherwise as a face. + """ + + if not App.ActiveDocument: + App.Console.PrintError("No active document. Aborting\n") + return + + if placement: type_check([(placement,App.Placement)], "make_rectangle") + + obj = App.ActiveDocument.addObject("Part::Part2DObjectPython","Rectangle") + Rectangle(obj) + + obj.Length = length + obj.Height = height + obj.Support = support + + if face != None: + obj.MakeFace = face + + if placement: obj.Placement = placement + + if App.GuiUp: + ViewProviderRectangle(obj.ViewObject) + format_object(obj) + select(obj) + + return obj + + +makeRectangle = make_rectangle \ No newline at end of file diff --git a/src/Mod/Draft/draftobjects/rectangle.py b/src/Mod/Draft/draftobjects/rectangle.py new file mode 100644 index 0000000000..fbbea335e7 --- /dev/null +++ b/src/Mod/Draft/draftobjects/rectangle.py @@ -0,0 +1,180 @@ +# *************************************************************************** +# * 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 object code for Draft Rectangle. +""" +## @package rectangle +# \ingroup DRAFT +# \brief This module provides the object code for Draft Rectangle. + +from PySide.QtCore import QT_TRANSLATE_NOOP + +import FreeCAD as App + +import DraftGeomUtils + +from draftutils.utils import get_param + +from draftobjects.base import DraftObject + + +class Rectangle(DraftObject): + """The Rectangle object""" + + def __init__(self, obj): + super(Rectangle, self).__init__(obj, "Rectangle") + + _tip = "Length of the rectangle" + obj.addProperty("App::PropertyDistance", "Length", + "Draft",QT_TRANSLATE_NOOP("App::Property",_tip)) + + _tip = "Height of the rectangle" + obj.addProperty("App::PropertyDistance", "Height", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "Radius to use to fillet the corners" + obj.addProperty("App::PropertyLength", "FilletRadius", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "Size of the chamfer to give to the corners" + obj.addProperty("App::PropertyLength", "ChamferSize", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "Create a face" + obj.addProperty("App::PropertyBool", "MakeFace", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "Horizontal subdivisions of this rectangle" + obj.addProperty("App::PropertyInteger", "Rows", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "Vertical subdivisions of this rectangle" + obj.addProperty("App::PropertyInteger", "Columns", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "The area of this object" + obj.addProperty("App::PropertyArea", "Area", + "Draft",QT_TRANSLATE_NOOP("App::Property", _tip)) + + obj.MakeFace = get_param("fillmode",True) + obj.Length=1 + obj.Height=1 + obj.Rows=1 + obj.Columns=1 + + def execute(self, obj): + """This method is run when the object is created or recomputed.""" + import Part + + if (obj.Length.Value == 0) or (obj.Height.Value == 0): + obj.positionBySupport() + return + + plm = obj.Placement + + shape = None + + if hasattr(obj,"Rows") and hasattr(obj,"Columns"): + # TODO: verify if this is needed: + if obj.Rows > 1: + rows = obj.Rows + else: + rows = 1 + if obj.Columns > 1: + columns = obj.Columns + else: + columns = 1 + # TODO: till here + + if (rows > 1) or (columns > 1): + shapes = [] + l = obj.Length.Value/columns + h = obj.Height.Value/rows + for i in range(columns): + for j in range(rows): + p1 = App.Vector(i*l,j*h,0) + p2 = App.Vector(p1.x+l,p1.y,p1.z) + p3 = App.Vector(p1.x+l,p1.y+h,p1.z) + p4 = App.Vector(p1.x,p1.y+h,p1.z) + p = Part.makePolygon([p1,p2,p3,p4,p1]) + if "ChamferSize" in obj.PropertiesList: + if obj.ChamferSize.Value != 0: + w = DraftGeomUtils.filletWire(p, + obj.ChamferSize.Value, + chamfer=True) + if w: + p = w + if "FilletRadius" in obj.PropertiesList: + if obj.FilletRadius.Value != 0: + w = DraftGeomUtils.filletWire(p, + obj.FilletRadius.Value) + if w: + p = w + if hasattr(obj,"MakeFace"): + if obj.MakeFace: + p = Part.Face(p) + shapes.append(p) + if shapes: + shape = Part.makeCompound(shapes) + + if not shape: + p1 = App.Vector(0,0,0) + p2 = App.Vector(p1.x+obj.Length.Value, + p1.y, + p1.z) + p3 = App.Vector(p1.x+obj.Length.Value, + p1.y+obj.Height.Value, + p1.z) + p4 = App.Vector(p1.x, + p1.y+obj.Height.Value, + p1.z) + shape = Part.makePolygon([p1, p2, p3, p4, p1]) + if "ChamferSize" in obj.PropertiesList: + if obj.ChamferSize.Value != 0: + w = DraftGeomUtils.filletWire(shape, + obj.ChamferSize.Value, + chamfer=True) + if w: + shape = w + if "FilletRadius" in obj.PropertiesList: + if obj.FilletRadius.Value != 0: + w = DraftGeomUtils.filletWire(shape, + obj.FilletRadius.Value) + if w: + shape = w + if hasattr(obj,"MakeFace"): + if obj.MakeFace: + shape = Part.Face(shape) + else: + shape = Part.Face(shape) + + obj.Shape = shape + + if hasattr(obj,"Area") and hasattr(shape,"Area"): + obj.Area = shape.Area + + obj.Placement = plm + + obj.positionBySupport() + + +_Rectangle = Rectangle \ No newline at end of file diff --git a/src/Mod/Draft/draftviewproviders/view_rectangle.py b/src/Mod/Draft/draftviewproviders/view_rectangle.py new file mode 100644 index 0000000000..35faed7ee5 --- /dev/null +++ b/src/Mod/Draft/draftviewproviders/view_rectangle.py @@ -0,0 +1,44 @@ +# *************************************************************************** +# * 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 view provider code for the Draft Rectangle object. +""" +## @package view_rectangle +# \ingroup DRAFT +# \brief This module provides the view provider code for the Draft Rectangle object. + +from PySide.QtCore import QT_TRANSLATE_NOOP + +from draftviewproviders.view_base import ViewProviderDraft + + +class ViewProviderRectangle(ViewProviderDraft): + + def __init__(self,vobj): + super(ViewProviderRectangle, self).__init__(vobj) + + _tip = "Defines a texture image (overrides hatch patterns)" + vobj.addProperty("App::PropertyFile","TextureImage", + "Draft", QT_TRANSLATE_NOOP("App::Property", _tip)) + + +_ViewProviderRectangle = ViewProviderRectangle \ No newline at end of file