Auto Dimension Drawing: Retrieving Drawing View curve from part inside sub assembly

Auto Dimension Drawing: Retrieving Drawing View curve from part inside sub assembly

A.Acheson
Mentor Mentor
903 Views
5 Replies
Message 1 of 6

Auto Dimension Drawing: Retrieving Drawing View curve from part inside sub assembly

A.Acheson
Mentor
Mentor

Hi all, Having a little trouble working through this issue. I am trying to retrieve a drawing curve from a part inside a sub assembly. The code below works find when the part is inside an assembly but not if it is deeper inside a sub assembly. Any idea what the issue could be? Is it proxy related? for context the part is an ipart member so the ipart factory needs to be read to find the face in the member. 

 

Errors out here.

AAcheson_0-1688071763133.png

 

 

Sub Main
	
	Dim drawDoc As DrawingDocument = ThisDoc.Document

	For Each drawSheet As Sheet In drawDoc.Sheets

		For Each drawView As DrawingView In drawSheet.DrawingViews

			Dim viewDoc As Document = drawView.ReferencedDocumentDescriptor.ReferencedDocument
					
		        ' Get the assembly document for the view.
				If viewDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		        	
					Dim asmDoc As AssemblyDocument = viewDoc
					Dim occ As ComponentOccurrence
				
					For Each oDoc In asmDoc.AllReferencedDocuments
						Dim RefOccs As ComponentOccurrencesEnumerator = asmDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc)
							If RefOccs.Count = 0 Then Continue For
							occ = RefOccs(1)
			        'For Each occ As ComponentOccurrence In asmDoc.ComponentDefinition.Occurrences
			      
			            If Not occ.Name.Contains("Part1") Then Continue For
							MessageBox.Show(occ.Name, "Title")

						' Get curve, location of each dimension leg start point.
						Dim curve1 As DrawingCurve = GetCurve("Part1_Left", occ, drawView)
						Dim curve2 As DrawingCurve = GetCurve("Part1_Right", occ, drawView)

						Dim tg As TransientGeometry = ThisApplication.TransientGeometry
				
						Dim pt1 As Point2d = tg.CreatePoint2d(curve1.StartPoint.X + 2, curve1.StartPoint.Y)

						Dim genDims As GeneralDimensions = drawSheet.DrawingDimensions.GeneralDimensions
	
						Dim dim1 As LinearGeneralDimension = genDims.AddLinear(pt1, drawSheet.CreateGeometryIntent(curve1), drawSheet.CreateGeometryIntent(curve2))
						dim1.CenterText
				
					Next
				Else
					MessageBox.Show("Is a part view Skiping", "Title")
					Continue For
				End If
			Next
	   Next
End Sub

' Work through either part or ipart looking for named faces then the curves. 
Function GetCurve(faceName As String, occ As ComponentOccurrence, drawView As DrawingView) As DrawingCurve
  'https://modthemachine.typepad.com/my_weblog/2020/09/get-named-face-of-ipartfactory.html
  Dim doc As PartDocument = occ.Definition.Document
  Dim drawViewCurves As DrawingCurvesEnumerator
  Dim drawCurve As DrawingCurve
  Dim partFace As Face
  Dim partFaceProxy As FaceProxy
  Dim namedEntities As NamedEntities
  
  If doc.ComponentDefinition.IsiPartMember Then

	  Dim factoryDoc As PartDocument = doc.ComponentDefinition.iPartMember.ReferencedDocumentDescriptor.ReferencedDocument
	    							
	  namedEntities = iLogicVb.Automation.GetNamedEntities(factoryDoc)
	  
	  partFace = namedEntities.FindEntity(faceName)
	  
	  For Each f2 As Face In doc.ComponentDefinition.SurfaceBodies(1).Faces
	    If f2.ReferencedEntity Is partFace Then
			
			' Get the face into the context of the assembly
	      	occ.CreateGeometryProxy(f2, partFaceProxy)
			
			' Finds the drawing edge that represents the one with the named entity.
			Try
				drawViewCurves = drawView.DrawingCurves(partFaceProxy)
			Catch
				Logger.Info("Error getting DrawViewCurves")
			End Try
			Try
				drawCurve = drawViewCurves.Item(1)
			Catch
				Logger.Info("Error getting DrawViewCurve")
			End Try
			Return drawCurve
	      Exit Function
	    End If
	  Next
	  
 Else
		namedEntities = iLogicVb.Automation.GetNamedEntities(doc)
    	partFace = namedEntities.FindEntity(faceName)
	
		' Get the face into the context of the assembly.
		occ.CreateGeometryProxy(partFace, partFaceProxy)
		drawViewCurves = drawView.DrawingCurves(partFaceProxy)
		drawCurve = drawViewCurves.Item(1)
		Return drawCurve
  End If
  
