Finding Index no. of a specific Object in a Collection

Finding Index no. of a specific Object in a Collection

mecanicu
Advocate Advocate
6,889 Views
8 Replies
Message 1 of 9

Finding Index no. of a specific Object in a Collection

mecanicu
Advocate
Advocate

Let's say i have a edge define oEdge and at oEdge.Start.StartVertex.Edges i have a collection of edges, that contains initial oEdge + 2 to 6 other edges. ( the number of item, in this case edges, varies from 3 to 7)

How to identify de Index number of oEdge in the collection? 

 

Thank you!

 

      

 

0 Likes
Accepted solutions (2)
6,890 Views
8 Replies
Replies (8)
Message 2 of 9

Michael.Navara
Advisor
Advisor
Accepted solution

You can iterate over the edges collection and test if the two edges are the same

 

Dim oEdge As Edge = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartEdgeFilter, "Pick edge")

Dim oEdges As Edges = oEdge.StartVertex.Edges

Dim i As Integer = 0
For Each vertexEdge As Edge In oEdges
	i += 1
	Logger.Info(i)
	If vertexEdge Is oEdge Then
		Logger.Info("The same on index " & i)
		Exit For
	End If
Next

'TEST ONLY
Dim part As PartDocument = ThisApplication.ActiveDocument
part.SelectSet.Clear
part.SelectSet.Select(oEdges(i))
Message 3 of 9

mecanicu
Advocate
Advocate

@Michael.Navara Thank you very much for fast replay.

Its a solution for my question but i'm having some problems integrate it in my code

Here is the code. I would like to project 2 edges from that collection, edges ar located left and right in geometric space from my oEdge (imagine a pyramid with 5faces and at the tip is my collection of edges, one of the edges is oEdge. I need the left and right edges of oEdge). The collection can have from 3 to 6 maybe 7 edges.

I have a case (Case V1) were oEdge has index 3 and Total no of edges in the collection is 4, so i-1 and i+1 should be correct. Another case (Case V3) were oEdge has index 1 and Total no of edges in  the collection is 4, so n and 2 should be correct. I don't know the logic regarding order indexing in a collection. I thought is based on a clockwise direction or something similar, but it has no logic.

i would like a solution to better identify the 2 edges I need. Tx. 

 

 

 

Sub Main()

Dim oApp  = ThisApplication
Dim part As PartDocument = ThisDoc.Document
Dim partDef = part.ComponentDefinition
Dim bodies = partDef.SurfaceBodies

For Each body As SurfaceBody In bodies
Dim edges = body.Edges
	For Each oEdge As Edge In edges
	Dim length = oApp.MeasureTools.GetMinimumDistance(oEdge.StartVertex, oEdge.StopVertex)
    '   MessageBox.Show("Message: " & length, "Title")
	Dim wp As WorkPlane
	Dim oWkPoint As WorkPoint
	oWkPoint = part.ComponentDefinition.WorkPoints.AddFixed(oEdge.PointOnEdge, Construction= False)
	wp = part.ComponentDefinition.WorkPlanes.AddByNormalToCurve(oEdge, oWkPoint, Construction= False)			
	Dim oSketch As Sketch
	oSketch = partDef.Sketches.AddWithOrientation(wp, oEdge, True, True, oWkPoint )
        Dim n As Integer
        n = oEdge.StartVertex.Edges.Count
	MessageBox.Show("Message: " & n, "Total Edges")
				
	Dim oEdges As edges = oEdge.StartVertex.Edges
	Dim sEntity1 As SketchLine
	Dim sEntity2 As SketchLine
	Dim i As Integer = 0
	For Each vertexEdge As Edge In oEdges
		i += 1
		'Case V1
                If vertexEdge Is oEdge And i<n And i>1 Then 
		MessageBox.Show("Message: " & i, "oEdge V1")
		sEntity1 = oSketch.AddByProjectingEntity(oEdge.StartVertex.Edges.Item(i - 1))
	        sEntity2 = oSketch.AddByProjectingEntity(oEdge.StartVertex.Edges.Item(i+1))
		
                'Case V2
                ElseIf vertexEdge Is oEdge And i=n Then
		MessageBox.Show("Message: " & i, "oEdge V2")
		sEntity1 = oSketch.AddByProjectingEntity(oEdge.StartVertex.Edges.Item(n - 1))
	        sEntity2 = oSketch.AddByProjectingEntity(oEdge.StartVertex.Edges.Item(1))
		
                'Case V3
                ElseIf vertexEdge Is oEdge And i=1 Then
		MessageBox.Show("Message: " & i, "oEdge V3")
		sEntity1 = oSketch.AddByProjectingEntity(oEdge.StartVertex.Edges.Item(n))
	        sEntity2 = oSketch.AddByProjectingEntity(oEdge.StartVertex.Edges.Item(2))
		End If
	Next
        sEntity1.DisabledActionTypes = True
	sEntity2.DisabledActionTypes = True
	sEntity1.Construction = True
	sEntity2.Construction = True
	Dim center As SketchPoint
	center = oSketch.AddByProjectingEntity(oWkPoint)
	Dim profileLine1 As SketchLine
	profileLine1 = oSketch.SketchLines.AddByTwoPoints(center, sEntity1.Geometry.MidPoint)
        Dim profileLine2 As SketchLine
	profileLine2 = oSketch.SketchLines.AddByTwoPoints(center, sEntity2.Geometry.MidPoint)
	Dim latime As DimensionConstraint
	latime = oSketch.DimensionConstraints.AddTwoPointDistance(center, profileLine1.EndSketchPoint, _
	kAlignedDim, ThisApplication.TransientGeometry.CreatePoint2d(1, 0), False)
        latime.Parameter.Value = 1
        oSketch.GeometricConstraints.AddEqualLength(profileLine1, profileLine2)
        oSketch.GeometricConstraints.AddCollinear(sEntity1, profileLine1)
	oSketch.GeometricConstraints.AddCollinear(sEntity2, profileLine2)
	'Create a Path.
	Dim oPath As Path
        oPath = partDef.Features.CreatePath(profileLine1)
  	Dim oContourFlangeFeatures As ContourFlangeFeatures
	oContourFlangeFeatures = partDef.Features.ContourFlangeFeatures
	'Create the flange definition.
	Dim cfDef As ContourFlangeDefinition
	cfDef = oContourFlangeFeatures.CreateContourFlangeDefinition(oPath)
	cfDef.Operation = kNewBodyOperation
	Call cfDef.SetDistanceExtent(length, PartFeatureExtentDirectionEnum.kSymmetricExtentDirection)
	Dim oCF As ContourFlangeFeature
	oCF = oContourFlangeFeatures.Add(cfDef)
       	Next
 Next

