AbdulElahGwaith's picture
Upload folder using huggingface_hub
985c397 verified
# 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> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * 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. *
# * *
# * FreeCAD 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 FreeCAD; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
"""Provides various functions to work with edges."""
## @package edges
# \ingroup draftgeoutils
# \brief Provides various functions to work with edges.
import lazy_loader.lazy_loader as lz
import FreeCAD as App
import DraftVecUtils
from draftgeoutils.general import geomType, vec
# Delay import of module until first use because it is heavy
Part = lz.LazyLoader("Part", globals(), "Part")
## \addtogroup draftgeoutils
# @{
def findEdge(anEdge, aList):
"""Return True if edge is found in list of edges."""
for e in range(len(aList)):
if str(anEdge.Curve) == str(aList[e].Curve):
if DraftVecUtils.equals(anEdge.Vertexes[0].Point, aList[e].Vertexes[0].Point):
if DraftVecUtils.equals(anEdge.Vertexes[-1].Point, aList[e].Vertexes[-1].Point):
return e
return None
def orientEdge(edge, normal=None, make_arc=False):
"""Re-orient the edge such that it is in the XY plane.
Re-orients `edge` such that it is in the XY plane.
If `normal` is passed, this is used as the basis for the rotation,
otherwise the placement of `edge` is used.
"""
# This 'normalizes' the placement to the xy plane
edge = edge.copy()
xyDir = App.Vector(0, 0, 1)
base = App.Vector(0, 0, 0)
if normal:
angle = DraftVecUtils.angle(normal, xyDir) * App.Units.Radian
axis = normal.cross(xyDir)
else:
axis = edge.Placement.Rotation.Axis
angle = -1 * edge.Placement.Rotation.Angle * App.Units.Radian
if axis == App.Vector(0.0, 0.0, 0.0):
axis = App.Vector(0.0, 0.0, 1.0)
if angle:
edge.rotate(base, axis, angle)
if isinstance(edge.Curve, Part.Line):
return Part.LineSegment(edge.Curve, edge.FirstParameter, edge.LastParameter)
elif make_arc and isinstance(edge.Curve, Part.Circle) and not edge.Closed:
return Part.ArcOfCircle(
edge.Curve, edge.FirstParameter, edge.LastParameter, edge.Curve.Axis.z > 0
)
elif make_arc and isinstance(edge.Curve, Part.Ellipse) and not edge.Closed:
return Part.ArcOfEllipse(
edge.Curve, edge.FirstParameter, edge.LastParameter, edge.Curve.Axis.z > 0
)
return edge.Curve
def isSameLine(e1, e2):
"""Return True if the 2 edges are lines and have the same points."""
if not isinstance(e1.Curve, Part.LineSegment):
return False
if not isinstance(e2.Curve, Part.LineSegment):
return False
if DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point) and DraftVecUtils.equals(
e1.Vertexes[-1].Point, e2.Vertexes[-1].Point
):
return True
elif DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[0].Point) and DraftVecUtils.equals(
e1.Vertexes[0].Point, e2.Vertexes[-1].Point
):
return True
return False
def is_line(bspline):
"""Return True if the given BSpline curve is a straight line."""
# previous implementation may fail for a multipole straight spline due
# a second order error in tolerance, which introduce a difference of 1e-14
# in the values of the tangents. Also, may fail on a periodic spline.
# step = bspline.LastParameter/10
# b = bspline.tangent(0)
#
# for i in range(10):
# if bspline.tangent(i * step) != b:
# return False
start_point = bspline.StartPoint
end_point = bspline.EndPoint
dist_start_end = end_point.distanceToPoint(start_point)
if abs(bspline.length() - dist_start_end) < 1e-7:
return True
return False
def invert(shape):
"""Return an inverted copy of the edge or wire contained in the shape."""
if shape.ShapeType == "Wire":
edges = [invert(edge) for edge in shape.OrderedEdges]
edges.reverse()
return Part.Wire(edges)
elif shape.ShapeType == "Edge":
if len(shape.Vertexes) == 1:
return shape
if geomType(shape) == "Line":
return Part.LineSegment(shape.Vertexes[-1].Point, shape.Vertexes[0].Point).toShape()
elif geomType(shape) == "Circle":
mp = findMidpoint(shape)
return Part.Arc(shape.Vertexes[-1].Point, mp, shape.Vertexes[0].Point).toShape()
elif geomType(shape) in ["BSplineCurve", "BezierCurve"]:
if isLine(shape.Curve):
return Part.LineSegment(shape.Vertexes[-1].Point, shape.Vertexes[0].Point).toShape()
print("DraftGeomUtils.invert: unable to invert", shape.Curve)
return shape
else:
print("DraftGeomUtils.invert: unable to handle", shape.ShapeType)
return shape
def findMidpoint(edge):
"""Return the midpoint of an edge."""
if edge.Length == 0:
return None
else:
return edge.valueAt(edge.Curve.parameterAtDistance(edge.Length / 2, edge.FirstParameter))
def getTangent(edge, from_point=None):
"""Return the tangent to an edge, including BSpline and circular arcs.
If from_point is given, it is used to calculate the tangent,
only useful for a circular arc.
"""
if geomType(edge) == "Line":
return vec(edge)
elif geomType(edge) == "BSplineCurve" or geomType(edge) == "BezierCurve":
if not from_point:
return None
cp = edge.Curve.parameter(from_point)
return edge.Curve.tangent(cp)[0]
elif geomType(edge) == "Circle":
if not from_point:
v1 = edge.Vertexes[0].Point.sub(edge.Curve.Center)
else:
v1 = from_point.sub(edge.Curve.Center)
return v1.cross(edge.Curve.Axis)
return None
def get_referenced_edges(property_value):
"""Return the Edges referenced by the value of a App:PropertyLink, App::PropertyLinkList,
App::PropertyLinkSub or App::PropertyLinkSubList property."""
edges = []
if not isinstance(property_value, list):
property_value = [property_value]
for element in property_value:
if hasattr(element, "Shape") and element.Shape:
edges += element.Shape.Edges
elif isinstance(element, tuple) and len(element) == 2:
object, subelement_names = element
if hasattr(object, "Shape") and object.Shape:
if len(subelement_names) == 1 and subelement_names[0] == "":
edges += object.Shape.Edges
else:
for subelement_name in subelement_names:
if subelement_name.startswith("Edge"):
edge_number = int(subelement_name.lstrip("Edge")) - 1
if edge_number < len(object.Shape.Edges):
edges.append(object.Shape.Edges[edge_number])
return edges
# compatibility layer
isLine = is_line
## @}