Is there a way to detect overlapping features using iLogic/API ?

Is there a way to detect overlapping features using iLogic/API ?

3DAli
Collaborator Collaborator
860 Views
8 Replies
Message 1 of 9

Is there a way to detect overlapping features using iLogic/API ?

3DAli
Collaborator
Collaborator

Hi, 

In a scenario like the one shown below, if a rule for the number of elements controls the pattern, ideally, you should adjust the quantity to avoid a situation where two holes overlap.  is there a way to catch this by checking the geometry for overlapping features in API?  nothing is constant here, the plate with, the position of the first element, quantity, and spacing are all dynamic, and this makes it very unpredictable to avoid mathematically, that's why I thought if we could check for the overlapping feature, then we can suppress those specific elements. any thoughts, or ideas are greatly appreciated.

 

Best

Ali

 

3DAli_0-1730209003088.png

 

0 Likes
Accepted solutions (1)
861 Views
8 Replies
Replies (8)
Message 2 of 9

_dscholtes_
Advocate
Advocate

The first thing that comes to mind for this example is counting the quantity of edgeloops of the top face. If there are no overlapping holes, there should be one edgeloop for the contour of the plate and one edgeloop for each non-overlapping hole. So for a plate with five holes, the edgeloop count should be 6 (hole pattern quantity + 1).

As soon as you have less than 6 edgeloops, you have either overlapping holes, holes placed on the contour of the plate or holes located outside of the plate.

Message 3 of 9

WCrihfield
Mentor
Mentor

Hi @3DAli.  One of the first things that comes to mind when looking at that situation is checking either Mass or Volume of the 'remaining' solid body(s), both before and after the feature is created/updated, to see if they match what is expected.  Volume would likely be simpler.  If you know the size of the hole, and know that it goes through, and know the thickness of the part, then you can easily calculate the volume of that solid cylinder.  Multiply that by the quantity, to get the total volume displacement.  Get/record volume of part/body before creating/changing/updating the feature, then calculate expected displacement, then get volume again, and compare if it it different by the expected amount, within a tolerance.  Just the first idea, but I'm sure there are multiple other ways.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 9

3DAli
Collaborator
Collaborator

@WCrihfield and @_dscholtes_ are both great ideas, thanks so much for sharing 

0 Likes
Message 5 of 9

C_Haines_ENG
Collaborator
Collaborator

You can use the RangeBox property of a part feature, and then check if they are overlapping using "IsDisjoint". See code below. Be careful with this method though, as if the hole is COMPLETELY overlapped it will return "Nothing" for its rangebox and then you cant use .isDisjoint. I added in some checking for this, but its something to be aware of.

 

Dim oPart As PartDocument = ThisDoc.Document

For Each oFeature As PartFeature In oPart.ComponentDefinition.Features.HoleFeatures
	
	If oFeature.RangeBox Is Nothing Then Continue For

	For Each oFeatureOther As PartFeature In oPart.ComponentDefinition.Features.HoleFeatures
		
		If oFeatureOther IsNot oFeature And oFeatureOther.RangeBox IsNot Nothing 
			
			If Not oFeature.RangeBox.IsDisjoint(oFeatureOther.RangeBox) Then Logger.Info("OVERLAPPING: " & oFeature.Name)
			
		End If
		
	Next
	
Next

 

 

0 Likes
Message 6 of 9

Pineapple2024
Advocate
Advocate

Add driven dimension on the 2 holes.

With diameter of both holes, you can calculate how many holes will fit.

A minimum distance can be set also.

0 Likes
Message 7 of 9

jnowel
Advocate
Advocate
Accepted solution

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

 

Message 8 of 9

3DAli
Collaborator
Collaborator

Thank you, I used a similar approach to compare the counts of the theoretical number of holes and actual circular edges to catch overlaps and it worked very well, the above is more comprehensive and I am sure someone will find it helpful 

 

Best

Ali

0 Likes
Message 9 of 9

Maxim-CADman77
Advisor
Advisor

Just an idea for probably simpler/faster approach that potentially can be applied to more complex geometry (ex. engraved text etc) and even on models without Part Features (derived, imported etc):

 

1. Get the initial volume value

2. Calculate the volume of sure non-overlapped feature instance

   2.1. Start the transaction

   2.2. Create temporary Extrude-Add (New Solid) feature and get the non-overlapped volume change (new solid) value

   2.3. Abort the transaction

3. Create the desired (Cut/Engrave) feature.

 

If resulting volume is > (initial volume - temporary solid volume) then there is some overlapping.

 

I wonder if step 2 can be done without making any change to the volume at all (by means of transient geometry)?

Please vote for Inventor-Idea Text Search within Option Names

0 Likes