MACRO LIBRARY

Lesson 7.5 code - Part I (spike creator)

Free public access. No account or subscription required.

Files

Lesson 7.5 code - Part I (spike creator)

Code

Module: mMain

'Creates a spike using a macro feature. The feature can be edited. The body can merge with _
    one other body that it is intersecting.
    
'Preconditions: a sketch with a single sketch point should be present.
    
'Limitations: _
    -If your sketch has multiple sketch points then only one of them will be used _
    when creating a spike. _
    -The merge will only occur with one of the bodies intersected by the spike. _
    -If a new sketch is chosen during edit definition, the originally chosen sketch will _
    still remain the macro feature's sub-feature.
    
'Written by Keith Rice
'CADSharp LLC
'www.cadsharp.com
    
Public pm As clsPMP    'Needs to be outside of module
Public swApp As SldWorks.SldWorks
Public swModel As SldWorks.ModelDoc2
Public swPart As SldWorks.PartDoc
Public swBody As SldWorks.Body2
Public swFeat As SldWorks.Feature
Public swMacroFeatData As SldWorks.MacroFeatureData
Public swSketchFeat As SldWorks.Feature
Public vSelObjects(0) As SldWorks.Feature
Public vEditBodies As Variant
Public swEditBody As SldWorks.Body2
Public swEditBodies(0) As SldWorks.Body2
    
Public swSketchMgr As SldWorks.SketchManager
Public swSketch As SldWorks.Sketch
Public swSketchPt As SldWorks.SketchPoint
Public vSketchPts As Variant
    
Public Const GROUP_SKETCH_ID = 0
Public Const GROUP_CYL_ID = 1
Public Const GROUP_CONE_ID = 2
Public Const REVERSE_ID = 3
Public Const SKETCH_ID = 4
Public Const CYL_RAD_ID = 5
Public Const CYL_DEPTH_ID = 6
Public Const CONE_RAD_ID = 7
Public Const CONE_DEPTH_ID = 8
    
Public dblCylRad As Double
Public dblCylDepth As Double
Public dblConeRad As Double
Public dblConeDepth As Double
Public dblCylLoc(2) As Double
Public dblConeLoc(2) As Double
Public dblVect(2) As Double
Public dblRelVect(2) As Double
Public dblCylData(7) As Double
Public dblConeData(8) As Double
    
Public Const INSERT As Integer = 1
Public Const EDIT As Integer = 2
Public STATE As Integer
Public blnMerged As Boolean
    
Sub main()
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    'Make sure a part is open
    If swModel Is Nothing Then
        MsgBox "Please open a part."
        End
    End If
    If swModel.GetType <> swDocPART Then
        MsgBox "Please open a part."
        End
    End If
    
    'Create the PMP
    Set pm = New clsPMP
    STATE = INSERT
    pm.Layout
End Sub

Module: mMacroFeature

Sub InsertMacroFeature()
    'MACRO METHODS
    Dim vMacroMethods As Variant
    Dim MacroMethods(8) As String
    'Regen function
    MacroMethods(0) = swApp.GetCurrentMacroPathName 'path to macro defining macro feature
    MacroMethods(1) = "mMacroFeature" 'name of the module where function resides
    MacroMethods(2) = "swmRebuild" 'function name
    'Edit definition function
    MacroMethods(3) = swApp.GetCurrentMacroPathName
    MacroMethods(4) = "mMacroFeature"
    MacroMethods(5) = "swmEditDefinition"
    'Security function (optional)
    MacroMethods(6) = swApp.GetCurrentMacroPathName
    MacroMethods(7) = "mMacroFeature"
    MacroMethods(8) = "swmSecurity"
    vMacroMethods = MacroMethods
    
    Set swEditBodies(0) = swEditBody
    
    'if a merge occurred the swEditBodies(0) won't be Nothing and we can replace that body _
        with the new body while keeping the other bodies; otherwise keep all bodies. Note _
        that this can only ever allow for a single body to be modified by this macro feature
    If Not swEditBodies(0) Is Nothing Then
        vEditBodies = swEditBodies
        Set swFeat = swModel.FeatureManager.InsertMacroFeature3("Spike", Empty, vMacroMethods, _
            Nothing, Nothing, Nothing, Nothing, Nothing, vEditBodies, Nothing, 0)
    Else
        Set swFeat = swModel.FeatureManager.InsertMacroFeature3("Spike", Empty, vMacroMethods, _
            Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, 0)
    End If
    
    'Turn sketch into sub-feature
    swFeat.MakeSubFeature swSketchFeat
End Sub
    
Function swmRebuild(app As Variant, model As Variant, feat As Variant) As Variant
    Dim i As Integer
    Set swApp = app
    Set swMacroFeatData = feat.GetDefinition
    
    If STATE = 0 Then
        For i = 0 To 7
            swMacroFeatData.GetDoubleByName "cyldata" & i, dblCylData(i)
        Next i
        For i = 0 To 8
            swMacroFeatData.GetDoubleByName "conedata" & i, dblConeData(i)
        Next i
        Call CreateSpike
        vEditBodies = swMacroFeatData.EditBodies
        On Error Resume Next    'otherwise the next line results in a type mismatch for _
            macro features not merged with an existing body
        Set swEditBody = vEditBodies(0)
        If Not swEditBody Is Nothing Then Call MergeBodies
    End If
    
    If STATE <> 0 Then
        'Assign edge and face IDs
        Dim vEdges As Variant
        Dim vFaces As Variant
        vEdges = swBody.GetEdges
        vFaces = swBody.GetFaces
        For i = 0 To UBound(vEdges)
            swMacroFeatData.SetEdgeUserId vEdges(i), i, 0
        Next i
        For i = 0 To UBound(vFaces)
            swMacroFeatData.SetFaceUserId vFaces(i), i, 0
        Next i
    End If
    
    'store control values in macro feature
    swMacroFeatData.SetDoubleByName "cyldepth", dblCylDepth
    swMacroFeatData.SetDoubleByName "cylrad", dblCylRad
    swMacroFeatData.SetDoubleByName "conedepth", dblConeDepth
    swMacroFeatData.SetDoubleByName "conerad", dblConeRad
    
    'all temp body data (for use with non-insert, non-edit rebuild)
    For i = 0 To 7
        swMacroFeatData.SetDoubleByName "cyldata" & i, dblCylData(i)
    Next i
    For i = 0 To 8
        swMacroFeatData.SetDoubleByName "conedata" & i, dblConeData(i)
    Next i
    
    'Set selections
    Set vSelObjects(0) = swSketchFeat
    swMacroFeatData.SetSelections2 vSelObjects, Nothing, Nothing
    
    'Return value
    Set swmRebuild = swBody
    
    'Reset STATE
    STATE = 0
End Function
    
Function swmEditDefinition(app As Variant, model As Variant, feat As Variant) As Variant
    STATE = EDIT
    Set swApp = app
    Set swFeat = feat
    Set swModel = model
    Set swMacroFeatData = swFeat.GetDefinition
    swMacroFeatData.AccessSelections swModel, Nothing
    
    'obtain control values stored in macro feature
    swMacroFeatData.GetDoubleByName "cyldepth", dblCylDepth
    swMacroFeatData.GetDoubleByName "cylrad", dblCylRad
    swMacroFeatData.GetDoubleByName "conedepth", dblConeDepth
    swMacroFeatData.GetDoubleByName "conerad", dblConeRad
    
    'Get selections
    swMacroFeatData.GetSelections3 vSelObjects, Nothing, Nothing, Nothing, Nothing
    vSelObjects(0).Select2 False, 0
    
    'Open PropertyManager page
    pm.Layout
End Function
    
Function swmSecurity(app As Variant, model As Variant, feat As Variant) As Variant
    swmSecurity = SwConst.swMacroFeatureSecurityOptions_e.swMacroFeatureSecurityByDefault
End Function

Module: mSpikeCreator

'Note the If STATE <> 0 conditional used with the temp body data array. If this conditional _
    is not here then if the user edits the definition, changes a radius or depth value, _
    cancels, and then updates, the rebuild will apply the new radius or depth value because _
    dblCylRad, dblCylDepth, dblConeRad, and dblConeDepth are being remembered from when _
    the user edited the definition. Consequently when CreateSpike is called in the rebuild _
    function, those new values are used in creating the temporary body.
    
