Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations IDS on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help needed for "select edges normal to surface"-macro

Status
Not open for further replies.

Morfmor

Mechanical
Feb 26, 2008
8
I'm trying to build a macro that can select edges normal to a preselected face. For instance if you have a rectangular plate, and want's to chamfer the corners, I would be able to selecet all 'corner-edges', just by selecting one face.
I can get boundary faces with .GetEdges, but I can't figure out how to select normal edges.

I'm trying to make a macro, because I can't find any methode for this selection via the standard GUI. So if anyone knows a simple way of selecting 'normal-edges' without help from a macro, I'm interested in that too.
 
Replies continue below

Recommended for you

My first thought would be to approach by finding the vertices in the loop of the face and then compare each line coming from the vertex to the face normal.
 
I've been looking in to that too. But I'm not able retrieve the orientation (direction) of an edge....

I've also tried simply select all edges, and then deselct edges who are not parallel to the surface normal. But same story - can't determind the direction of an edge.

Mayby there is a parallel-methode??? Then I could just preselect an edge, and then the macro could find all remaining edges parallel to that one???
 
I assume you know how to get the face normal vector as a MathVector object. To get the direction of an edge, you'll have to get the Edge's Curve, then check if the Curve IsLine, then get the LineParams, then use those to CreateVector, using the last 3 values returned by LineParams. Cross the face normal vector with the edge's vector. If the value is < 0.0000001 or so, the vectors are parallel. The reason I don't say = 0 is because of the rounding error you often get. Many instances where you should get 0, you actually get something like 1.3438387248417E-16.
 
Well, for whom it might interest, I found a solution.
I ended up with preselecting an edge, and then find all other edges in that direction. It only works on edges in x/y/z direction(what I needed), but could easily be modified to edges running parralel in the same plane as the preselected.

Here is the code. Raw, unpolished, with danish comments and without errorhandling etc.

' ******************************************************************************
' Selects all edges with same direction as the preselected one
' (works only in x/y/z direction)
' ******************************************************************************
Option Explicit

Sub main()

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSelMgr As SldWorks.SelectionMgr
Dim vEdgeArr As Variant
Dim vEdge As Variant
Dim swEdge As SldWorks.Edge
Dim vCurveParam As Variant

Dim dirOK, dir1 As Variant
Dim dirVek(2) As Variant
Dim Bodyarr As Variant
Dim Body As SldWorks.Body2
Dim Edgearr As Variant
Dim EdgeGood(10) As SldWorks.Edge
Dim bRet As Boolean
Dim swSelData As SldWorks.SelectData

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swSelMgr = swModel.SelectionManager

'Find den ønskede kant-retning
Set swEdge = swSelMgr.GetSelectedObject5(1)

vCurveParam = swEdge.GetCurveParams2
dirVek(0) = Round(vCurveParam(0) - vCurveParam(3), 10) ' afrundes da der er kans på 17 decimal!
dirVek(1) = Round(vCurveParam(1) - vCurveParam(4), 10)
dirVek(2) = Round(vCurveParam(2) - vCurveParam(5), 10)

If dirVek(0) = 0 And dirVek(1) = 0 And dirVek(2) <> 0 Then
dirOK = 1 'Z
ElseIf dirVek(0) = 0 And dirVek(1) <> 0 And dirVek(2) = 0 Then
dirOK = 2 'Y
ElseIf dirVek(0) <> 0 And dirVek(1) = 0 And dirVek(2) = 0 Then
dirOK = 3 'X
Else
MsgBox ("Kun kanter der løber i x/y/z retning er supporteret :)")
End
End If

swModel.ClearSelection2 True

Bodyarr = swModel.GetBodies2(swSolidBody, True)

Set Body = Bodyarr(0)
Edgearr = Body.GetEdges

For Each vEdge In Edgearr

'swEdge.Display 2, 0#, 0#, 0#, True ' debuging

Set swEdge = vEdge

'swEdge.Display 2, 1#, 1#, 0#, True ' debuging

vCurveParam = swEdge.GetCurveParams2
dirVek(0) = Round(vCurveParam(0) - vCurveParam(3), 10)
dirVek(1) = Round(vCurveParam(1) - vCurveParam(4), 10)
dirVek(2) = Round(vCurveParam(2) - vCurveParam(5), 10)

If dirVek(0) = 0 And dirVek(1) = 0 And dirVek(2) <> 0 Then
dir1 = 1 'Z
ElseIf dirVek(0) = 0 And dirVek(1) <> 0 And dirVek(2) = 0 Then
dir1 = 2 'Y
ElseIf dirVek(0) <> 0 And dirVek(1) = 0 And dirVek(2) = 0 Then
dir1 = 3 'X
Else
dir1 = 0
End If