End Sub

 

 

 

 

0 Likes
Message 4 of 9

Michael.Navara
Advisor
Advisor

I don't know if access to edges by index is right approach. Because I don't know it is guaranteed order of edges in collection.

But two adjacent edges connected in one vertex MUST belong to one face. Your oEdge belongs to two faces (in described situation). Only two more edges belongs to one of this two faces. This edges is your result. 

Message 5 of 9

mecanicu
Advocate
Advocate
Exactly, you are right. But i don't know how to!!! maybe a start in this direction will be much appreciate!
Thank you very much @Michael.Navara
0 Likes
Message 6 of 9

Michael.Navara
Advisor
Advisor
Accepted solution

Try this piece of code for beginning

Dim oEdge As Edge = ThisApplication.CommandManager.Pick(selectionfilterenum.kPartEdgeFilter, "Pick edge")
Dim oFaces As Faces = oEdge.Faces

Dim adjecentEdges As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

For Each edg As Edge In oEdge.StartVertex.Edges
	If edg Is oEdge Then Continue For
	For Each f1 As Face In edg.Faces
		For Each f2 As Face In oFaces
			If f1 Is f2 Then
				adjecentEdges.Add(edg)
				GoTo nextEdge
			End If
		Next
	Next
	nextEdge :
Next

'TEST ONLY
Logger.Debug(adjecentEdges.Count)	
Dim part As PartDocument = ThisDoc.Document
part.SelectSet.Clear
part.SelectSet.SelectMultiple(adjecentEdges)

 

 

Message 7 of 9

mecanicu
Advocate
Advocate

It works like magic.😀

Here is the Final code, if some one is interested. It working like a frame generator but for custom corner angle.

P.S. It's working only in Sheet Metal Part and it's generating a Multi Body Part. U need to have or extrude a Solid with edges (example a pyramid or a cube) "latime.Parameter.Value = 1" controls the width of the corner angle in cm.

It has some bug's (like it fails at firs, maybe it's generate a bad first part. but after second run it's ok), limitation and u have to manually set the "offset direction" for Contour Flange  + Corner Seam the frames after( next step to automate) .... 

Thank you very much to @Michael.Navara u helped me a lot. Kudos

 

 

Sub Main()

Dim oApp  = ThisApplication
Dim part As PartDocument = ThisDoc.Document
Dim partDef = part.ComponentDefinition
Dim bodies = partDef.SurfaceBodies

