output ijk values using a point and a surface

Does anyone know of a way to output ijk values using a point and a surface in Solidworks?
I had a macro years ago, but it didn’t actually output the correct numbers. There were close, but not correct.

(Could also use a point and an axis if that helps.)

Thanks
Mark

You mean the normal vector of a surface at a point?

Yes .. Exactly!

To be extra clear … its the values of that vector in ijk format that I am trying to get.

What kind of point? Sketchpoint? Mouse pick point?

Yes sir. Sketch point and a face that the point is on … or an axis at that sketch point.
Either way would work.

I assume your sketchpoint is a 3D sketchpoint… If not, this will not give good results because it assumes the XYZ coordinates of the sketchpoint are in the same coordinate system as the face. 2D sketchpoints have to be transformed to get into model space.

Dim swApp As SldWorks.SldWorks
Dim swDoc As SldWorks.ModelDoc2
Dim swFace As SldWorks.Face2
Dim swSurf As SldWorks.Surface
Dim swSelMgr As SldWorks.SelectionMgr
Dim swSkPt As SldWorks.SketchPoint
Dim SelPt As Variant
Dim FacePt As Variant
Dim SurfEval As Variant
Dim i As Long
Dim sMsg As String
Dim dFlip As Double
Const NDEC As Long = 3
Const ZEROTOL As Double = 0.0000001
Sub main()

Set swApp = Application.SldWorks
Set swDoc = swApp.ActiveDoc
Set swSelMgr = swDoc.SelectionManager
Set swSkPt = Nothing
Set swFace = Nothing
sMsg = ""

'get the first face and the first point
For i = 1 To swSelMgr.GetSelectedObjectCount2(-1)
    If swSelMgr.GetSelectedObjectType3(i, -1) = swSelFACES Then
        Set swFace = swSelMgr.GetSelectedObject6(i, -1)
    End If
    If swSelMgr.GetSelectedObjectType3(i, -1) = swSelSKETCHPOINTS Then
        Set swSkPt = swSelMgr.GetSelectedObject6(i, -1)
    End If
    If swSelMgr.GetSelectedObjectType3(i, -1) = swSelEXTSKETCHPOINTS Then
        Set swSkPt = swSelMgr.GetSelectedObject6(i, -1)
    End If
Next i

If swSkPt Is Nothing Or swFace Is Nothing Then
    MsgBox "Please select a face and a sketchpoint before running the macro."
    Exit Sub
End If

If False = swSkPt.GetSketch.Is3D Then
    sMsg = "Warning: Selected point was not in a 3D sketch.  Results may be wrong." & vbCrLf & vbCrLf
End If

'This tells if the surface normal points in the same direction as face normal.
'Actual function is not intuitive.  False means face and surface are same.
Set swSurf = swFace.GetSurface
If False = swFace.FaceInSurfaceSense Then
    dFlip = 1
Else
    dFlip = -1
End If

'Check if the point actually is on the face

FacePt = swFace.GetClosestPointOn(swSkPt.X, swSkPt.Y, swSkPt.Z)
If Not ((Abs(swSkPt.X - FacePt(0)) < ZEROTOL) And (Abs(swSkPt.Y - FacePt(1)) < ZEROTOL) And (Abs(swSkPt.Z - FacePt(2)) < ZEROTOL)) Then
    sMsg = sMsg & "Warning: sketchpoint does not appear to be actually on the face.  Result is measured at closest point on face." & vbCrLf & vbCrLf
Else
    sMsg = sMsg & "Point appears to be on the face." & vbCrLf & vbCrLf
End If

'Evaluate at the point on the face
SurfEval = swSurf.EvaluateAtPoint(FacePt(0), FacePt(1), FacePt(2))


Debug.Print "Sketchpoint XYZ: ", swSkPt.X, swSkPt.Y, swSkPt.Z
Debug.Print "Closest pt XYZ:, FacePt(0), FacePt(1), FacePt(2)"
Debug.Print "Vector:", "[" & dFlip * SurfEval(0) & " " & dFlip * SurfEval(1) & " " & dFlip * SurfEval(2) & "]"

MsgBox sMsg & "i: " & Round(dFlip * SurfEval(0), NDEC) & vbCrLf & "j: " & Round(dFlip * SurfEval(1), NDEC) & vbCrLf & "k: " & Round(dFlip * SurfEval(2), NDEC)

Set swSurf = Nothing
Set swFace = Nothing
Set swSelMgr = Nothing
Set swDoc = Nothing
Set swApp = Nothing
End Sub

This is exactly what I was looking for ! Your assumption is correct that it it a 3D sketch point in the same model space.

Really appreciate you providing this solution. Thank you.