If dir1 = dirOK Then
bRet = swEdge.Select4(True, swSelData): Debug.Assert bRet
End If
 
I think you are shortchanging yourself by only considering XYZ directions. You may want to investigate the MathUtility and its objects further. They can be quite handy. Here is some mostly raw and unpolished but very robust (I think) code that will do what you originally wanted. Sorry my Danish is a bit rusty, so what few comments exist are in English. ;-)

Code:
Dim swApp As SldWorks.SldWorks
Dim swDoc As SldWorks.ModelDoc2
Dim myMathUtil As SldWorks.MathUtility
Dim swSelMgr As SldWorks.SelectionMgr
Dim myFaceNormal As MathVector
Dim myFace As SldWorks.Face2
Dim myEdge As SldWorks.Edge
Dim myCurve As SldWorks.Curve
Dim myDirVec As SldWorks.MathVector
Dim myLoop As SldWorks.Loop2
Dim myVertices As Variant
Dim myEdges As Variant
Dim myParams As Variant
Dim myXYZ(2) As Double
Dim myCrossValue As Double
Dim myCrossVector As MathVector
Dim myFaceColl As New Collection
Dim h As Long
Dim i As Long
Dim j As Long

Sub main()

Set swApp = Application.SldWorks
Set swDoc = swApp.ActiveDoc
Set myMathUtil = swApp.GetMathUtility
Set swSelMgr = swDoc.SelectionManager

'''''''''Quit if not a part doc
If swDoc.GetType <> swDocPART Then
    MsgBox "This macro works on parts only!"
    Set swApp = Nothing
    Set swDoc = Nothing
    Exit Sub
End If

'''''''Get a collection of currently selected faces
For i = 1 To swSelMgr.GetSelectedObjectCount2(-1)
    '''''''only add faces to collection
    If swSelMgr.GetSelectedObjectType3(i, -1) = swSelFACES Then
        Set myFace = swSelMgr.GetSelectedObject6(i, -1)
        ''''''Only add face if planar.  Non-planar faces have 0,0,0 normal.
        If myMathUtil.CreateVector(myFace.Normal).GetLength <> 0 Then
            myFaceColl.Add myFace
        End If
    End If
Next i

swDoc.ClearSelection2 True

'''''''iterate through face collection
For Each myFace In myFaceColl
    ''''Create vector for face normal
    Set myFaceNormal = myMathUtil.CreateVector(myFace.Normal)
    ''''Get first loop of face
    Set myLoop = myFace.GetFirstLoop
    While Not myLoop Is Nothing
        '''''Get all vertices in loop
        myVertices = myLoop.GetVertices
        For i = 0 To UBound(myVertices)
            ''''Get all edges owned by vertex
            myEdges = myVertices(i).GetEdges
            For j = 0 To UBound(myEdges)
                Set myEdge = myEdges(j)
                Set myCurve = myEdge.GetCurve
                If 0 = myCurve.IsLine Then
                    'not a line, do nothing
                Else
                    myParams = myCurve.LineParams
                    'last 3 elements are the direction unit vector
                    myXYZ(0) = myParams(3)
                    myXYZ(1) = myParams(4)
                    myXYZ(2) = myParams(5)
                    Set myDirVec = myMathUtil.CreateVector(myXYZ)
                    Set myCrossVector = myDirVec.Cross(myFaceNormal)
                    If myCrossVector.GetLength < 0.00000000001 Then
                        'if cross product is zero, select edge
                        myEdge.Select4 True, Nothing
                    End If
                End If
            Next j
        Next i
        Set myLoop = myLoop.GetNext
    Wend
Next myFace

Set swApp = Nothing
Set swDoc = Nothing
Set swSelMgr = Nothing
Set myFaceColl = Nothing

End Sub

With this code, you can select any combination of faces, edges, features, etc. before running the code. After running, all edges adjacent and normal to the faces selected will be selected. In pseudocode, the procedure is:

Examine selections, add selected faces to new collection (if planar)
For each face:
Find the face normal vector
Get first loop of face
Get array of vertexes in the loop
For each vertex in the loop:
Get array of edges
For each edge:
Get edge's Curve object
Check if linear
Create direction vector
Cross vector with normal vector
If vector length is 0, select edge
 
Nice Handleman! That code is really briliant. Thank you very much for your help.
Nice to know that such usefull help is available at this site!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor