' convert the selected plain holes to be tapped or threaded features. a ' dialog box comes up that asks you what you want to do. Option Explicit Public Sub ConvertSelectedHolesToThreaded Dim doc As FMDocument Dim obj As FMModel Dim hole As FMHole, thread As FMFeature Dim converted As Long Dim activeSetup As String Dim errmsg As String Dim dia As Double, depth As Double Dim plain_cnt As Long, tapped_cnt As Long Dim thread_feat_type As Long, thread_depth As Double, tap_hole_depth As Double, tap_hole_dia As Double Dim pitch As Double, taper_angle As Double, thread_height As Double, thread_mill_depth_per As Double Dim isPitch As Boolean Set doc = ActiveDocument activeSetup = doc.ActiveSetup ' make sure all selected holes are same diameter and depth dia = -1 depth = -1 plain_cnt = 0 tapped_cnt = 0 thread_depth = 0 tap_hole_depth = 0 tap_hole_dia = 0 pitch = 0 taper_angle = 0 For Each obj In doc.Selected If TypeName(obj) = "IFMHole" Then Set hole = obj If( Not CheckHoleType( hole, dia, depth, tapped_cnt, plain_cnt, thread_depth, tap_hole_dia, tap_hole_depth, pitch, taper_angle)) Then Exit Sub End If End If Next obj If( tapped_cnt > 0 And plain_cnt > 0) Then MsgBox "You have selected a mixture of plain and tapped holes. You must select one type or the other." Exit Sub ElseIf( tapped_cnt = 0 And plain_cnt = 0) Then MsgBox "Select 1 or more holes to be converted." Exit Sub ElseIf( tapped_cnt > 0) Then thread_feat_type = 1 ElseIf( plain_cnt > 0) Then thread_feat_type = -1 End If GetThreadDimensions dia, thread_feat_type, thread_depth, tap_hole_depth, tap_hole_dia, pitch, isPitch, taper_angle If( thread_feat_type = -1) Then Exit Sub End If thread_mill_depth_per = doc.Attribute(eAID_ThdDepthPer) thread_height = (pitch * thread_mill_depth_per) / 100.0 converted = 0 For Each obj In doc.Selected If TypeName(obj) = "IFMHole" Then Set hole = obj If( thread_feat_type = 0) Then MakeTappedHole doc, hole, thread, thread_feat_type, dia, thread_depth, tap_hole_depth, pitch, isPitch, taper_angle ElseIf( thread_feat_type = 1) Then MakeThreadMill doc, hole, thread, thread_feat_type, dia, thread_depth, tap_hole_depth, tap_hole_dia, pitch, taper_angle, thread_height End If If( Not thread Is Nothing) Then converted = converted + 1 End If End If Next obj doc.Setups.ActiveSetup = activeSetup If( converted > 0) Then If( thread_feat_type = 0) Then MsgBox( "Converted " + CStr(converted) + " holes to tapped hole features") ElseIf( thread_feat_type = 1) Then MsgBox( "Converted " + CStr(converted) + " holes to thread mill features") End If End If doc.InvalidateAll End Sub Private Function CheckHoleType( hole As FMHole, _ dia As Double, _ depth As Double, _ tapped_cnt As Long, _ plain_cnt As Long, _ thread_depth As Double, _ tap_hole_dia As Double, _ tap_hole_depth As Double, _ pitch As Double, _ taper_angle As Double ) As Boolean Dim d As Double Dim oper As FMOperation Dim twistdrill As FMTwistDrill, endmill As FMEndMill Dim drill_name As String Dim hole_type As tagFMHoleType CheckHoleType = True hole_type = hole.Type If( hole_type = eHT_TappedHole Or hole_type = eHT_CDTappedHole ) Then tapped_cnt = tapped_cnt + 1 d = hole.ThreadDepth If( dia = -1) Then thread_depth = hole.ThreadDepth tap_hole_depth = hole.Depth tap_hole_dia = 0.0 pitch = hole.TPIorPitch If( Not hole.ThreadIsPitch) Then pitch = 1 / pitch End If drill_name = ":d[" If( hole_type = eHT_CDTappedHole) Then drill_name = ":d2[" End If For Each oper In hole.Operations If( InStr( oper.Name, drill_name) > 0) Then If( Not oper.Tool Is Nothing) Then If( TypeName( oper.Tool) = "IFMTwistDrill") Then Set twistdrill = oper.Tool tap_hole_dia = twistdrill.Diameter ElseIf( TypeName( oper.Tool) = "IFMEndMill") Then Set endmill = oper.Tool tap_hole_dia = endmill.Diameter End If End If End If Next oper End If Else plain_cnt = plain_cnt + 1 d = hole.Depth If( dia = -1) Then thread_depth = d tap_hole_depth = d End If End If If( dia = -1) Then dia = hole.Diameter depth = d ElseIf( dia <> hole.Diameter Or depth <> d) Then MsgBox( "hole: '" + hole.Name + "' is not the same diameter(" + Format(hole.Diameter,"##0.0###") + ") or depth(" + Format(d,"##0.0###") + ") as the other holes.") CheckHoleType = False End If End Function Private Sub GetThreadDimensions( dia As Double, _ thread_feat_type As Long, _ thread_depth As Double, _ tap_hole_depth As Double, _ tap_hole_dia As Double, _ pitch As Double, _ isPitch As Boolean, _ taper_angle As Double) Dim rc As Long thread_feat_type = -1 ' cancel Begin Dialog UserDialog 400,240,"Convert Holes"' %GRID:10,6,1,1 Text 10,7,90,14,"FeatureType: ",.Text1 OptionGroup .Group1 OptionButton 110,7,100,14,"Tapped Hole",.DoTappedHole OptionButton 110,21,90,14,"ThreadMill",.DoThreadMill OKButton 300,7,90,21 CancelButton 300,35,90,21 End Dialog Dim dlg As UserDialog rc = Dialog( dlg) If( rc = -1) Then If( dlg.Group1 = 0) Then GetTappedHoleDimensions dia, thread_feat_type, thread_depth, tap_hole_depth, pitch, isPitch, taper_angle Else GetThreadMillDimensions dia, thread_feat_type, thread_depth, tap_hole_depth, tap_hole_dia, pitch, taper_angle End If End If End Sub Private Sub GetThreadMillDimensions( dia As Double, _ thread_feat_type As Long, _ thread_depth As Double, _ tap_hole_depth As Double, _ tap_hole_dia As Double, _ pitch As Double, _ taper_angle As Double) Dim rc As Long Begin Dialog UserDialog 400,203,"Thread Mill Dimensions" ' %GRID:10,7,1,1 OKButton 300,7,90,21 CancelButton 300,35,90,21 Text 20,7,100,14,"Minor Diameter",.Text2 Text 20,35,100,14,"Thread Length",.Text3 Text 20,63,90,14,"Pitch",.Text5 Text 20,91,90,14,"Taper Angle",.Text6 TextBox 130,7,90,21,.MinorDiameter TextBox 130,35,90,21,.ThreadLength TextBox 130,63,90,21,.Pitch TextBox 130,91,90,21,.TaperAngle Text 20,119,90,14,"Tap Drill Dia",.Text1 TextBox 130,119,90,21,.TapDrillDia TextBox 130,147,90,21,.TapDrillDepth Text 20,147,100,14,"Tap Drill Depth",.Text7 End Dialog Dim dlg As UserDialog dlg.MinorDiameter = CStr( dia) dlg.ThreadLength = CStr( thread_depth) dlg.TapDrillDepth = CStr( tap_hole_depth) dlg.TapDrillDia = CStr( tap_hole_dia) dlg.Pitch = CStr( pitch) dlg.TaperAngle = CStr( taper_angle) rc = Dialog( dlg) If( rc = -1) Then dia = CDbl( dlg.MinorDiameter) thread_depth = CDbl( dlg.ThreadLength) tap_hole_depth = CDbl( dlg.TapDrillDepth) tap_hole_dia = CDbl( dlg.TapDrillDia) pitch = CDbl( dlg.Pitch) taper_angle = CDbl( dlg.TaperAngle) If( dia <= 0) Then MsgBox( "Invalid Minor Diameter: " + Format(dia,"##0.0###")) ElseIf( thread_depth <= 0) Then MsgBox( "Invalid Thread Length: " + Format(thread_depth,"##0.0###")) ElseIf( pitch <= 0) Then MsgBox( "Invalid Pitch: " + Format(pitch,"##0.0###")) ElseIf( taper_angle < 0) Then MsgBox( "Invalid Taper Angle: " + Format(taper_angle,"##0.0###")) ElseIf( tap_hole_dia < 0) Then MsgBox( "Invalid Tap Drill Diameter: " + Format(tap_hole_dia,"##0.0###")) ElseIf( tap_hole_depth < 0) Then MsgBox( "Invalid Tap Drill Depth: " + Format(tap_hole_depth,"##0.0###")) Else thread_feat_type = 1 End If End If End Sub Private Sub GetTappedHoleDimensions( dia As Double, _ thread_feat_type As Long, _ thread_depth As Double, _ tap_hole_depth As Double, _ pitch_or_tpi As Double, _ isPitch As Boolean, _ taper_angle As Double) Dim rc As Long Begin Dialog UserDialog 400,203,"Tapped Hole Dimensions" ' %GRID:10,7,1,1 OKButton 300,7,90,21 CancelButton 300,35,90,21 Text 20,7,100,14,"Diameter",.Text2 Text 20,63,100,14,"Thread Depth",.Text3 Text 20,119,90,14,"Taper Angle",.Text6 TextBox 130,7,90,21,.Diameter TextBox 130,63,90,21,.ThreadDepth TextBox 130,91,90,21,.PitchOrTPI TextBox 130,119,90,21,.TaperAngle TextBox 130,35,90,21,.Depth Text 20,35,90,14,"Depth",.Text1 OptionGroup .Group1 OptionButton 20,91,50,14,"Pitch",.OptionButton1 OptionButton 80,91,40,14,"TPI",.OptionButton2 End Dialog Dim dlg As UserDialog dlg.Diameter = CStr( dia) dlg.ThreadDepth = CStr( thread_depth) dlg.PitchOrTPI = CStr( 0.0) dlg.Group1 = 1 dlg.TaperAngle = CStr( taper_angle) dlg.Depth = CStr( tap_hole_depth) rc = Dialog( dlg) If( rc = -1) Then dia = CDbl( dlg.Diameter) thread_depth = CDbl( dlg.ThreadDepth) pitch_or_tpi = CDbl( dlg.PitchOrTPI) taper_angle = CDbl( dlg.TaperAngle) tap_hole_depth = CDbl( dlg.Depth) If( dlg.Group1 = 0) Then isPitch = True Else isPitch = False End If If( dia <= 0) Then MsgBox( "Invalid Diameter: " + Format(dia,"##0.0###")) ElseIf( thread_depth <= 0) Then MsgBox( "Invalid Thread Depth: " + Format(thread_depth,"##0.0###")) ElseIf( tap_hole_depth <= thread_depth) Then MsgBox( "Invalid Depth: " + Format(tap_hole_depth,"##0.0###")) ElseIf( pitch_or_tpi <= 0) Then MsgBox( "Invalid Pitch: " + Format(pitch_or_tpi,"##0.0###")) ElseIf( taper_angle < 0) Then MsgBox( "Invalid Taper Angle: " + Format(taper_angle,"##0.0###")) Else thread_feat_type = 0 End If End If End Sub Private Sub MakeThreadMill( doc As FMDocument, _ hole As FMHole, _ thread As FMFeature, _ thread_feat_type As Long, _ dia As Double, _ thread_depth As Double, _ tap_hole_depth As Double, _ tap_hole_dia As Double, _ pitch As Double, _ taper_angle As Double, _ thread_height As Double ) Dim locType As tagFMFeatureLocationType Dim x As Double, y As Double, z As Double, angle As Double, radialLateralOffset As Double, radialAngle As Double, radialRadius As Double, BAxisTiltAngle As Double Dim relativePosition As Boolean, flipAnchor As Boolean Dim order As Long Dim setup As FMSetup Dim hole_type As tagFMHoleType Dim err_msg As String Set thread = Nothing Set setup = hole.Setup If( Not setup Is Nothing) Then ' setup is nothing if hole is object of pattern setup.Activate order = hole.Order End If ' get full location information hole.GetFeatureLocation( locType, x, y, z, angle, radialLateralOffset, radialAngle, radialRadius, BAxisTiltAngle, relativePosition, flipAnchor) ' create tap drill hole If( tap_hole_dia > 0 And tap_hole_depth > 0) Then hole_type = hole.Type If( hole_type = eHT_TappedHole) Then hole_type = eHT_PlainHole ElseIf( hole_type = eHT_CDTappedHole) Then hole_type = eHT_CounterDrill End If hole.Update( hole_type, tap_hole_dia, tap_hole_depth,,,,,,,,,err_msg,False) If( err_msg <> "") Then MsgBox( err_msg) thread_feat_type = -1 Exit Sub End If order = order + 1 ElseIf( Not setup Is Nothing) Then hole.Delete End If ' create thread mill Set thread = doc.Features.AddThreadMilling( False,False,dia,pitch,thread_depth,thread_height,taper_angle,x,y,z, err_msg) If( err_msg <> "") Then MsgBox( err_msg) thread_feat_type = -1 Set thread = Nothing Exit Sub End If ' follow tap drill hole in process plan If( Not setup Is Nothing) Then thread.Order = order End If ' set location of each if not just xyz If( locType <> eFLT_xyz) Then thread.SetFeatureLocation( locType, x,y,z,angle,radialLateralOffset,radialAngle,radialRadius,BAxisTiltAngle,relativePosition,flipAnchor) End If End Sub Private Sub MakeTappedHole( doc As FMDocument, _ hole As FMHole, _ thread As FMFeature, _ thread_feat_type As Long, _ dia As Double, _ thread_depth As Double, _ tap_hole_depth As Double, _ pitch As Double, _ isPitch As Boolean, _ taper_angle As Double) Dim hole_type As tagFMHoleType Dim err_msg As String ' change hole type to tapped hole_type = hole.Type If( hole_type = eHT_CounterDrill) Then hole_type = eHT_CDTappedHole Else hole_type = eHT_TappedHole End If hole.Update( hole_type, dia,,,,taper_angle,,,thread_depth,pitch,isPitch,err_msg,False) If( err_msg <> "") Then MsgBox( err_msg) thread_feat_type = -1 Else Set thread = hole End If End Sub