Skip to content

Instantly share code, notes, and snippets.

@stephensmitchell
Created October 14, 2025 10:35
Show Gist options
  • Select an option

  • Save stephensmitchell/2826a70de82073afba3afdee9709f132 to your computer and use it in GitHub Desktop.

Select an option

Save stephensmitchell/2826a70de82073afba3afdee9709f132 to your computer and use it in GitHub Desktop.
Pocket Hole Creator
#https://help.alibre.com/articles/#!alibre-help-v28/pocket-hole-creator
# Pocket Hole Creator
# (c) Alibre, LLC 2019, All Rights Reserved
# Version 1.00
from __future__ import division
from math import *
# compares two points [X1, Y1, Z1] and [X2, Y2, Z2]
# returns true if they are the same
def PointsAreEqual(P1, P2):
if (round(P1[0], 6) == round(P2[0], 6) and
round(P1[1], 6) == round(P2[1], 6) and
round(P1[2], 6) == round(P2[2], 6)):
return True
else:
return False
# gets part faces that use an edge
# returns a list of faces
def GetFacesFromEdge(Prt, Ege):
Faces = []
PartEdge = [[Ege.Vertices[0].X, Ege.Vertices[0].Y, Ege.Vertices[0].Z], [Ege.Vertices[1].X, Ege.Vertices[1].Y, Ege.Vertices[1].Z]]
for Fce in Prt.Faces:
for Edg in Fce.GetEdges():
EdgeVertices = Edg.GetVertices()
V1 = [EdgeVertices[0].X, EdgeVertices[0].Y, EdgeVertices[0].Z]
V2 = [EdgeVertices[1].X, EdgeVertices[1].Y, EdgeVertices[1].Z]
if ((PointsAreEqual(V1, PartEdge[0]) and PointsAreEqual(V2, PartEdge[1])) or
(PointsAreEqual(V2, PartEdge[0]) and PointsAreEqual(V1, PartEdge[1]))):
Faces.append(Fce)
return Faces
# given a part, face and edge of the face this returns the other face
# that shares the same edge
def GetOtherFace(Prt, Edg, TopFace):
Fces = GetFacesFromEdge(Prt, Edg)
for EgeFace in Fces:
if EgeFace.Name != TopFace.Name:
return EgeFace
return None
# creates a pocket hole
def CreatePocketHole(Values):
# TargetEdge = edge that the pocket hole is on
# Fce = face where the pocket is inserted
# DistanceFromEdge = distance from the edge of the face for the packet
# Depth = distance from pocket to drill hole
# Diameter = diameter of packet
# DrillDiameter = diameter of drill hole
# Angle = angle of pocket
TargetEdge = Values[1]
Fce = Values[2]
DistanceFromEdge = Values[3]
Depth = Values[4]
Diameter = Values[5]
DrillDiameter = Values[6]
Angle = Values[7]
Prt = Fce.GetPart()
# get face that has exit hole
ExitFace = GetOtherFace(Prt, TargetEdge, Fce)
# get thickness of part (height of face with exit hole)
ExitFaceEdges = ExitFace.GetEdges()
Thickness = 0
for ExEdg in ExitFaceEdges:
if ExEdg.Length > 0:
if ExEdg.Length != TargetEdge.Length:
Thickness = ExEdg.Length
if Thickness == 0:
print "Unable to get thickness of part"
sys.exit()
# get location of center of exit hole
ExitHoleCenterX = TargetEdge.Length - DistanceFromEdge
ExitHoleCenterY = Thickness / 2.0
# get location of exit hole center in 3D coordinates
ExitSk = Prt.AddSketch('Exit Sk', ExitFace)
ExitSk.StartFaceMapping(TargetEdge.Vertices[0], TargetEdge.Vertices[1])
ExitPt = ExitSk.AddPoint(ExitHoleCenterX, ExitHoleCenterY, False)
ExitSk.StopFaceMapping()
ExitPtGlobal = ExitSk.PointtoGlobal(ExitSk.Figures[0].X, ExitSk.Figures[0].Y)
Prt.RemoveSketch(ExitSk)
# create exit point
ExitPoint = Prt.AddPoint('Exit', ExitPtGlobal[0], ExitPtGlobal[1], ExitPtGlobal[2])
# get location of entry hole in 2D
EntryHoleCenterX = DistanceFromEdge
EntryHoleCenterY = (Thickness / 2.0) / tan(radians(Angle))
# get location of entry hole center in 3D coordinates
EntrySk = Prt.AddSketch('Entry Sk', Fce)
EntrySk.StartFaceMapping(TargetEdge.Vertices[0], TargetEdge.Vertices[1])
EntryPt = EntrySk.AddPoint(EntryHoleCenterX, EntryHoleCenterY, False)
EntrySk.StopFaceMapping()
EntryPtGlobal = EntrySk.PointtoGlobal(EntrySk.Figures[0].X, EntrySk.Figures[0].Y)
Prt.RemoveSketch(EntrySk)
# create entry point
EntryPoint = Prt.AddPoint('Entry', EntryPtGlobal[0], EntryPtGlobal[1], EntryPtGlobal[2])
# create axis from entry to exit point
PocketAxis = Prt.AddAxis('Pocket Axis', EntryPoint.GetCoordinates(), ExitPoint.GetCoordinates())
# create plane perpendicular to axis on the start point
nx = ExitPtGlobal[0] - EntryPtGlobal[0]
ny = ExitPtGlobal[1] - EntryPtGlobal[1]
nz = ExitPtGlobal[2] - EntryPtGlobal[2]
EntryPlane = Prt.AddPlane('Entry Plane', [nx, ny, nz], EntryPoint.GetCoordinates())
# get drill distances
EntrytoExitDistance = (Thickness / 2.0) / sin(radians(Angle))
Drill1Distance = EntrytoExitDistance - Depth
# first drill
Drill1Sk = Prt.AddSketch('Drill 1', EntryPlane)
DrillCenter = Drill1Sk.GlobaltoPoint(EntryPtGlobal[0], EntryPtGlobal[1], EntryPtGlobal[2])
Drill1Sk.AddCircle(DrillCenter[0], DrillCenter[1], Diameter, False)
Prt.AddExtrudeCut('Drill 1', Drill1Sk, Drill1Distance * 2, False, Part.EndCondition.MidPlane, None, 0, Part.DirectionType.Normal, None, 0, 0)
# second drill
Drill2Sk = Prt.AddSketch('Drill 2', EntryPlane)
DrillCenter = Drill2Sk.GlobaltoPoint(EntryPtGlobal[0], EntryPtGlobal[1], EntryPtGlobal[2])
Drill2Sk.AddCircle(DrillCenter[0], DrillCenter[1], DrillDiameter, False)
Prt.AddExtrudeCut('Drill 2', Drill2Sk, 0, False, Part.EndCondition.ThroughAll, None, 0, Part.DirectionType.Normal, None, 0, 0)
# clean up
EntryPoint.Hide()
ExitPoint.Hide()
PocketAxis.Hide()
EntryPlane.Hide()
###########################################################################################
# check minimum requirements
if AlibreScriptVersion < 1110:
sys.exit('Please upgrade your copy of Alibre Design to use this script')
ScriptName = 'Pocket Hole Creator'
Win = Windows()
# define options to show in dialog window
Options = []
Options.append([None, WindowsInputTypes.Image, 'PocketHoleCreatorIcon.png', 200])
Options.append(['Edge', WindowsInputTypes.Edge, None])
Options.append(['Face', WindowsInputTypes.Face, None])
Options.append(['Distance From Edge', WindowsInputTypes.Real, 20.0])
Options.append(['Depth', WindowsInputTypes.Real, 10.0])
Options.append(['Diameter', WindowsInputTypes.Real, 10.0])
Options.append(['Drill Diameter', WindowsInputTypes.Real, 4.0])
Options.append(['Angle', WindowsInputTypes.Real, 15.0])
# show utility window
Win.UtilityDialog(ScriptName, 'Create Pocket Hole', CreatePocketHole, None, Options, 200)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment