Below is my attempt on trying to create a 'solution'.
There are probably some odd behaviors especially for very complicated model.
And if there are features after the "Test Pattern".
How one considers what "overlapping" features can be subjective so had used my own interpretation.
Say, if a resulting pattern cutout lie inside a pocket, is that considered overlapped or not.
Anyway, for the attached "Test Part", INV 2023, I considered that the resulting number of edges should be equal to the base feature cutout.
So, if a cutout falls inside the pocket, then it can be non-overlapping, but if the cutout falls on the border of the pocket, then it is overlapping.
I've added a check for minimum distance with other edges as it might be useful (actually, there is another related post with that requirement).
And since I used the Edges for comparison, the rule may take a while to evaluate the minimum distances.
Sub Main
Dim oDoc As PartDocument = ThisApplication.ActiveDocument
Dim oCompDef As PartComponentDefinition = oDoc.ComponentDefinition
Dim oFeats As PartFeatures = oCompDef.Features
Dim bCheckforMinDist As Boolean = True
Dim oUoM As UnitsOfMeasure = oDoc.UnitsOfMeasure
Dim MinDist As DoubleForEquals = 0.04 'a negative value will accept, not suppress if measure min distance = 0 mm
Dim MinDistUnit As String = "in"
'Define the base feature of the cutout pattern
Dim oPattBase As PartFeature
oPattBase = oFeats.Item("Test Feat2")
'Define the cutout pattern
Dim oPattern As RectangularPatternFeature
oPattern = oFeats.RectangularPatternFeatures.Item("Test Pattern2")
Dim oPattBaseEdgeDict As New Dictionary(Of Double, Edge)
Dim oBodyEdgeDict As New Dictionary(Of Double, Edge)
Dim oPattElemEdgeDict As New Dictionary(Of String, Edge)
'Use a dictionary to only consider unique edges
'as an edges can be shared between two faces
For Each oFace As Face In oPattBase.Faces
For Each oEdge As Edge In oFace.Edges
If Not oPattBaseEdgeDict.ContainsKey(oEdge.TransientKey) Then
oPattBaseEdgeDict.Add(oEdge.TransientKey,oEdge)
End If
Next
Next
'This needs to be set so that all features/edges after the oPattern are ignored
oPattern.SetEndOfPart(False) : oDoc.Update
Dim oElements As FeaturePatternElements
oElements = oPattern.PatternElements
'UnSuppress all Pattern Elements for now
For i = 2 To oElements.Count
oElements.Item(i).Suppressed = False
Next
Logger.Info("Pattern Base Feature Edge Count: " & oPattBaseEdgeDict.Keys.Count)
'Update Model to properly get the resulting edges of the Elements
oDoc.Update()
'Skip Index=1 as it is the Base Hole annd cannot suppress it
'Assumes that Base Hole is "ok", doesn't intersect with other cutouts
'Need more than 2 elements
If oElements.Count < 2 Then Exit Sub
For i = 2 To oElements.Count
Dim oElemKeyList As New List(Of String)
For Each oFace As Face In oElements(i).Faces
For Each oEdge As Edge In oFace.Edges
'Used a modified transient key so can get the Element index of the edge easier later
Dim sModKey As String = i & ":" & oEdge.TransientKey
If Not oPattElemEdgeDict.ContainsKey(sModKey) Then
oElemKeyList.Add(sModKey)
oPattElemEdgeDict.Add(sModKey, oEdge)
End If
Next
Next
'Assumption: the number of edges created of the Base Hole feature should equal to the resulting number of edges
'for the Pattern element to be considered not intersecting/overlapping with other cutouts
'there will be some limitations for this assumption depending on what is considered overlapping features.
If oElemKeyList.Count <> oPattBaseEdgeDict.Keys.Count Then
'Element Overlaps with other cutouts so remove those edges in the element Edge dictionary
For Each item In oElemKeyList
oPattElemEdgeDict.Remove(item)
Next
'Suppress the element considered overlapping
oElements(i).Suppressed = True
Logger.Info("Pattern Element " & i & " creates an overlap cutout")
End If
'Logger.Info("Pattern Element " & i & " Count: " & oElemKeyList.Count)
Next
If Not bCheckforMinDist Then GoTo FinalUpdate
oPattern.SetEndOfPart(True) : oDoc.Update
'Again, used a dictionary to get the unique edges before the pattern
Dim iEdgeCount As Integer = 0
For i = 1 To oCompDef.Features.Count
Dim oFeature As PartFeature = oCompDef.Features(i)
'Get only the edges before the Pattern
If oFeature.Name = oPattern.Name Then Exit For
For Each oFace As Face In oFeature.Faces
If oFace.CreatedByFeature.Name = oPattern.Name Then Continue For
For Each oEdge As Edge In oFace.Edges
If Not oBodyEdgeDict.ContainsKey(oEdge.TransientKey) Then
oBodyEdgeDict.Add(oEdge.TransientKey,oEdge)
End If
Next
Next
'Just for debugging/checking
'iEdgeCount = oBodyEdgeDict.Keys.Count - iEdgeCount
'Logger.Info(oFeature.Name & " " & iEdgeCount)
'iEdgeCount = oBodyEdgeDict.Keys.Count
Next
oPattern.SetEndOfPart(False) : oDoc.Update
Logger.Info("Base Body Edge Count: " & oBodyEdgeDict.Keys.Count)
'Evaluate Min Distaces based on Edges
Dim MinDistList As New List(Of DoubleForEquals)
Dim oSuppressIndexList As New List(Of Double)
Dim dPattIndex, dSuppressIndex As Double
Dim iCounter As Integer = 0
For Each EdgeKey In oPattElemEdgeDict.Keys
Dim oPattEdge As Edge = oPattElemEdgeDict.Item(EdgeKey)
dPattIndex = CDbl(Split(EdgeKey, ":")(0))
If oPattEdge.GeometryType = CurveTypeEnum.kUnknownCurve Then Continue For
'Logger.Info("Pattern Element: " & dPattIndex & vbLf & _
' "Suppress Element: " & dSuppressIndex)
'Check if Index is already for suppression, so just skip the Min Distance evaluation
If dPattIndex = dSuppressIndex Then Continue For
Dim dDist, dDist_Temp As DoubleForEquals
dDist = 1000 * Abs(MinDist) 'Just a large number greater than min distance as initial value
For Each oBodyEdge As Edge In oBodyEdgeDict.Values
If oBodyEdge.GeometryType = CurveTypeEnum.kUnknownCurve Then Continue For
'Check if both edges are line segments
'if they are parallel then we don't want to evaluate the min distance between them
If (TypeOf oPattEdge.Geometry Is LineSegment) AndAlso (TypeOf oBodyEdge.Geometry Is LineSegment) Then
Dim oPattEdgeVector As UnitVector = oPattEdge.Geometry.Direction
Dim oBodyEdgeVector As UnitVector = oBodyEdge.Geometry.Direction
If oPattEdgeVector.IsParallelTo(oBodyEdgeVector) Then Continue For
End If
'just for checking the iteration count
iCounter += 1
dDist_Temp = ThisApplication.MeasureTools.GetMinimumDistance(oPattEdge, oBodyEdge)
'Convert measured distance to input MinDisUnits
dDist_Temp = oUoM.ConvertUnits(dDist_Temp, UnitsTypeEnum.kDatabaseLengthUnits, oUoM.GetTypeFromString(MinDistUnit))
'Assumpption is that body thickness is larger than the minimum distace
If dDist >= dDist_Temp Then
dDist = dDist_Temp
End If
If dDist <= MinDist Then
'Logger.Info(Round(dDist,3) & " vs " & MinDist)
dSuppressIndex = dPattIndex
oSuppressIndexList.Add(dSuppressIndex)
'Logger.Info("Index :" & dSuppressIndex )
Logger.Info("Pattern Element " & dPattIndex & " Edge Pair Found (Distance = " & Round(dDist, 3) & " " & MinDistUnit & ")")
'Logger.Info(oPattEdge.GeometryType.ToString)
'Logger.Info(oBodyEdge.GeometryType.ToString)
'Found minimmum, so no need to evaluate distance to other edges
Exit For
End If
Next
Next
Logger.Info("Edge Pairs Evaluated: " & iCounter)
Logger.Info("Minimum Distance Criteria: " & MinDist & " " & MinDistUnit)
'Suppress the element index If it was found To result To lower than minimum Edge distance
For Each item In oSuppressIndexList
Logger.Info("Pattern Element " & item & " has resulting edge distance under minimum")
oElements(item).Suppressed = True
Next
FinalUpdate:
oCompDef.SetEndOfPartToTopOrBottom(False)
oDoc.Update
End Sub