Make CircularHoleBase use drillableLib

debugs

remove deprecated PathUtils.isDrillable

drillableLib cmake

make PathProfile use new drillableLib
This commit is contained in:
sliptonic
2021-12-05 20:16:23 -06:00
parent f156d9daea
commit fc2d6c172b
9 changed files with 133 additions and 290 deletions

View File

@@ -73,119 +73,6 @@ def waiting_effects(function):
return new_function
def isDrillable(obj, candidate, tooldiameter=None, includePartials=False):
"""
Checks candidates to see if they can be drilled.
Candidates can be either faces - circular or cylindrical or circular edges.
The tooldiameter can be optionally passed. if passed, the check will return
False for any holes smaller than the tooldiameter.
obj=Shape
candidate = Face or Edge
tooldiameter=float
"""
PathLog.track(
"obj: {} candidate: {} tooldiameter {}".format(obj, candidate, tooldiameter)
)
if list == type(obj):
for shape in obj:
if isDrillable(shape, candidate, tooldiameter, includePartials):
return (True, shape)
return (False, None)
drillable = False
try:
if candidate.ShapeType == "Face":
face = candidate
# eliminate flat faces
if (round(face.ParameterRange[0], 8) == 0.0) and (
round(face.ParameterRange[1], 8) == round(math.pi * 2, 8)
):
for (
edge
) in face.Edges: # Find seam edge and check if aligned to Z axis.
if isinstance(edge.Curve, Part.Line):
PathLog.debug("candidate is a circle")
v0 = edge.Vertexes[0].Point
v1 = edge.Vertexes[1].Point
# check if the cylinder seam is vertically aligned. Eliminate tilted holes
if (
numpy.isclose(v1.sub(v0).x, 0, rtol=1e-05, atol=1e-06)
) and (numpy.isclose(v1.sub(v0).y, 0, rtol=1e-05, atol=1e-06)):
drillable = True
# vector of top center
lsp = Vector(
face.BoundBox.Center.x,
face.BoundBox.Center.y,
face.BoundBox.ZMax,
)
# vector of bottom center
lep = Vector(
face.BoundBox.Center.x,
face.BoundBox.Center.y,
face.BoundBox.ZMin,
)
# check if the cylindrical 'lids' are inside the base
# object. This eliminates extruded circles but allows
# actual holes.
if obj.isInside(lsp, 1e-6, False) or obj.isInside(
lep, 1e-6, False
):
PathLog.track(
"inside check failed. lsp: {} lep: {}".format(
lsp, lep
)
)
drillable = False
# eliminate elliptical holes
elif not hasattr(face.Surface, "Radius"):
PathLog.debug("candidate face has no radius attribute")
drillable = False
else:
if tooldiameter is not None:
drillable = face.Surface.Radius >= tooldiameter / 2
else:
drillable = True
elif type(face.Surface) == Part.Plane and PathGeom.pointsCoincide(
face.Surface.Axis, FreeCAD.Vector(0, 0, 1)
):
if len(face.Edges) == 1 and type(face.Edges[0].Curve) == Part.Circle:
center = face.Edges[0].Curve.Center
if obj.isInside(center, 1e-6, False):
if tooldiameter is not None:
drillable = face.Edges[0].Curve.Radius >= tooldiameter / 2
else:
drillable = True
else:
for edge in candidate.Edges:
if isinstance(edge.Curve, Part.Circle) and (
includePartials or edge.isClosed()
):
PathLog.debug("candidate is a circle or ellipse")
if not hasattr(edge.Curve, "Radius"):
PathLog.debug("No radius. Ellipse.")
drillable = False
else:
PathLog.debug("Has Radius, Circle")
if tooldiameter is not None:
drillable = edge.Curve.Radius >= tooldiameter / 2
if not drillable:
FreeCAD.Console.PrintMessage(
"Found a drillable hole with diameter: {}: "
"too small for the current tool with "
"diameter: {}".format(
edge.Curve.Radius * 2, tooldiameter
)
)
else:
drillable = True
PathLog.debug("candidate is drillable: {}".format(drillable))
except Exception as ex: # pylint: disable=broad-except
PathLog.warning(
translate("Path", "Issue determine drillability: {}").format(ex)
)
return drillable
# set at 4 decimal places for testing
def fmt(val):
return format(val, ".4f")