Hide Table of Contents

Determine Type of Face Example (VBA)

This example shows how to identify holes, bosses, and tangent faces on a selected face.

NOTE: To determine the type of face, start from a selected face and use IFace2::GetFirstLoop to get the first loop in the face. For every loop on the face (use ILoop2::GetNext), if the loop is not the outer loop (ILoop2::IsOuter equals false), then get the coedge for this loop and the partner coedge for the coedge.  

For each coedge, get the face normal at the middle of the coedge. This is found by obtaining the middle of the coedge with a call to ICoEdge::GetCurveParams, and a call to ICoEdge::Evaluate on the midpoint of the coedge to get the point’s coordinates.  

The normal is returned by a call to ISurface::EvaluateAtPoint at the point in the middle of the coedge. If the normals for the two faces are equal, then there is a tangent face (fillet) on the selected face.  If the normals are not equal, then if the cross product of the two normals is equal to the tangent of the face, there is a hole at the coedge. Otherwise, if there is a loop that is not the outer loop that does not meet any of the other conditions, it is a boss.  

'----------------------------------------------
' Preconditions:
' 1. Open public_documents\samples\tutorial\api\block.sldprt.
' 2. Select either face that contains a hole.
'
' Postconditions:
' 1. Identifies the hole in the selected face
'    and displays a message box.
' 2. Click OK to close the message box.
'
' NOTE: If you run this macro and select a face
' that does not have a hole, boss, or tangent face,
' then a message box is not displayed.
'------------------------------------------------
Option Explicit
Sub main()
    Dim swApp As SldWorks.SldWorks
    Dim swDoc As SldWorks.ModelDoc2
    Dim swSelMgr As SldWorks.SelectionMgr
    Dim swFace As SldWorks.Face2
    Dim swSelData As SldWorks.SelectData
    Set swApp = GetObject(, "SldWorks.Application")
    Set swDoc = swApp.ActiveDoc
    'Verify that a face is selected
    Set swSelMgr = swDoc.SelectionManager
    If swSelMgr.GetSelectedObjectCount <> 1 Then Exit Sub
    If swSelMgr.GetSelectedObjectType2(1) <> swSelFACES Then Exit Sub
    'Get the selected face
    Set swFace = swSelMgr.GetSelectedObject6(1, -1)
    Set swSelData = swSelMgr.CreateSelectData
    'Find the holes and bosses in the selected face
    Call FindHolesAndBosses(swFace, swSelData)
End Sub
'This subroutine locates all holes, bosses,
'and tangent faces in the selected face
Sub FindHolesAndBosses(swFace, swSelData)
    Dim swThisLoop As SldWorks.Loop2
    Dim swThisCoEdge As SldWorks.CoEdge
    Dim swPartnerFace As SldWorks.Face2
    Dim swPartnerLoop As SldWorks.Loop2
    Dim swPartnerCoEdge As SldWorks.CoEdge
    Dim swEntity As SldWorks.Entity
    Dim varThisNormal As Variant
    Dim varPartnerNormal As Variant
    Dim varCrossProduct As Variant
    Dim varTangent As Variant
    Set swThisLoop = swFace.GetFirstLoop
    'For every loop on the face
    Do While Not swThisLoop Is Nothing
        If swThisLoop.IsOuter = False Then
            Set swThisCoEdge = swThisLoop.GetFirstCoEdge
            Set swPartnerCoEdge = swThisCoEdge.GetPartner
            varThisNormal = GetFaceNormalAtMidCoEdge(swThisCoEdge)
            varPartnerNormal = GetFaceNormalAtMidCoEdge(swPartnerCoEdge)
            If VectorsAreEqual(varThisNormal, varPartnerNormal) Then
               ' The neighboring face is tangent to the
               ' selected face; additional code is necessary for
               ' determining how the surface moves away from the
               ' selected face
                Set swPartnerLoop = swPartnerCoEdge.GetLoop
                Set swPartnerFace = swPartnerLoop.GetFace
                Set swEntity = swPartnerFace
                swEntity.Select4 False, swSelData
                MsgBox "This face is tangent."
            Else
               ' There is a sufficient change between
               ' the two faces to determine the kind of transition
               ' being made
                varCrossProduct = GetCrossProduct(varThisNormal, varPartnerNormal)
                varTangent = GetTangentAtMidCoEdge(swThisCoEdge)
                If VectorsAreEqual(varCrossProduct, varTangent) Then
                    'Hole
                    Set swPartnerLoop = swPartnerCoEdge.GetLoop
                    Set swPartnerFace = swPartnerLoop.GetFace
                    Set swEntity = swPartnerFace
                    swEntity.Select4 False, swSelData
                    MsgBox "This face is a hole."
                Else
                    'Boss
                    Set swPartnerLoop = swPartnerCoEdge.GetLoop
                    Set swPartnerFace = swPartnerLoop.GetFace
                    Set swEntity = swPartnerFace
                    swEntity.Select4 False, swSelData
                    MsgBox "This face is a boss."
                End If
            End If
        End If
        Set swThisLoop = swThisLoop.GetNext
    Loop