For Each body As SurfaceBody In bodies
Dim edges = body.Edges
	For Each oEdge As Edge In edges
	Dim length = oApp.MeasureTools.GetMinimumDistance(oEdge.StartVertex, oEdge.StopVertex)
        '   MessageBox.Show("Message: " & length, "Title")

				
	Dim wp As WorkPlane
	Dim oWkPoint As WorkPoint
	oWkPoint = part.ComponentDefinition.WorkPoints.AddFixed(oEdge.PointOnEdge, Construction= False)
	wp = part.ComponentDefinition.WorkPlanes.AddByNormalToCurve(oEdge, oWkPoint, Construction= False)			


	Dim oSketch As Sketch
	oSketch = partDef.Sketches.AddWithOrientation(wp, oEdge, True, True, oWkPoint )
	Dim oFaces As Faces = oEdge.Faces
	Dim adjecentEdges As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	For Each edg As Edge In oEdge.StartVertex.Edges
		If edg Is oEdge Then Continue For
		For Each f1 As Face In edg.Faces
		For Each f2 As Face In oFaces
			If f1 Is f2 Then
			adjecentEdges.Add(edg)
			GoTo nextEdge
		End If
	        Next
		Next
	nextEdge :
	Next
				
	Dim sEntity1 As SketchLine
	Dim sEntity2 As SketchLine
	sEntity1 = oSketch.AddByProjectingEntity(adjecentEdges.Item(1))
	sEntity2 = oSketch.AddByProjectingEntity(adjecentEdges.Item(2))
	sEntity1.DisabledActionTypes = True
	sEntity2.DisabledActionTypes = True
	sEntity1.Construction = True
	sEntity2.Construction = True      
	Dim center As SketchPoint
	center = oSketch.AddByProjectingEntity(oWkPoint)
	Dim profileLine1 As SketchLine
	profileLine1 = oSketch.SketchLines.AddByTwoPoints(center, sEntity1.Geometry.MidPoint)
        Dim profileLine2 As SketchLine
	profileLine2 = oSketch.SketchLines.AddByTwoPoints(center, sEntity2.Geometry.MidPoint)
	Dim latime As DimensionConstraint
	latime = oSketch.DimensionConstraints.AddTwoPointDistance(center, profileLine1.EndSketchPoint, kAlignedDim, ThisApplication.TransientGeometry.CreatePoint2d(1, 0), False)
        latime.Parameter.Value = 1
		 
         oSketch.GeometricConstraints.AddEqualLength(profileLine1, profileLine2)
	 oSketch.GeometricConstraints.AddCollinear(sEntity1, profileLine1)
         oSketch.GeometricConstraints.AddCollinear(sEntity2, profileLine2)
	'Create a Path.
	 Dim oPath As Path
	 oPath = partDef.Features.CreatePath(profileLine1)
	 Dim oContourFlangeFeatures As ContourFlangeFeatures
	 oContourFlangeFeatures = partDef.Features.ContourFlangeFeatures
	 'Create the flange definition.
	 Dim cfDef As ContourFlangeDefinition
	 cfDef = oContourFlangeFeatures.CreateContourFlangeDefinition(oPath)
	 cfDef.Operation = kNewBodyOperation
	 Call cfDef.SetDistanceExtent(length, PartFeatureExtentDirectionEnum.kSymmetricExtentDirection)
	    		
	 Dim oCF As ContourFlangeFeature
	 oCF = oContourFlangeFeatures.Add(cfDef)
                
	 Next
	Exit For
  Next

End Sub

 

 

 

0 Likes
Message 8 of 9

loicLPQZG
Contributor
Contributor

Could i bother you with a similar question ,

 

I have my browsernoders ordered in my browser.

If i have a base number of 10 i would like to suppress all the node indexes > 10

The reason i would like to use index is because the parts are the same ones just copied X amount of times so they have to same name but the displayname Part_1:1 or Part_1:2 or Part_1:3  is not in the right order.

 

 

for each oBrow as browsernode in ofolder.Browsernodes



if ofolder.Browsernodes.getindexof(oBrow) > 10 then '{doesn't work}

oBrow.nativeobject.suppress

end if



next oBrow

 

does anybody know what to use instead .getindexof() 

 

many thanks!

 

 

 

 

0 Likes
Message 9 of 9

WCrihfield
Mentor
Mentor

Hi @loicLPQZG.  When you need to iterate through a collection in their 'natural' order, which uses their 'Index' number, then you need to use a [For i As Integer = 1 To Count...Next] type loop, instead of a [For Each ... Next] type of loop.  For Each loop is not guaranteed to iterate though them in the same order as their Index numbers, but the other way does.  For Each is slightly more efficient, but offers a little less control also.  However, not all types of collections keep their contents in a specific order, and when the collection itself does not retain the order of its contents, then the Index numbers of the objects within the collection are meaningless or random.  Natural order goes by order of existence.   What that means is, the first object that was created, and has existed in that collection the longest, will have the first, or lowest value Index number, and the newest item in that collection, that has existed in that collection the least amount of time, will have the last, or greatest value Index number.  If an item used to exist in that collection, but was removed from it, then added back in later, then it will be newer than it used to be, and have a later (or larger) index number than it did before.  That is how most collections work, but not all of them.  There are tons of different types of collections.

Another tip is that if a collection type is defined by Autodesk or Inventor, the Index of its first item will be one (1).  But most collection types defined by the vb.net language, the index of the first item will be zero (0), instead of one.  Examples of vb.net collections like that are Array(), List(Of ...), & Dictionary(Of ...).

Here is a copy of your last code that I just directly edited within this forum reply to be similar to what I am talking about.

For i As Integer = 1 To ofolder.Browsernodes.Count
Dim oBrow as browsernode = ofolder.Browsernodes.Item(i)
If i > 10 then '{doesn't work}
oBrow.NativeObject.Suppress()
End If
Next oBrow

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes