Files
Get extreme length of body Associated model
Code
Module: mMain
'Demonstrates how to use ExtremeLength class to get the extreme length of the selected body _
in a direction determined by another entity that the user has selected.
'To use ExtremeLength, run Calculate function. This takes in two parameters. The first is _
the body for which you want the extreme length and the second parameter must be a _
straight edge, circular edge, cylindrical face, planar face, or reference plane.
'Notes:
'For a circular edge and cylindrical face, the axis is used. For planar face, reference _
plane, and straight edge, the normal is used.
'The body specified in the first parameter of Calculate does not need to be parent of the _
entity specified in the second parameter of Calculate.
'Preconditions for using the macro:
' 1. Body is selected in feature tree
' 2. Straight edge, circular edge, planar face, cylindrical face, or reference plane is selected
'Written by Keith Rice
'CADSharp LLC
'www.cadsharp.com
Option Explicit
Private Const SEL_ERR As String = "In order to run this macro you must pre-select two objects. " & _
"The first object must be a body, selected from the FeatureManager design tree. " & _
"The second object must be a straight edge, circular edge, planar face, cylindrical face, " & _
"or reference plane."
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSelMgr As SldWorks.SelectionMgr
Dim swBody As SldWorks.Body2
Dim swObj As Object
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
swApp.SendMsgToUser "Please open a part or assembly."
Exit Sub
End If
If swModel.GetType = swDocDRAWING Then
swApp.SendMsgToUser "Please open a part or assembly."
Exit Sub
End If
Set swSelMgr = swModel.SelectionManager
If swSelMgr.GetSelectedObjectCount2(-1) <> 2 Or _
swSelMgr.GetSelectedObjectType3(1, -1) <> swSelSOLIDBODIES Then
swApp.SendMsgToUser SEL_ERR
Exit Sub
End If
Set swBody = swSelMgr.GetSelectedObject6(1, -1)
Set swObj = swSelMgr.GetSelectedObject6(2, -1)
If TypeOf swObj Is SldWorks.Feature Then
Dim swfeat As SldWorks.Feature
Set swfeat = swObj
If Not TypeOf swfeat.GetSpecificFeature2 Is SldWorks.RefPlane Then
swApp.SendMsgToUser SEL_ERR
Exit Sub
End If
ElseIf Not TypeOf swObj Is SldWorks.Edge And Not TypeOf swObj Is SldWorks.Face2 And Not TypeOf swObj Is SldWorks.Feature Then
swApp.SendMsgToUser SEL_ERR
Exit Sub
End If
Dim myExtremeLength As New ExtremeLength
myExtremeLength.Calculate swBody, swObj
If IsEmpty(myExtremeLength.Direction) Then
swApp.SendMsgToUser "Failed to get direction vector for selected object."
Else
If myExtremeLength.Length = -1 Then
swApp.SendMsgToUser "Failed to get extreme length."
Else
If MsgBox("Extreme length (m): " & Round(myExtremeLength.Length, 6) & vbCrLf & vbCrLf & _
"Would you like to sketch the line between the two extreme points discovered? " & _
"(Note: This line does not necessarily represent the extreme length.)", vbYesNo) = vbYes Then
SketchExtremePoints swModel, myExtremeLength.ExtremePoints
End If
End If
End If
End Sub
Private Sub SketchExtremePoints(swModel As SldWorks.ModelDoc2, vPts)
Dim swSketch As SldWorks.Sketch
Set swSketch = swModel.SketchManager.ActiveSketch
If swSketch Is Nothing Then
swModel.SketchManager.Insert3DSketch Empty
swModel.SketchManager.CreateLine vPts(0), vPts(1), vPts(2), vPts(3), vPts(4), vPts(5)
swModel.SketchManager.Insert3DSketch Empty
ElseIf swSketch.Is3D Then
swModel.SketchManager.CreateLine vPts(0), vPts(1), vPts(2), vPts(3), vPts(4), vPts(5)
Else
swModel.SketchManager.InsertSketch Empty
swModel.SketchManager.Insert3DSketch Empty
swModel.SketchManager.CreateLine vPts(0), vPts(1), vPts(2), vPts(3), vPts(4), vPts(5)
swModel.SketchManager.Insert3DSketch Empty
End If
End Sub
Class: ExtremeLength
Option Explicit
Private extreme_points_backing As Variant
Private direction_backing As Variant
Private length_backing As Double
Private Enum EdgeGeom
Straight
Arc
OtherEdgeType
End Enum
Private Enum FaceGeom
planar
cylindrical
OtherFaceType
End Enum
Public Property Get ExtremePoints() As Variant
ExtremePoints = extreme_points_backing
End Property
Public Property Get Direction() As Variant
Direction = direction_backing
End Property
Public Property Get Length() As Double
Length = length_backing
End Property
Public Sub Calculate(body As SldWorks.Body2, ent As Object)
extreme_points_backing = Empty
direction_backing = Empty
length_backing = -1
If ent Is Nothing Then Exit Sub
If TypeOf ent Is SldWorks.Edge Then
If ProcessEdge(ent, direction_backing) = False Then Exit Sub
ElseIf TypeOf ent Is SldWorks.Face2 Then
If ProcessFace(ent, direction_backing) = False Then Exit Sub
ElseIf TypeOf ent Is SldWorks.Feature Then
If ProcessFeat(ent, direction_backing) = False Then Exit Sub
End If
If IsEmpty(direction_backing) Then Exit Sub
length_backing = GetExtremeLength(body, direction_backing, extreme_points_backing)
End Sub
Private Function ProcessEdge(swObj As Object, ByRef vDir As Variant) As Boolean
ProcessEdge = True
Dim swEdge As SldWorks.Edge
Set swEdge = swObj
If GetEdgeGeometry(swEdge) = Straight Then
vDir = GetStraightEdgeDirVector(swEdge)
ElseIf GetEdgeGeometry(swEdge) = Arc Then
vDir = GetArcEdgeDirVector(swEdge)
Else
ProcessEdge = False
End If
End Function
Private Function ProcessFace(swObj As Object, ByRef vDir As Variant) As Boolean
ProcessFace = True
Dim swFace As SldWorks.Face2
Set swFace = swObj
If GetFaceGeometry(swFace) = planar Then
vDir = GetPlanarFaceDirVector(swFace)
ElseIf GetFaceGeometry(swFace) = cylindrical Then
vDir = GetCylFaceDirVector(swFace)
Else
ProcessFace = False
End If
End Function
Private Function ProcessFeat(swObj As Object, ByRef vDir As Variant) As Boolean
ProcessFeat = True
Dim swfeat As SldWorks.Feature
Dim swRefPlane As SldWorks.RefPlane
Set swfeat = swObj
If swfeat.GetTypeName = "RefPlane" Then
Set swRefPlane = swfeat.GetSpecificFeature2
vDir = GetRefPlaneDirVector(swRefPlane)
Else
ProcessFeat = False
End If
End Function
Private Function GetEdgeGeometry(swEdge As SldWorks.Edge) As EdgeGeom
Dim swCurve As SldWorks.Curve
Set swCurve = swEdge.GetCurve
If swCurve.IsLine Then
GetEdgeGeometry = Straight
ElseIf swCurve.IsCircle Then
GetEdgeGeometry = Arc
Else
GetEdgeGeometry = OtherEdgeType
End If
End Function
Private Function GetFaceGeometry(swFace As SldWorks.Face2) As FaceGeom
Dim swSurf As SldWorks.Surface
Set swSurf = swFace.GetSurface
If swSurf.IsPlane Then
GetFaceGeometry = planar
ElseIf swSurf.IsCylinder Then
GetFaceGeometry = cylindrical
Else
GetFaceGeometry = OtherFaceType
End If
End Function
Private Function GetStraightEdgeDirVector(swEdge As SldWorks.Edge) As Variant
Dim swCurve As SldWorks.Curve
Set swCurve = swEdge.GetCurve
GetStraightEdgeDirVector = Array(swCurve.LineParams(3), swCurve.LineParams(4), swCurve.LineParams(5))
End Function
Private Function GetArcEdgeDirVector(swEdge As SldWorks.Edge) As Variant
Dim swCurve As SldWorks.Curve
Set swCurve = swEdge.GetCurve
GetArcEdgeDirVector = Array(swCurve.CircleParams(3), swCurve.CircleParams(4), swCurve.CircleParams(5))
End Function
Private Function GetPlanarFaceDirVector(swFace As SldWorks.Face2) As Variant
GetPlanarFaceDirVector = swFace.Normal
End Function
Private Function GetCylFaceDirVector(swFace As SldWorks.Face2) As Variant
Dim swSurf As SldWorks.Surface
Set swSurf = swFace.GetSurface
GetCylFaceDirVector = Array(swSurf.CylinderParams(3), swSurf.CylinderParams(4), swSurf.CylinderParams(5))
End Function
Private Function GetRefPlaneDirVector(swRefPlane As SldWorks.RefPlane) As Variant
GetRefPlaneDirVector = Array(swRefPlane.GetRefPlaneParams(6), swRefPlane.GetRefPlaneParams(7), swRefPlane.GetRefPlaneParams(8))
End Function
Private Function GetExtremeLength(swBody As SldWorks.Body2, vDir As Variant, _
ByRef vExtremePoints As Variant) As Double
Dim dblExtremePts(5) As Double
If swBody.GetExtremePoint(vDir(0), vDir(1), vDir(2), dblExtremePts(0), dblExtremePts(1), dblExtremePts(2)) = False Then
'Failed to get extreme point in first direction
GetExtremeLength = -1
Exit Function
End If
If swBody.GetExtremePoint(-1 * vDir(0), -1 * vDir(1), -1 * vDir(2), dblExtremePts(3), dblExtremePts(4), dblExtremePts(5)) = False Then
'Failed to get extreme point in second direction
GetExtremeLength = -1
Exit Function
End If
'See http://www.evernote.com/l/APC1pDtICBxDT5N-Bj6UHs36mPM3mo6sC_0/ for an
' explanation of the calculation below.
Dim Length As Double
Length = CalculateLength(dblExtremePts, vDir)
vExtremePoints = dblExtremePts
GetExtremeLength = Length
End Function
Private Function CalculateLength(vExtremePts, vDir As Variant) As Double
Dim swApp As SldWorks.SldWorks
Dim swMathUtil As SldWorks.MathUtility
Dim swV1 As SldWorks.MathVector
Dim swV2 As SldWorks.MathVector
Dim swDir1 As SldWorks.MathVector
Dim swDir2 As SldWorks.MathVector
Dim swVHyp As SldWorks.MathVector
Dim ptArr(2) As Double
Dim dblDotProduct As Double
Set swApp = Application.SldWorks
Set swMathUtil = swApp.GetMathUtility
ptArr(0) = vExtremePts(0)
ptArr(1) = vExtremePts(1)
ptArr(2) = vExtremePts(2)
Set swV1 = swMathUtil.CreateVector(ptArr)
ptArr(0) = vExtremePts(3)
ptArr(1) = vExtremePts(4)
ptArr(2) = vExtremePts(5)
Set swV2 = swMathUtil.CreateVector(ptArr)
ptArr(0) = vDir(0)
ptArr(1) = vDir(1)
ptArr(2) = vDir(2)
Set swDir1 = swMathUtil.CreateVector(ptArr)
Set swVHyp = swV1.Subtract(swV2)
Set swDir2 = swVHyp.Normalise
dblDotProduct = swDir2.Dot(swDir1)
CalculateLength = Abs(swVHyp.GetLength * dblDotProduct)
End Function