Get Bounding Box Dimensions on Drawing Part

Get Bounding Box Dimensions on Drawing Part

C_Haines_ENG
Collaborator Collaborator
1,683 Views
9 Replies
Message 1 of 10

Get Bounding Box Dimensions on Drawing Part

C_Haines_ENG
Collaborator
Collaborator

Good morning,

 

I was wondering if its possible to use the bounding box rule on drawing views, to get their overall sizes.

 

Id ideally like to do this without opening the part file thats being used in the document

 

 

 

 

0 Likes
Accepted solutions (1)
1,684 Views
9 Replies
Replies (9)
Message 2 of 10

WCrihfield
Mentor
Mentor

Hi @C_Haines_ENG.  I am not sure what you are planning on doing with that information once you get it, but here is an iLogic rule you can review that might help you towards achieving your goals.  The alternative would be to just get the DrawingView.Width & DrawingView.Height properties.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Return
	Dim oView As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select a view.")
	If oView Is Nothing Then Return
	Dim oViewBox As Box2d = GetViewGeomBox2d(oView)
	If oViewBox Is Nothing Then Return
	Dim dWidth As Double = oViewBox.MaxPoint.X - oViewBox.MinPoint.X
	Dim dHeight As Double = oViewBox.MaxPoint.Y - oViewBox.MinPoint.Y
	Logger.Info("View Geometry Bounding Box Size:  " & dWidth & " x " & dHeight)
End Sub

Function GetViewGeomBox2d(oView As DrawingView) As Box2d
	If oView Is Nothing Then Return Nothing
	Dim oDCE As DrawingCurvesEnumerator = Nothing
	Try : oDCE = oView.DrawingCurves : Catch : End Try
	If oDCE Is Nothing OrElse oDCE.Count = 0 Then Return Nothing
	Dim dMinPointX As Double = oView.Left + oView.Width
	Dim dMinPointY As Double = oView.Top
	Dim dMaxPointX As Double = oView.Left
	Dim dMaxPointY As Double = oView.Top - oView.Height
	For Each oDC As DrawingCurve In oDCE
		Dim dMinParam, dMaxParam As Double
		oDC.Evaluator2D.GetParamExtents(dMinParam, dMaxParam)
		Dim oParams() As Double = {dMinParam, dMaxParam}
		Dim oPointCoords() As Double = {}
		oDC.Evaluator2D.GetPointAtParam(oParams, oPointCoords)
		If oPointCoords(0) < dMinPointX Then
			dMinPointX = oPointCoords(0)
		ElseIf oPointCoords(0) > dMaxPointX Then
			dMaxPointX = oPointCoords(0)
		End If
		If oPointCoords(1) < dMinPointY Then
			dMinPointY = oPointCoords(1)
		ElseIf oPointCoords(1) > dMaxPointY Then
			dMaxPointY = oPointCoords(1)
		End If
	Next
	Dim oBox2d As Box2d = ThisApplication.TransientGeometry.CreateBox2d
	oBox2d.PutBoxData({dMinPointX, dMinPointY}, {dMaxPointX, dMaxPointY})
	Return oBox2d
End Function

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 10

WCrihfield
Mentor
Mentor

The example above writes the results to the iLogic Log window, and the units are in database units (centimeters), instead of document units, and the view's scale is not taken into consideration either.  If you would like to further refine the numerical size results, you could modify the 'Main' routine like this:

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then Return
	Dim oView As DrawingView = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select a view.")
	If oView Is Nothing Then Return
	Dim oViewBox As Box2d = GetViewGeomBox2d(oView)
	If oViewBox Is Nothing Then Return
	Dim dWidth As Double = oViewBox.MaxPoint.X - oViewBox.MinPoint.X
	Dim dHeight As Double = oViewBox.MaxPoint.Y - oViewBox.MinPoint.Y
	'adjust for view scale to get 'actual size' results
	dWidth = IIf (oView.Scale > 1, dWidth * oView.Scale, dWidth / oView.Scale)
	dHeight = IIf (oView.Scale > 1, dHeight * oView.Scale, dHeight / oView.Scale)
	'convert units from database units (centimeters) to document units
	Dim UOM As UnitsOfMeasure = ThisDoc.Document.UnitsOfMeasure
	dWidth = UOM.ConvertUnits(dWidth, UnitsTypeEnum.kDatabaseLengthUnits, UOM.LengthUnits)
	dHeight = UOM.ConvertUnits(dHeight, UnitsTypeEnum.kDatabaseLengthUnits, UOM.LengthUnits)
	Logger.Info("View Geometry Bounding Box Size:  " & dWidth & " x " & dHeight)
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 10

