Download src/Mod/Draft/draftobjects/wire.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 12.6 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Draft/draftobjects/wire.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Draft/draftobjects/wire.py
-
curl -L -o wire.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Draft/draftobjects/wire.py
12.6 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # *************************************************************************** | |
| # * Copyright (c) 2009, 2010 Yorik van Havre <yorik@uncreated.net> * | |
| # * Copyright (c) 2009, 2010 Ken Cline <cline@frii.com> * | |
| # * 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 * | |
| # * * | |
| # *************************************************************************** | |
| """Provides the object code for the Wire (Polyline) object.""" | |
| ## @package wire | |
| # \ingroup draftobjects | |
| # \brief Provides the object code for the Wire (Polyline) object. | |
| ## \addtogroup draftobjects | |
| # @{ | |
| import math | |
| from PySide.QtCore import QT_TRANSLATE_NOOP | |
| import FreeCAD as App | |
| import DraftGeomUtils | |
| import DraftVecUtils | |
| from draftobjects.base import DraftObject | |
| from draftutils import gui_utils | |
| from draftutils import params | |
| from draftutils.messages import _log | |
| class Wire(DraftObject): | |
| """The Wire object""" | |
| def __init__(self, obj): | |
| super().__init__(obj, "Wire") | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "The vertices of the wire") | |
| obj.addProperty("App::PropertyVectorList", "Points", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "If the wire is closed or not") | |
| obj.addProperty("App::PropertyBool", "Closed", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP( | |
| "App::Property", "The base object is the wire, it's formed from 2 objects" | |
| ) | |
| obj.addProperty("App::PropertyLink", "Base", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP( | |
| "App::Property", "The tool object is the wire, it's formed from 2 objects" | |
| ) | |
| obj.addProperty("App::PropertyLink", "Tool", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "The start point of this line") | |
| obj.addProperty("App::PropertyVectorDistance", "Start", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "The end point of this line") | |
| obj.addProperty("App::PropertyVectorDistance", "End", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "The length of this line") | |
| obj.addProperty("App::PropertyLength", "Length", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "Radius to use to fillet the corners") | |
| obj.addProperty("App::PropertyLength", "FilletRadius", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "Size of the chamfer to give to the corners") | |
| obj.addProperty("App::PropertyLength", "ChamferSize", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "Create a face if this object is closed") | |
| obj.addProperty("App::PropertyBool", "MakeFace", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "The number of subdivisions of each edge") | |
| obj.addProperty("App::PropertyInteger", "Subdivisions", "Draft", _tip, locked=True) | |
| _tip = QT_TRANSLATE_NOOP("App::Property", "The area of this object") | |
| obj.addProperty("App::PropertyArea", "Area", "Draft", _tip, locked=True) | |
| obj.MakeFace = params.get_param("MakeFaceMode") | |
| obj.Closed = False | |
| def onDocumentRestored(self, obj): | |
| super().onDocumentRestored(obj) | |
| gui_utils.restore_view_object(obj, vp_module="view_wire", vp_class="ViewProviderWire") | |
| vobj = getattr(obj, "ViewObject", None) | |
| if vobj is None: | |
| return | |
| if hasattr(vobj, "ArrowSize") or hasattr(vobj, "ArrowType") or hasattr(vobj, "EndArrow"): | |
| self.update_properties_1v1(obj, vobj) | |
| def update_properties_1v1(self, obj, vobj): | |
| """Update view properties.""" | |
| vobj.Proxy._set_properties(vobj) | |
| if getattr(vobj, "EndArrow", False) and hasattr(vobj, "ArrowType"): | |
| vobj.ArrowTypeEnd = vobj.ArrowType | |
| if hasattr(vobj, "ArrowSize"): | |
| vobj.ArrowSizeStart = vobj.ArrowSize | |
| vobj.ArrowSizeEnd = vobj.ArrowSize | |
| vobj.setPropertyStatus("ArrowSize", "-LockDynamic") | |
| vobj.removeProperty("ArrowSize") | |
| if hasattr(vobj, "ArrowType"): | |
| vobj.setPropertyStatus("ArrowType", "-LockDynamic") | |
| vobj.removeProperty("ArrowType") | |
| if hasattr(vobj, "EndArrow"): | |
| vobj.setPropertyStatus("EndArrow", "-LockDynamic") | |
| vobj.removeProperty("EndArrow") | |
| _log("v1.1, " + obj.Name + ", migrated view properties") | |
| def execute(self, obj): | |
| if self.props_changed_placement_only( | |
| obj | |
| ): # Supplying obj is required because of `Base` and `Tool`. | |
| obj.positionBySupport() | |
| self.update_start_end(obj) | |
| self.props_changed_clear() | |
| return | |
| import Part | |
| plm = obj.Placement | |
| if obj.Base and (not obj.Tool): | |
| if obj.Base.isDerivedFrom("Sketcher::SketchObject"): | |
| shape = obj.Base.Shape.copy() | |
| if obj.Base.Shape.isClosed(): | |
| if getattr(obj, "MakeFace", True): | |
| shape = Part.Face(shape) | |
| obj.Shape = shape | |
| elif obj.Base and obj.Tool: | |
| if hasattr(obj.Base, "Shape") and hasattr(obj.Tool, "Shape"): | |
| if (not obj.Base.Shape.isNull()) and (not obj.Tool.Shape.isNull()): | |
| sh1 = obj.Base.Shape.copy() | |
| sh2 = obj.Tool.Shape.copy() | |
| shape = sh1.fuse(sh2) | |
| if DraftGeomUtils.isCoplanar(shape.Faces): | |
| shape = DraftGeomUtils.concatenate(shape) | |
| obj.Shape = shape | |
| p = [] | |
| for v in shape.Vertexes: | |
| p.append(v.Point) | |
| if obj.Points != p: | |
| obj.Points = p | |
| elif obj.Points: | |
| if obj.Points[0] == obj.Points[-1]: | |
| if not obj.Closed: | |
| obj.Closed = True | |
| obj.Points.pop() | |
| if obj.Closed and (len(obj.Points) > 2): | |
| pts = obj.Points | |
| if getattr(obj, "Subdivisions", 0) > 0: | |
| npts = [] | |
| for i in range(len(pts)): | |
| p1 = pts[i] | |
| npts.append(pts[i]) | |
| if i == len(pts) - 1: | |
| p2 = pts[0] | |
| else: | |
| p2 = pts[i + 1] | |
| v = p2.sub(p1) | |
| v = DraftVecUtils.scaleTo(v, v.Length / (obj.Subdivisions + 1)) | |
| for j in range(obj.Subdivisions): | |
| npts.append(p1.add(App.Vector(v).multiply(j + 1))) | |
| pts = npts | |
| shape = Part.makePolygon(pts + [pts[0]]) | |
| 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 | |
| try: | |
| if getattr(obj, "MakeFace", True): | |
| shape = Part.Face(shape) | |
| except Part.OCCError: | |
| pass | |
| else: | |
| edges = [] | |
| pts = obj.Points[1:] | |
| lp = obj.Points[0] | |
| for p in pts: | |
| if not DraftVecUtils.equals(lp, p): | |
| if getattr(obj, "Subdivisions", 0) > 0: | |
| npts = [] | |
| v = p.sub(lp) | |
| v = DraftVecUtils.scaleTo(v, v.Length / (obj.Subdivisions + 1)) | |
| edges.append(Part.LineSegment(lp, lp.add(v)).toShape()) | |
| lv = lp.add(v) | |
| for j in range(obj.Subdivisions): | |
| edges.append(Part.LineSegment(lv, lv.add(v)).toShape()) | |
| lv = lv.add(v) | |
| else: | |
| edges.append(Part.LineSegment(lp, p).toShape()) | |
| lp = p | |
| try: | |
| shape = Part.Wire(edges) | |
| except Part.OCCError: | |
| print("Error wiring edges") | |
| shape = None | |
| 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 shape: | |
| obj.Shape = shape | |
| if hasattr(obj, "Area") and hasattr(shape, "Area"): | |
| obj.Area = shape.Area | |
| if hasattr(obj, "Length"): | |
| obj.Length = shape.Length | |
| obj.Placement = plm | |
| obj.positionBySupport() | |
| self.update_start_end(obj) | |
| self.props_changed_clear() | |
| def onChanged(self, obj, prop): | |
| self.props_changed_store(prop) | |
| tol = 1e-7 | |
| if prop == "Start": | |
| pts = obj.Points | |
| invpl = App.Placement(obj.Placement).inverse() | |
| realfpstart = invpl.multVec(obj.Start) | |
| if pts: | |
| if not pts[0].isEqual(realfpstart, tol): | |
| pts[0] = realfpstart | |
| obj.Points = pts | |
| elif prop == "End": | |
| pts = obj.Points | |
| invpl = App.Placement(obj.Placement).inverse() | |
| realfpend = invpl.multVec(obj.End) | |
| if len(pts) > 1: | |
| if not pts[-1].isEqual(realfpend, tol): | |
| pts[-1] = realfpend | |
| obj.Points = pts | |
| elif prop == "Length": | |
| if len(obj.Points) == 2 and obj.Length.Value > tol: | |
| vec = obj.Points[-1].sub(obj.Points[0]) | |
| if abs(obj.Length.Value - vec.Length) > tol: | |
| vec = DraftVecUtils.scaleTo(vec, obj.Length.Value) | |
| obj.Points = [obj.Points[0], obj.Points[0].add(vec)] | |
| def update_start_end(self, obj): | |
| tol = 1e-7 | |
| pl = App.Placement(obj.Placement) | |
| if len(obj.Points) > 1: | |
| displayfpstart = pl.multVec(obj.Points[0]) | |
| displayfpend = pl.multVec(obj.Points[-1]) | |
| if not obj.Start.isEqual(displayfpstart, tol): | |
| obj.Start = displayfpstart | |
| if not obj.End.isEqual(displayfpend, tol): | |
| obj.End = displayfpend | |
| # Alias for compatibility with v0.18 and earlier | |
| _Wire = Wire | |
| ## @} | |