Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.
jnowel
in reply to: 3DAli

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