Sub CreateSpike()
    Dim swModeler As SldWorks.Modeler
    Set swModeler = swApp.GetModeler
    
    'Create cylinder and check body
    If STATE <> 0 Then
        Dim swCylBody As SldWorks.Body2
        dblCylData(0) = dblCylLoc(0)   'center of face (x coord)
        dblCylData(1) = dblCylLoc(1)   'center of face (y coord)
        dblCylData(2) = dblCylLoc(2)   'center of face (z coord)
        dblCylData(3) = dblRelVect(0)  'axis vector (x component)
        dblCylData(4) = dblRelVect(1)  'axis vector (y component)
        dblCylData(5) = dblRelVect(2)  'axis vector (z component)
        dblCylData(6) = dblCylRad   'radius
        dblCylData(7) = dblCylDepth 'extrude length
    End If
    
    Set swCylBody = swModeler.CreateBodyFromCyl(dblCylData)
    If STATE <> 0 Then swCylBody.Display3 swModel, 255, 0
    
    'Create cone and check body
    If STATE <> 0 Then
        Call GetFaceCenter
        Dim swConeBody As SldWorks.Body2
        dblConeData(0) = dblConeLoc(0)      'center of face (x coord)
        dblConeData(1) = dblConeLoc(1)      'center of face (y coord)
        dblConeData(2) = dblConeLoc(2)      'center of face (z coord)
        dblConeData(3) = dblRelVect(0)     'axis vector (x component)
        dblConeData(4) = dblRelVect(1)     'axis vector (y component)
        dblConeData(5) = dblRelVect(2)     'axis vector (z component)
        dblConeData(6) = dblConeRad     'base radius
        dblConeData(7) = 0              'top radius
        dblConeData(8) = dblConeDepth   'extrude length
    End If
    
    Set swConeBody = swModeler.CreateBodyFromCone(dblConeData)
    If STATE <> 0 Then swConeBody.Display3 swModel, 255, 0
    
    'Add bodies
    Dim vBodies As Variant
    Dim lngErrors As Long
    vBodies = swConeBody.Operations2(SWBODYADD, swCylBody, lngErrors)
    If lngErrors <> 0 Then
        swApp.SendMsgToUser "Boolean operation error: " & lngErrors
        Exit Sub
    End If
    Set swBody = vBodies(0)
    Set vBodies(0) = Nothing
End Sub
    
'Merge bodies notes:
'IBody2::Operations2 makes the pointers for the target and tool body invalid, which is why _
    you will get an automation error if you do not first make a copy of swBody.
'When you get the existing bodies in the part from GetBodies2, they will not be temporary _
    bodies but they must be to use Operations2 on them. Use IBody2::Copy to make a copy of the _
    body as a temporary body.
'This only allows one merged body. The original body will be stored in swEditBody.
'IBody2::Operations2 doesn't consider two coincident planar faces as intersecting. Instead _
    test using IBody2::GetIntersectionEdges.
    
Sub MergeBodies()
    Dim swMergeBody As SldWorks.Body2
    Dim swTempBody As SldWorks.Body2
    Dim vResults As Variant
    Dim lngErrors As Long
    Dim j As Integer
    Set swPart = swModel
    Set swTempBody = swBody.Copy
    
    If STATE <> 0 Then vEditBodies = swPart.GetBodies2(swSolidBody, False)
    
    If IsEmpty(vEditBodies) = False Then
        For j = 0 To UBound(vEditBodies)
            Set swMergeBody = vEditBodies(j)
            Set swMergeBody = swMergeBody.Copy
            
            vResults = swMergeBody.GetIntersectionEdges(swTempBody)
            If UBound(vResults) <> -1 Then
                vResults = swMergeBody.Operations2(SWBODYADD, swTempBody, lngErrors)
                If lngErrors = 0 Then
                    Set swBody = vResults(0)
                    Set swEditBody = vEditBodies(j)  'see notes by InsertMacroFeature3
                End If
            End If
        Next j
    End If
End Sub

Module: mTransform

Dim swMathUtil As SldWorks.MathUtility
Dim swTransform As SldWorks.MathTransform
Dim swMathPt As SldWorks.MathPoint
Dim swMathVect As SldWorks.MathVector
Dim vPts As Variant
    
Sub SketchTransform(swSketch As SldWorks.Sketch)
    Set swMathUtil = swApp.GetMathUtility
    
    'Create the new math pt from sketch data
    Set swMathPt = swMathUtil.CreatePoint(dblCylLoc)
    
    'Get the model-to-sketch transform of the sketch
    Set swTransform = swSketch.ModelToSketchTransform
    
    'Get the sketch-to-model transform
    Set swTransform = swTransform.Inverse
    
    'Get math pt relative to model space
    Set swMathPt = swMathPt.MultiplyTransform(swTransform)
    
    'Extract pt data
    vPts = swMathPt.ArrayData
    dblCylLoc(0) = vPts(0)
    dblCylLoc(1) = vPts(1)
    dblCylLoc(2) = vPts(2)
End Sub
    
Sub NormalTransform(swSketch As SldWorks.Sketch)
    'By default, the sketch is normal to the Z axis. Create Z-axis vector to transform _
        to model space
    dblVect(0) = 0
    dblVect(1) = 0
    Set swMathVect = swMathUtil.CreateVector(dblVect)
    Set swMathVect = swMathVect.MultiplyTransform(swTransform)
    vPts = swMathVect.ArrayData
    dblRelVect(0) = vPts(0)
    dblRelVect(1) = vPts(1)
    dblRelVect(2) = vPts(2)
End Sub
    
Sub GetFaceCenter()
    Set swMathVect = swMathVect.Normalise
    vPts = swMathVect.ArrayData
    dblConeLoc(0) = dblCylLoc(0) + vPts(0) * dblCylDepth
    dblConeLoc(1) = dblCylLoc(1) + vPts(1) * dblCylDepth
    dblConeLoc(2) = dblCylLoc(2) + vPts(2) * dblCylDepth
End Sub

Class: clsPMP

Dim pmHandler As clsPMPHandler
Dim pmPage As SldWorks.PropertyManagerPage2
Dim pmGroupSketch As SldWorks.PropertyManagerPageGroup
Dim pmGroupCyl As SldWorks.PropertyManagerPageGroup
Dim pmGroupCone As SldWorks.PropertyManagerPageGroup
Dim pmCheckboxReverse As SldWorks.PropertyManagerPageCheckbox
Dim pmSelBoxSketch As SldWorks.PropertyManagerPageSelectionbox
Dim pmNumBoxCylRad As SldWorks.PropertyManagerPageNumberbox
Dim pmNumBoxCylDepth As SldWorks.PropertyManagerPageNumberbox
Dim pmNumBoxConeRad As SldWorks.PropertyManagerPageNumberbox
Dim pmNumBoxConeDepth As SldWorks.PropertyManagerPageNumberbox
Dim lngErrors As Long
    
Sub Layout()
    Set pmHandler = New clsPMPHandler
    Set pmPage = swApp.CreatePropertyManagerPage("Create spike", _
        swPropertyManagerOptions_OkayButton + swPropertyManagerOptions_CancelButton + _
        swPropertyManagerOptions_LockedPage, pmHandler, lngErrors)
        
    If lngErrors = 0 Then
        'Initial PMP control values
        If STATE = INSERT Then
            dblCylRad = 0.005
            dblCylDepth = 0.01
            dblConeRad = 0.005
            dblConeDepth = 0.01
        End If
        
        'Set message
        pmPage.SetMessage3 "Select a 2D sketch containing a sketch point. Spike is created normal to the sketch plane.", swImportantMessageBox, _
            swMessageBoxMaintainExpandState, Empty
    
        'Group box - sketch selection
        Set pmGroupSketch = pmPage.AddGroupBox(GROUP_SKETCH_ID, "Sketch", _
            swGroupBoxOptions_Expanded + swGroupBoxOptions_Visible)
        
        'Selection box - selection box
        Set pmSelBoxSketch = pmGroupSketch.AddControl(SKETCH_ID, _
            swControlType_Selectionbox, Empty, swControlAlign_Indent, _
            swControlOptions_Visible + swControlOptions_Enabled, "Select sketch")
        pmSelBoxSketch.SetSelectionFilters swSelSKETCHES
        pmSelBoxSketch.SetStandardPictureLabel swBitmapLabel_SelectProfile
        pmSelBoxSketch.SingleEntityOnly = True
        pmSelBoxSketch.Height = 13
    
        'Checkbox - reverse direction
        Set pmCheckboxReverse = pmGroupSketch.AddControl(REVERSE_ID, _
            swControlType_Checkbox, "Reverse direction", swControlAlign_Indent, _
            swControlOptions_Visible + swControlOptions_Enabled, "Reverse direction")
    
        'Group box - cylinder
        Set pmGroupCyl = pmPage.AddGroupBox(GROUP_CYL_ID, "Cylinder", _
            swGroupBoxOptions_Expanded + swGroupBoxOptions_Visible)
        
        'Number box - cylinder radius
        Set pmNumBoxCylRad = pmGroupCyl.AddControl(CYL_RAD_ID, _
            swControlType_Numberbox, Empty, swControlAlign_Indent, _
            swControlOptions_Visible + swControlOptions_Enabled, "Radius")
        pmNumBoxCylRad.Value = dblCylRad
        pmNumBoxCylRad.SetRange2 swNumberBox_Length, 0, 1, True, 0.005, 0.005, 0.005
        pmNumBoxCylRad.SetStandardPictureLabel swBitmapLabel_Radius
    
        'Number box - cylinder depth
        Set pmNumBoxCylDepth = pmGroupCyl.AddControl(CYL_DEPTH_ID, _
            swControlType_Numberbox, Empty, swControlAlign_Indent, _
            swControlOptions_Visible + swControlOptions_Enabled, "Depth")
        pmNumBoxCylDepth.Value = dblCylDepth
        pmNumBoxCylDepth.SetRange2 swNumberBox_Length, 0, 1, True, 0.005, 0.005, 0.005
        pmNumBoxCylDepth.SetStandardPictureLabel swBitmapLabel_LinearDistance
        
        'Group box - cone
        Set pmGroupCone = pmPage.AddGroupBox(GROUP_CONE_ID, "Cone", _
            swGroupBoxOptions_Expanded + swGroupBoxOptions_Visible)
        
        'Number box - cone radius
        Set pmNumBoxConeRad = pmGroupCone.AddControl(CONE_RAD_ID, _
            swControlType_Numberbox, Empty, swControlAlign_Indent, _
            swControlOptions_Visible + swControlOptions_Enabled, "Radius")
        pmNumBoxConeRad.Value = dblConeRad
        pmNumBoxConeRad.SetRange2 swNumberBox_Length, 0, 1, True, 0.005, 0.005, 0.005
        pmNumBoxConeRad.SetStandardPictureLabel swBitmapLabel_Radius
    
        'Number box - cone depth
        Set pmNumBoxConeDepth = pmGroupCone.AddControl(CONE_DEPTH_ID, _
            swControlType_Numberbox, Empty, swControlAlign_Indent, _
            swControlOptions_Visible + swControlOptions_Enabled, "Depth")
        pmNumBoxConeDepth.Value = dblConeDepth
        pmNumBoxConeDepth.SetRange2 swNumberBox_Length, 0, 1, True, 0.005, 0.005, 0.005
        pmNumBoxConeDepth.SetStandardPictureLabel swBitmapLabel_LinearDistance
        
        'Display the PMP
        pmPage.Show2 0
    Else
        Debug.Print "Error creating PropertyManager page."
        Debug.Print "Error code: " & lngErrors
    End If
End Sub

Class: clsPMPHandler

Implements PropertyManagerPage2Handler8
    
Private Sub PropertyManagerPage2Handler8_AfterActivation()
    'otherwise when you edit a macro feature that you reversed the direction of, _
        it can be flipped in the wrong direction
    If STATE = INSERT Then dblVect(2) = 1
End Sub
    
Private Sub PropertyManagerPage2Handler8_AfterClose()
    
End Sub
    
Private Function PropertyManagerPage2Handler8_OnActiveXControlCreated(ByVal Id As Long, ByVal Status As Boolean) As Long
    
End Function
    