End Sub
'This function returns the face normal from the provided coedge
Function GetFaceNormalAtMidCoEdge(swCoEdge As CoEdge) As Variant
    Dim swFace As SldWorks.Face2
    Dim swSurface As SldWorks.Surface
    Dim swLoop As SldWorks.Loop2
    Dim varParams As Variant
    Dim varPoint As Variant
    Dim dblMidParam As Double
    Dim dblNormal(2) As Double
    Dim bFaceSenseReversed As Boolean
    varParams = swCoEdge.GetCurveParams
    If varParams(6) > varParams(7) Then
        dblMidParam = (varParams(6) - varParams(7)) / 2 + varParams(7)
    Else
        dblMidParam = (varParams(7) - varParams(6)) / 2 + varParams(6)
    End If
    varPoint = swCoEdge.Evaluate(dblMidParam)
    ' Get the face of the given coedge; remember to check
    ' for the sense of the face
    Set swLoop = swCoEdge.GetLoop
    Set swFace = swLoop.GetFace
    Set swSurface = swFace.GetSurface
    bFaceSenseReversed = swFace.FaceInSurfaceSense
    varParams = swSurface.EvaluateAtPoint(varPoint(0), varPoint(1), varPoint(2))
    If bFaceSenseReversed Then
        ' Negate the surface normal as it is opposite from the face normal
        dblNormal(0) = -varParams(0)
        dblNormal(1) = -varParams(1)
        dblNormal(2) = -varParams(2)
    Else
        dblNormal(0) = varParams(0)
        dblNormal(1) = varParams(1)
        dblNormal(2) = varParams(2)
    End If
    GetFaceNormalAtMidCoEdge = dblNormal
End Function
'Get the tangent vector for the provided coedge
Function GetTangentAtMidCoEdge(swCoEdge As Variant) As Variant
    Dim varParams As Variant
    Dim dblMidParam As Double
    Dim dblTangent(2) As Double
    varParams = swCoEdge.GetCurveParams
    If varParams(6) > varParams(7) Then
        dblMidParam = (varParams(6) - varParams(7)) / 2 + varParams(7)
    Else
        dblMidParam = (varParams(7) - varParams(6)) / 2 + varParams(6)
    End If
    varParams = swCoEdge.Evaluate(dblMidParam)
    dblTangent(0) = varParams(3)
    dblTangent(1) = varParams(4)
    dblTangent(2) = varParams(5)
    GetTangentAtMidCoEdge = dblTangent
End Function
 
'Obtain the cross product of two vectors
Function GetCrossProduct(varVec1 As Variant, varVec2 As Variant) As Variant
    Dim dblCross(2) As Double
    dblCross(0) = varVec1(1) * varVec2(2) - varVec1(2) * varVec2(1)
    dblCross(1) = varVec1(2) * varVec2(0) - varVec1(0) * varVec2(2)
    dblCross(2) = varVec1(0) * varVec2(1) - varVec1(1) * varVec2(0)
    GetCrossProduct = dblCross
End Function
'Checks whether two vectors are equal within a tolerance of 1.0 e^-10
Function VectorsAreEqual(varVec1 As Variant, varVec2 As Variant) As Boolean
    Dim dblMag As Double
    Dim dblDot As Double
    Dim dblUnit1(2) As Double
    Dim dblUnit2(2) As Double
    dblMag = (varVec1(0) * varVec1(0) + varVec1(1) * varVec1(1) + varVec1(2) * varVec1(2)) ^ 0.5
    dblUnit1(0) = varVec1(0) / dblMag: dblUnit1(1) = varVec1(1) / dblMag: dblUnit1(2) = varVec1(2) / dblMag
    dblMag = (varVec2(0) * varVec2(0) + varVec2(1) * varVec2(1) + varVec2(2) * varVec2(2)) ^ 0.5
    dblUnit2(0) = varVec2(0) / dblMag: dblUnit2(1) = varVec2(1) / dblMag: dblUnit2(2) = varVec2(2) / dblMag
    dblDot = dblUnit1(0) * dblUnit2(0) + dblUnit1(1) * dblUnit2(1) + dblUnit1(2) * dblUnit2(2)
    dblDot = Abs(dblDot - 1#)
    If dblDot < 0.0000000001 Then '1.0e-10
        VectorsAreEqual = True
    Else
        VectorsAreEqual = False
    End If
End Function


Provide feedback on this topic

SOLIDWORKS welcomes your feedback concerning the presentation, accuracy, and thoroughness of the documentation. Use the form below to send your comments and suggestions about this topic directly to our documentation team. The documentation team cannot answer technical support questions. Click here for information about technical support.

* Required

 
*Email:  
Subject:   Feedback on Help Topics
Page:   Determine Type of Face Example (VBA)
*Comment:  
*   I acknowledge I have read and I hereby accept the privacy policy under which my Personal Data will be used by Dassault Systèmes

Print Topic

Select the scope of content to print:

x

We have detected you are using a browser version older than Internet Explorer 7. For optimized display, we suggest upgrading your browser to Internet Explorer 7 or newer.

 Never show this message again
x

Web Help Content Version: API Help (English only) 2021 SP05

To disable Web help from within SOLIDWORKS and use local help instead, click Help > Use SOLIDWORKS Web Help.

To report problems encountered with the Web help interface and search, contact your local support representative. To provide feedback on individual help topics, use the “Feedback on this topic” link on the individual topic page.