Merge pull request #6605 from Russ4262/fix/misaligned_extensions

Path: Fix some misaligned extensions [Bug]
This commit is contained in:
sliptonic
2022-04-01 09:30:49 -05:00
committed by GitHub

View File

@@ -174,6 +174,44 @@ def setExtensions(obj, extensions):
obj.ExtensionFeature = [(ext.obj, ext.getSubLink()) for ext in extensions]
def getStandardAngle(x, y):
"""getStandardAngle(x, y)...
Return standard degree angle given x and y values of vector."""
angle = math.degrees(math.atan2(y, x))
if angle < 0.0:
return angle + 360.0
return angle
def arcAdjustmentAngle(arc1, arc2):
"""arcAdjustmentAngle(arc1, arc2)...
Return adjustment angle to apply to arc2 in order to align it with arc1.
Arcs must have same center point."""
center = arc1.Curve.Center
cntr2 = arc2.Curve.Center
# Verify centers of arcs are same
if center.sub(cntr2).Length > 0.0000001:
return None
# Calculate midpoint of arc1, and standard angle from center to that midpoint
midPntArc1 = arc1.valueAt(
arc1.FirstParameter + (arc1.LastParameter - arc1.FirstParameter) / 2.0
)
midPntVect1 = midPntArc1.sub(center)
ang1 = getStandardAngle(midPntVect1.x, midPntVect1.y)
# Calculate midpoint of arc2, and standard angle from center to that midpoint
midPntArc2 = arc2.valueAt(
arc2.FirstParameter + (arc2.LastParameter - arc2.FirstParameter) / 2.0
)
midPntVect2 = midPntArc2.sub(center)
ang2 = getStandardAngle(midPntVect2.x, midPntVect2.y)
# Return adjustment angle to apply to arc2 in order to align with arc1
return ang1 - ang2
class Extension(object):
DirectionNormal = 0
DirectionX = 1
@@ -300,6 +338,7 @@ class Extension(object):
PathLog.debug("Extending single edge wire")
edge = edges[0]
if Part.Circle == type(edge.Curve):
PathLog.debug("is Part.Circle")
circle = edge.Curve
# for a circle we have to figure out if it's a hole or a cylinder
p0 = edge.valueAt(edge.FirstParameter)
@@ -315,6 +354,7 @@ class Extension(object):
# assuming the offset produces a valid circle - go for it
if r > 0:
PathLog.debug("radius > 0 - extend outward")
e3 = Part.makeCircle(
r,
circle.Center,
@@ -322,7 +362,18 @@ class Extension(object):
edge.FirstParameter * 180 / math.pi,
edge.LastParameter * 180 / math.pi,
)
# Determine if rotational alignment is necessary for new arc
rotationAdjustment = arcAdjustmentAngle(edge, e3)
if not PathGeom.isRoughly(rotationAdjustment, 0.0):
e3.rotate(
edge.Curve.Center,
FreeCAD.Vector(0.0, 0.0, 1.0),
rotationAdjustment,
)
if endPoints(edge):
PathLog.debug("Make section of donut")
# need to construct the arc slice
e0 = Part.makeLine(
edge.valueAt(edge.FirstParameter),
@@ -332,12 +383,21 @@ class Extension(object):
edge.valueAt(edge.LastParameter),
e3.valueAt(e3.LastParameter),
)
return Part.Wire([e0, edge, e2, e3])
wire = Part.Wire([e0, edge, e2, e3])
# Determine if calculated extension collides with model (wrong direction)
face = Part.Face(wire)
if face.common(feature).Area < face.Area * 0.10:
return wire # Calculated extension is correct
else:
return None # Extension collides with model
extWire = Part.Wire([e3])
self.extFaces = [self._makeCircularExtFace(edge, extWire)]
return extWire
PathLog.debug("radius < 0 - extend inward")
# the extension is bigger than the hole - so let's just cover the whole hole
if endPoints(edge):
# if the resulting arc is smaller than the radius, create a pie slice
@@ -351,13 +411,14 @@ class Extension(object):
return Part.Wire([edge])
else:
PathLog.debug("else is NOT Part.Circle")
PathLog.track(self.feature, self.sub, type(edge.Curve), endPoints(edge))
direction = self._getDirection(sub)
if direction is None:
return None
# return self._extendEdge(feature, edge, direction)
return self._extendEdge(feature, edges[0], direction)
elif sub.isClosed():
PathLog.debug("Extending multi-edge closed wire")
subFace = Part.Face(sub)
@@ -380,7 +441,14 @@ class Extension(object):
return off2D
PathLog.debug("Extending multi-edge open wire")
return extendWire(feature, sub, length)
extendedWire = extendWire(feature, sub, length)
if extendedWire is None:
return extendedWire
# Trim wire face using model
extFace = Part.Face(extendedWire)
trimmedWire = extFace.cut(self.obj.Shape).Wires[0]
return trimmedWire.copy()
def _makeCircularExtFace(self, edge, extWire):
"""_makeCircularExtensionFace(edge, extWire)...