Private Sub PropertyManagerPage2Handler8_OnButtonPress(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnCheckboxCheck(ByVal Id As Long, ByVal Checked As Boolean)
    dblVect(2) = dblVect(2) * -1
    Call NormalTransform(swSketch)
    Call CreateSpike
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnClose(ByVal Reason As Long)
    If Reason = swPropertyManagerPageClose_Okay Then
        Call MergeBodies
        If STATE = INSERT Then
            Call InsertMacroFeature
        ElseIf STATE = EDIT Then
            swFeat.ModifyDefinition swMacroFeatData, swModel, Nothing
        End If
    Else
        Set swBody = Nothing    'this must come before ReleaseSelectionAccess or temp body _
            will stay visible since ReleaseSelAccess doesn't call Rebuild function
        swMacroFeatData.ReleaseSelectionAccess
        STATE = 0   'reset
    End If
    swModel.ClearSelection2 True
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnComboboxEditChanged(ByVal Id As Long, ByVal Text As String)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnComboboxSelectionChanged(ByVal Id As Long, ByVal Item As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnGainedFocus(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnGroupCheck(ByVal Id As Long, ByVal Checked As Boolean)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnGroupExpand(ByVal Id As Long, ByVal Expanded As Boolean)
    
End Sub
    
Private Function PropertyManagerPage2Handler8_OnHelp() As Boolean
    
End Function
    
Private Function PropertyManagerPage2Handler8_OnKeystroke(ByVal Wparam As Long, ByVal Message As Long, ByVal Lparam As Long, ByVal Id As Long) As Boolean
    
End Function
    
Private Sub PropertyManagerPage2Handler8_OnListboxRMBUp(ByVal Id As Long, ByVal PosX As Long, ByVal PosY As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnListboxSelectionChanged(ByVal Id As Long, ByVal Item As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnLostFocus(ByVal Id As Long)
    
End Sub
    
Private Function PropertyManagerPage2Handler8_OnNextPage() As Boolean
    
End Function
    
Private Sub PropertyManagerPage2Handler8_OnNumberboxChanged(ByVal Id As Long, ByVal Value As Double)
    If Id = CYL_RAD_ID Then dblCylRad = Value
    If Id = CYL_DEPTH_ID Then dblCylDepth = Value
    If Id = CONE_RAD_ID Then dblConeRad = Value
    If Id = CONE_DEPTH_ID Then dblConeDepth = Value
    Call CreateSpike
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnOptionCheck(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnPopupMenuItem(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnPopupMenuItemUpdate(ByVal Id As Long, retval As Long)
    
End Sub
    
Private Function PropertyManagerPage2Handler8_OnPreview() As Boolean
    
End Function
    
Private Function PropertyManagerPage2Handler8_OnPreviousPage() As Boolean
    
End Function
    
Private Sub PropertyManagerPage2Handler8_OnRedo()
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnSelectionboxCalloutCreated(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnSelectionboxCalloutDestroyed(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnSelectionboxFocusChanged(ByVal Id As Long)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnSelectionboxListChanged(ByVal Id As Long, ByVal Count As Long)
    If Count = 0 Then Set swBody = Nothing
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnSliderPositionChanged(ByVal Id As Long, ByVal Value As Double)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnSliderTrackingCompleted(ByVal Id As Long, ByVal Value As Double)
    
End Sub
    
Private Function PropertyManagerPage2Handler8_OnSubmitSelection(ByVal Id As Long, ByVal Selection As Object, ByVal SelType As Long, ItemText As String) As Boolean
    PropertyManagerPage2Handler8_OnSubmitSelection = True
    
    'Get sketch pt coordinates
    Set swSketchFeat = Selection  'even though SelItem says sketch, its actually a feature; _
        see also return value of IMacroFeatureData::GetSelections3
    Set swSketch = swSketchFeat.GetSpecificFeature2
    vSketchPts = swSketch.GetSketchPoints2
    Set swSketchPt = vSketchPts(0)
    dblCylLoc(0) = swSketchPt.X
    dblCylLoc(1) = swSketchPt.Y
    dblCylLoc(2) = swSketchPt.Z
    Call SketchTransform(swSketch)
    
    'Get axis vector
    Call NormalTransform(swSketch)
    
    'Create temporary body for preview
    Call CreateSpike
    swModel.ShowNamedView2 "*Isometric", 7
    swModel.ViewZoomtofit2
End Function
    
Private Function PropertyManagerPage2Handler8_OnTabClicked(ByVal Id As Long) As Boolean
    
End Function
    
Private Sub PropertyManagerPage2Handler8_OnTextboxChanged(ByVal Id As Long, ByVal Text As String)
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnUndo()
    
End Sub
    
Private Sub PropertyManagerPage2Handler8_OnWhatsNew()
    
End Sub
    
Private Function PropertyManagerPage2Handler8_OnWindowFromHandleControlCreated(ByVal Id As Long, ByVal Status As Boolean) As Long
    
End Function