End Function

 

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Accepted solutions (1)
904 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @A.Acheson.  Yes, I believe this is simply a proxy level related issue.  If that iPart member was within a sub assembly, inside the main assembly that the view is for, then you would simply need to 'get a proxy of the proxy' to get a reference to the proxy that is in the context of the top level assembly.  However, I can not be sure that the specific component you are working with is actually at that specific level in your overall assembly structure, due to something I am seeing in middle of this code that is a bit of a wildcard in my head.  You get all referenced documents of the main assembly to a variable, then get all referenced components within the main assembly that references that one referenced document, without knowing which specific document it is, then simply get the first referenced component in that collection.  If I knew that was only component like that in the entire assembly structure, that would simplify things a bit, and everything would likely be OK.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 6

A.Acheson
Mentor
Mentor

Hi @WCrihfield 

 

Thank you for the response, yes there is only one occurrence in the sub assembly so no extra occurrences to deal with. I did use also a recursion method to retrieve the occurrence in another trial but with the same result. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 4 of 6

lmc.engineering
Advocate
Advocate

Hi @A.Acheson 

 

I made a couple of tweaks so this works at all levels now, and I ditched the proxies in favour of generic object, letting Inventor sort out the proxy mess.

Sub Main

	Dim drawDoc As DrawingDocument = ThisDoc.Document

	For Each drawSheet As Sheet In drawDoc.Sheets

		For Each drawView As DrawingView In drawSheet.DrawingViews

			Dim viewDoc As Document = drawView.ReferencedDocumentDescriptor.ReferencedDocument

			' Get the assembly document for the view.
			If viewDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then

				Dim asmDoc As AssemblyDocument = viewDoc
				Dim OccEnum As ComponentOccurrencesEnumerator
				OccEnum = asmDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(asmDoc.ComponentDefinition)

				For Each Occ As ComponentOccurrence In OccEnum
					If Not TypeOf Occ.Definition.Document Is PartDocument Then Continue For

					' Get curve, location of each dimension leg start point.
					Dim curve1 As DrawingCurve = GetCurve("Part1_Left", Occ, drawView)
					If curve1 Is Nothing Then Continue For
					Dim curve2 As DrawingCurve = GetCurve("Part1_Right", Occ, drawView)
					If curve2 Is Nothing Then Continue For

					Dim tg As TransientGeometry = ThisApplication.TransientGeometry

					Dim pt1 As Point2d = tg.CreatePoint2d(curve1.StartPoint.X + 2, curve1.StartPoint.Y)

					Dim genDims As GeneralDimensions = drawSheet.DrawingDimensions.GeneralDimensions

					Dim dim1 As LinearGeneralDimension = genDims.AddLinear(pt1, drawSheet.CreateGeometryIntent(curve1), drawSheet.CreateGeometryIntent(curve2))
					dim1.CenterText

				Next
			Else
				MessageBox.Show("Is a part view Skiping", "Title")
				Continue For
			End If
		Next
	Next
End Sub

' Work through either part or ipart looking for named faces then the curves. 
Function GetCurve(faceName As String, occ As ComponentOccurrence, drawView As DrawingView) As DrawingCurve
	'https://modthemachine.typepad.com/my_weblog/2020/09/get-named-face-of-ipartfactory.html
	Dim doc As PartDocument = occ.Definition.Document
	Dim drawViewCurves As DrawingCurvesEnumerator
	Dim drawCurve As DrawingCurve
	Dim partFace As Face
	Dim partobj As Object
	Dim namedEntities As NamedEntities

	If doc.ComponentDefinition.IsiPartMember Then

		Dim factoryDoc As PartDocument = doc.ComponentDefinition.iPartMember.ReferencedDocumentDescriptor.ReferencedDocument

		namedEntities = iLogicVb.Automation.GetNamedEntities(factoryDoc)

		Try
			partFace = namedEntities.FindEntity(faceName)
		Catch
			Return Nothing
		End Try

		For Each f2 As Face In doc.ComponentDefinition.SurfaceBodies(1).Faces
			If f2.ReferencedEntity Is partFace Then

				' Get the face into the context of the assembly
				occ.CreateGeometryProxy(f2, partobj)

				' Finds the drawing edge that represents the one with the named entity.
				Try
					drawViewCurves = drawView.DrawingCurves(partobj)
				Catch
					Logger.Info("Error getting DrawViewCurves")
				End Try
				Try
					drawCurve = drawViewCurves.Item(1)
				Catch
					Logger.Info("Error getting DrawViewCurve")
				End Try
				Return drawCurve
				Exit Function
			End If
		Next

	Else
		namedEntities = iLogicVb.Automation.GetNamedEntities(doc)
		Try
			partFace = namedEntities.FindEntity(faceName)
		Catch
			Return Nothing
		End Try


		' Get the face into the context of the assembly.
		Try
			occ.CreateGeometryProxy(partFace, partobj)
			drawViewCurves = drawView.DrawingCurves(partobj)
			drawCurve = drawViewCurves.Item(1)
		Catch
			Return Nothing
		End Try

		Return drawCurve
	End If

End Function

Only thing I haven't done is test with an iPart, but should work all the same.

 

Regards
 

Message 5 of 6

A.Acheson
Mentor
Mentor

Hi @lmc.engineering 

Thanks for the response. Getting as far as here and stopping. A mystery. 

If f2.ReferencedEntity Is partFace Then

AAcheson_0-1688156528406.png

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 6 of 6

A.Acheson
Mentor
Mentor
Accepted solution

So it seems the error was in the ipart where a face was modified later by a cut extrusion therefore converting the face into multiple faces. It is necessary to loop through reference entities and check the face there while also wrapping everything in a try catch for faces without multiple entities. Without it only suppressing the face allowed the face to be found without error.

AAcheson_0-1693101023546.png

AAcheson_1-1693101091795.png

 

 

' Work through either part or ipart looking for named faces then the curves. 
Function GetCurve(faceName As String, occ As ComponentOccurrence, drawView As DrawingView) As DrawingCurve
	  'https://modthemachine.typepad.com/my_weblog/2020/09/get-named-face-of-ipartfactory.html
	  Dim doc As PartDocument = occ.Definition.Document
	  Dim drawViewCurves As DrawingCurvesEnumerator
	  Dim drawCurve As DrawingCurve
	  Dim partFace As Face 
	  Dim partFaceProxy As FaceProxy
	 
	  If doc.ComponentDefinition.IsiPartMember Then

		  Dim factoryDoc As PartDocument = doc.ComponentDefinition.iPartMember.ReferencedDocumentDescriptor.ReferencedDocument
				  
		  Dim namedEntities As NamedEntities = iLogicVb.Automation.GetNamedEntities(factoryDoc)		
		 
		 Try
			partFace = namedEntities.FindEntity(faceName)
			Logger.Info(namedEntities.NameExists(faceName) &" - " & faceName)
		Catch
			Logger.Info("Error getting face entity")
			Return Nothing
		End Try
		
		  For Each f2 As Face In doc.ComponentDefinition.SurfaceBodies(1).Faces
				Try
					' Face we are looking for has been cut by a feature so will have more than one reference entity, 
					' So loop through the Collection
					For Each entity As Face In f2.ReferencedEntity
					
						If entity Is partFace Then 
							Logger.Info("Found Face")
							
							' Get the face into the context of the assembly
							occ.CreateGeometryProxy(f2, partFaceProxy)
			
							' Finds the drawing edge that represents the one with the named entity.
							Try
								drawViewCurves = drawView.DrawingCurves(partFaceProxy)
							Catch
								Logger.Info("Error getting DrawViewCurves")
							End Try
							Try
								drawCurve = drawViewCurves.Item(1)
							Catch
								Logger.Info("Error getting DrawViewCurve")
							End Try
			
							Return drawCurve
							Exit Function
							
						End If
					Next
				Catch
					Logger.Info("Error")
				End Try

			Next
	  End If
  
End Function

 

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan