' UDF and UDO for reverse boring ' This macro can be used to create a UDF for back boring intoa hole. It asks the user for the shift, bore depth, dore diameter ' and other parameters, and creates the UDF. When the UDO is simulated, it takes the tool, shifts it by the required distance, rapids it ' down to the end of the hole, and then starts the spindle. If boring is selected as 'Only Up', then a bore down value of 0.005 is assumed. ' Otherwise, if 'bore up and down' is selected, then the optional bore-down value inputed by the user is used to bore down, stop the spindle, ' shift it, orient it and then rapid it up out of the hole. ' It is the user's responsibility to correctly input the shift parameters so that the tool does not gouge the stock Option Explicit Dim udf_reverse_boring As FMUserFeatureRegister Dim udo_reverse_boring As FMUserOperationRegister Private Sub AddIn_OnConnect(ByVal flags As FeatureCAM.tagFMAddInFlags) Dim feed_direction (1) As String feed_direction(0) = "Only Up" feed_direction(1) = "Up and Down" Dim spindle_direction (1) As String spindle_direction(0) = "CW" spindle_direction(1) = "CCW" Dim docc As FMDocument Set docc = Application.ActiveDocument 'Debug.Print docc.Attribute(eAID_ZRapid) ' The user inputed variables Set udf_reverse_boring = Application.RegisterUserFeature( "Reverse bore", eST_Milling, _ "reverse_bore", eUDF_PickLocation) udf_reverse_boring.AddDataDefinition ( "Bore Diameter", eUDT_PositiveDouble, 0, 0,,eUDT_UseSelectedDiameter) udf_reverse_boring.AddDataDefinition ( "Hole Depth", eUDT_PositiveDouble, 0, 0) udf_reverse_boring.AddDataDefinition ( "Bore Dwell", eUDT_PositiveDouble, 0, 0) udf_reverse_boring.AddDataDefinition ( "clearence for plunge", eUDT_PositiveDouble, 0, 0) udf_reverse_boring.AddDataDefinition ( "Bore Up", eUDT_PositiveDouble, 0, 0) udf_reverse_boring.AddDataDefinition ( "Optional dwell", eUDT_PositiveDouble, 0, 0) udf_reverse_boring.AddDataDefinition ( "Feed direction",eUDT_DropList,0, 0, feed_direction) udf_reverse_boring.AddDataDefinition ( "Feed down value",eUDT_PositiveDouble,0, 0, 0) udf_reverse_boring.AddDataDefinition ( "Spindle direction",eUDT_DropList,0, 0, spindle_direction) udf_reverse_boring.AddDataDefinition ( "X axis shift", eUDT_Double, 0, 0) udf_reverse_boring.AddDataDefinition ( "Y axis shift", eUDT_Double, 0, 0) 'udf_reverse_boring.AddDataDefinition ( "Z Rapid Plane", eUDT_Double, docc.Attribute(eAID_ZRapid), docc.Attribute(eAID_ZRapid)*2.54) udf_reverse_boring.AddDataDefinition ( "Z Rapid Plane", eUDT_Double, 1, 2.54) udf_reverse_boring.AddDataDefinition ( "",eUDT_None,"","") udf_reverse_boring.AddDataDefinition ( "Version", eUDT_StaticString, "1.0", "1.0") Set udo_reverse_boring = Application.RegisterUserOperation( "Reverse bore operation", "reverse_bore_operation", _ eTG_EndMill, eST_Milling) udo_reverse_boring.AddAttributeDefinition2 eAID_ZRampClear udo_reverse_boring.AddAttributeDefinition2 eAID_ZClear If flags = eAIF_ConnectUserLoad Then Dim Doc As FMDocument For Each Doc In Application.Documents Doc.InvalidateToolpaths Next Doc End If End Sub Private Sub AddIn_OnDisConnect(ByVal flags As FeatureCAM.tagFMAddInFlags) Set udf_reverse_boring = Nothing Set udo_reverse_boring = Nothing If flags = eAIF_DisConnectUserUnLoad Then Dim Doc As FMDocument For Each Doc In Application.Documents Doc.InvalidateToolpaths Next Doc End If End Sub Private Sub Application_UserFeatureVerify(Doc As FeatureCAM.FMDocument, UDF As FeatureCAM.FMUserFeature, _ valid As Variant, error_message As String) If( UDF.RegisteredName = udf_reverse_boring.Name ) Then Dim Diameter As Double, Depth As Double, clearance As Double, bore_depth As Double, dwell As Double, bore_dwell As Double, radius As Double, x_axis_shift As Double, y_axis_shift As Double, feed_down As Double Dim feed_direction As String, spindle_direction As String, z_rapid_plane As Double Diameter = UDF.GetData( 0) ' data object #0 is diameter Depth = UDF.GetData( 1) ' data object #1 is depth bore_dwell = UDF.GetData( 2) ' data object #2 is dwell clearance = UDF.GetData( 3) ' data object #3 is clearance value bore_depth = UDF.GetData( 4) ' data object #4 is bore depth dwell = UDF.GetData( 5) ' data object #5 is the optional dwell feed_direction = UDF.GetData( 6) ' data object #6 is the direction of the feed feed_down = UDF.GetData( 7) ' data object #7 is the optional feed down value spindle_direction = UDF.GetData( 8) ' data object #8 is the spindle direction - CW or CCW x_axis_shift = UDF.GetData( 9) ' data object #9 is the shift in x-axis y_axis_shift = UDF.GetData( 10) ' data object #10 is the shift in y-axis z_rapid_plane = UDF.GetData( 11) radius = Diameter/2 Dim UDO As FMUserOperation Set UDO = UDF.AddUserOperation ( "Reverse bore operation", Diameter, Depth, bore_dwell, clearance, bore_depth, dwell, feed_direction, feed_down, spindle_direction, x_axis_shift, y_axis_shift, z_rapid_plane ) valid = True If valid Then ' make the cross section of the bore and display some wireframe geometry UDF.AddCrossSectionLinear( radius, 0) UDF.AddCrossSectionLinear( radius, -Depth ) UDF.AddCrossSectionLinear( 0, -Depth) End If End If End Sub ' this event handler is called in order to perform the automatic tool selection ' Private Sub Application_UserOperationDefaultTool(UDO As FeatureCAM.FMUserOperation, tool_name As String, _ valid As Variant, Crib As FeatureCAM.FMToolCrib) 'Choose the first tool that appears in the crib, therefore allowing the user to choose their own tool in the wizard If( UDO.RegisteredName = udo_reverse_boring.Name) Then Dim Tools As FMTools Dim Tool As FMEndMill Set Tools = Crib.EndMills Set Tool = Tools(1) tool_name = Tool.Name End If End Sub ' this event handler is called upon in order to compute automatic feeds and speeds ' Private Sub Application_UserOperationFeedSpeed(UDO As FeatureCAM.FMUserOperation, Feed As Double, speed As Double, valid As Variant) 'If Not unloading Then If( UDO.RegisteredName = udo_reverse_boring.Name ) Then Dim Tool As FMEndMill Set Tool = UDO.Tool UDO.MillFeedSpeed(Feed, speed, eFSOT_Profile,True) 'UDO.TurnFeedSpeed( Feed, Speed, Tool.diameter, eFSOT_Profile, True ) valid = True End If 'End If End Sub ' this event handler is called upon in order to compute the toolpath for the UDO ' Private Sub Application_UserOperationToolPath(UDO As FeatureCAM.FMUserOperation, valid As Variant) If( UDO.RegisteredName = udo_reverse_boring.Name ) Then Dim Diameter As Double, Depth As Double, clearance As Double, bore_depth As Double, dwell As Double, bore_dwell As Double Dim feed_direction As String, spindle_direction As String, radius As Double, x_axis_shift As Double, y_axis_shift As Double Dim ZClear As Double, ZRapidPlane As Double, speed As Integer, feed_down As Double', ZRampClear As Double, Diameter = UDO.GetArgument( 0) Depth = UDO.GetArgument( 1) bore_dwell = UDO.GetArgument( 2) clearance = UDO.GetArgument( 3) bore_depth = UDO.GetArgument( 4) dwell = UDO.GetArgument( 5) feed_direction = UDO.GetArgument( 6) feed_down = UDO.GetArgument( 7) spindle_direction = UDO.GetArgument( 8) x_axis_shift = UDO.GetArgument( 9) y_axis_shift = UDO.GetArgument( 10) ZRapidPlane = UDO.GetArgument( 11) ' Calculate the radius radius = Diameter/2 Dim Tool As FMEndMill, ToolDia As Double Set Tool = UDO.Tool ToolDia = Tool.Diameter If( UDO.Document.Metric <> Tool.Metric ) Then If( Tool.Metric) Then ToolDia = ToolDia / 25.4 Else ToolDia = ToolDia * 25.4 End If End If 'ZRampClear = UDO.Attribute(eAID_ZRampClear) ZClear = UDO.Attribute(eAID_ZClear) 'ZRapidPlane = UDO.Attribute(eAID_ZRapid) Dim Xloc As Double, Yloc As Double, Zloc As Double Xloc = 0.0 ' toolpaths are relative to feature location Yloc = 0.0 Zloc = 0.0 ' Get the spindle speed speed = Int(UDO.Speed) ' Stop the spindle 'UDO.OverrideSpeed(0, True) UDO.AddPostedText("M05", "Stop the spindle") ' Orient the spindle UDO.AddPostedText("M19", "Orient the spindle") ' Move down to to the bottom of the hole ' Need to add clearence here UDO.AddRapidMove (Xloc+x_axis_shift, Yloc+y_axis_shift, ZRapidPlane) UDO.AddRapidMove (Xloc+x_axis_shift, Yloc+y_axis_shift, ZClear) UDO.AddRapidMove (Xloc+x_axis_shift, Yloc+y_axis_shift, -(Depth+clearance)) 'UDO.AddLinearMove (Xloc+x_axis_shift, Yloc+y_axis_shift, ZRapidPlane+Depth+clearance) ' Move back to the center 'UDO.AddRapidMove(Xloc, Yloc, 0) UDO.AddLinearMove(Xloc, Yloc, -(Depth+clearance)) ' Start spindle 'UDO.OverrideSpeed(speed, False) If spindle_direction = "0" Then UDO.AddPostedText("S" + Trim(Str(speed)) + "M03", "CW spindle") Else UDO.AddPostedText("S" + Trim(Str(speed)) + "M04", "CCW spindle") End If ' Need to add feedback value here 'UDO.AddLinearMove(Xloc, Yloc, -(Depth+clearance) + feedback) ' Dwell? 'UDO.SetAttribute(eAID_SpindleDwell, , bore_dwell, , False) If bore_dwell <> 0 Then UDO.AddPostedText("G04 X" + Trim(Str(bore_dwell)), "Dwell") End If ' Move to final depth UDO.AddLinearMove(Xloc, Yloc, -Depth + bore_depth) ' Feeding back If feed_direction = "0" Then ' Optional dwell? If dwell <> 0 Then UDO.AddPostedText("G04 X" + Trim(Str(dwell)), "Optional dwell") End If ' Feed down 0.005? UDO.AddLinearMove(Xloc, Yloc, -Depth + bore_depth - 0.005) 'Stop the spindle ' UDO.OverrideSpeed(0, False) UDO.AddPostedText("M05", "Stop the spindle") ' Orient the tool back to original position UDO.AddPostedText("M19", "Orient the spindle") UDO.AddLinearMove (Xloc+x_axis_shift, Yloc+y_axis_shift, -Depth + bore_depth - 0.005) Else UDO.AddLinearMove(Xloc, Yloc, -Depth + bore_depth - feed_down) 'Stop the spindle ' UDO.OverrideSpeed(0, False) UDO.AddPostedText("M05", "Stop the spindle") ' Orient the tool back to original position UDO.AddPostedText("M19", "Orient the spindle") UDO.AddLinearMove (Xloc+x_axis_shift, Yloc+y_axis_shift, -Depth + bore_depth - feed_down) End If UDO.AddRapidMove (Xloc+x_axis_shift, Yloc+y_axis_shift, ZClear) UDO.AddRapidMove (Xloc+x_axis_shift, Yloc+y_axis_shift, ZRapidPlane) valid = True End If End Sub