C_Haines_ENG
Collaborator
Collaborator

My program is calculating the thickness of a panel, be that in an assembly or part file.

 

This rule will only work If I can select the side profile every time, and my program runs through 10-20 drawings at a time so selecting every single side profile view may be a worse solution to what I already have.


At the momment I have a program looping through all dimensions and seeing if it can find one that matches a database of possible panel thicknesses. This often fails on new panel thicknesses and makes adding new panel types very tedious. 

0 Likes
Message 5 of 10

C_Haines_ENG
Collaborator
Collaborator

My Main concern is that I HAVE to select the drawing view to use every time, is there a way to get the X Y and Z extents of the referenced part or assem file?

 

I dont think it will be possible to automate getting a side view every time, or maybe I can have it loop through all views and just grab the smallest value...

0 Likes
Message 6 of 10

WCrihfield
Mentor
Mentor

OK.  That sounds a bit more complicated than what I was thinking about.  The 'Pick' method was to allow a quick way to test the rest of the code.  Some of the code in the last part of the Sub Main block, could be moved down into the custom Function, then the Function could be changed to return a different Type of output.  It could return an Array of Double, List(Of Double), String, or something else.  If your drawing documents have one component per sheet, and maybe multiple views per sheet (front, top, right, ISO) of that same component, then the routine that calls the custom Function to run could maybe loop through all the views on each sheet using that function to gather sizes to then get  the minimum overall measurement of all the views on the sheet, then if the panel thickness is always less than its length & width, you would have the panel thickness of the component on that sheet.  Just a thought, but it does seem like too much processing for a 'batch' type process of that many drawings.

Edit:  Posted before seeing you last response.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 10

WCrihfield
Mentor
Mentor

Yes, we could definitely get the bounding box of the referenced model the more traditional way, but that would require accessing that referenced model file directly by code, instead of just the view's geometry.  The model is most likely already technically 'open' in the background anyways (not necessarily visible, not necessarily going to see a document tab for it), because that happens automatically every time you open assemblies or drawings.  That also takes some processing effort though, even though it may seem like less code.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 10

C_Haines_ENG
Collaborator
Collaborator

I managed to figure out the confusing part from your original code:

 

 

Sub Main
	
Dim oDrawingDoc As DrawingDocument
oDrawingDoc = ThisApplication.ActiveDocument
Dim oSheet As Sheet
oSheet = oDrawingDoc.ActiveSheet
For Each oSheet In oDrawingDoc.Sheets
	oViews = oSheet.DrawingViews
	Dim oView As DrawingView
	For Each oView In oViews
		
		Dim dViewWidth As Double = Round(oView.Width * (10 / oView.Scale),2)
		Dim dViewHeight As Double = Round(oView.Height * (10 / oView.Scale),2)
		
		MessageBox.Show(dViewWidth & "    " & dViewHeight, "Title")
		
	Next
	
Next

End Sub

 

Is there a more efficient way to extract the smallest value, like having them all add into an array and then just grab the smallest value? Id like to avoid endless comparisions.

 

0 Likes
Message 9 of 10

WCrihfield
Mentor
Mentor

Yes.  If you add each Double to a List(Of Double), then use its Sort method, the Doubles will naturally be sorted from smallest (at top/first) to largest (at bottom/last).  Another simple way to compare multiple Doubles at once, and return the smallest of them is the 'MinOfMany' method.

Edit:  Added example below of that last one:

Dim A As Double = 2.3
Dim B As Double = 5.8
Dim C As Double = 1.9
Dim D As Double = MinOfMany(A, B, C)
MsgBox("D = " & D,,"")

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 10

C_Haines_ENG
Collaborator
Collaborator
Accepted solution

Nevermind simple comparison was found im a little slow today, mondays I guess. Thanks for the stellar and quick help as always!

 

 

Sub Main
	
Dim oDrawingDoc As DrawingDocument = ThisApplication.ActiveDocument
Dim oSheet As Sheet = oDrawingDoc.ActiveSheet
Dim PanelT As Double = 1000000

For Each oSheet In oDrawingDoc.Sheets
	oViews = oSheet.DrawingViews
	Dim oView As DrawingView
	For Each oView In oViews
		
		Dim ViewWidth As Double = Round(oView.Width * (10 / oView.Scale),2)
		Dim ViewHeight As Double = Round(oView.Height * (10 / oView.Scale),2)
		
		If ViewWidth < ViewHeight And PanelT
			PanelT = ViewWidth
		ElseIf ViewHeight < ViewWidth And PanelT
			PanelT = ViewHeight
		End If
		
	Next
	
Next

MessageBox.Show(PanelT, "Title")

End Sub

 

0 Likes