Extremely slow performance checking drawing view is up to date.

Extremely slow performance checking drawing view is up to date.

matt_jlt
Collaborator Collaborator
2,123 Views
9 Replies
Message 1 of 10

Extremely slow performance checking drawing view is up to date.

matt_jlt
Collaborator
Collaborator

I have a problem where this particular piece of code takes a really long time to run on some large drawings. For example, on idw drawings that are 200MB >1000MB in filesize.

 

I run this code before exporting a drawing to make sure we don't get any raster views in our automated PDF export tool. The issue is that even if all of the drawing views are up to date, and i can export the PDF just fine manually, if this code runs, it takes really long to go through each view. Like 2-5 minutes per view and more. and on a drawing with 30 views this is a really long time. And i know that the drawing is very large, but it doesnt makes sense that each view takes that long to check if its up to date.

 

If you want to see a full example of the print code it is here
https://github.com/mattjlt/Inventor-Code-Library/blob/master/Scripts/DRG_Export_PDF%20%2B%20DXF.iLog...

 

The section in particular is the "Do While oView.IsUpdateComplete = False"

I think something is happening that makes it get stuck / loop unnecessarily.

 

Any help is be appreciated. Even if you have a more efficient way to check that the views are all up to date / not raster and ready for PDF + DXF export.

 

Thanks, Matt.

 

Function UpdateAllViews(ByRef oDoc As DrawingDocument) As Boolean
	' Update application status bar for user to monitor progress
	ThisApplication.StatusBarText = "Updating drawing views"
	
	' Make sure there are no raster views, not going to use as unsure if it is efficient as checking all views separately
	'oDoc.MakeAllViewsPrecise()

	' Ensure all views are updated before printing, this prevents raster view printouts on large assemblies
	For Each oSheet As Inventor.Sheet In oDoc.Sheets ' Iterate through all sheets

	    ' This was on a couple of drawings where someone mistakenly selected this
	    ' Check if sheet is excluded from count but is being printed aswell, add it back to the count to prevent export sheet number issues
	    If oSheet.ExcludeFromCount = True AndAlso oSheet.ExcludeFromPrinting = False Then
	        ' Add sheet back into count
	        oSheet.ExcludeFromCount = False
	    End If
		
		' Iterate through all drawing views
	    For Each oView In oSheet.DrawingViews
	        ThisApplication.StatusBarText = "Checking if view is raster"
	        If oView.IsRasterView Then ' Check if view is raster
	            ThisApplication.StatusBarText = "View is raster so changing to precise"
	            oView.IsRasterView = False ' Set view to precise / not a raster
	        End If

	        ' Wait for view to update
	        ThisApplication.StatusBarText = "Checking if view is updated"
	        Do While oView.IsUpdateComplete = False
	            Wait_Inventor(1) ' Just wait for one second, don't do anything
	            ThisApplication.StatusBarText = "Updating drawing views"
	        Loop
	    Next
	Next

	ThisApplication.StatusBarText = "Drawing views updated"
	
	' Succeeded, return true
	Return True
	
End Function

Public Sub Wait_Inventor(ByVal seconds As Integer)
    For i As Integer = 0 To seconds * 100
        System.Threading.Thread.Sleep(10)
        ThisApplication.UserInterfaceManager.DoEvents() ' Inventor do events
    Next
End Sub

 

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

bradeneuropeArthur
Mentor
Mentor
Accepted solution

Would this help?

 

 

' Iterate through all drawing views
	    For Each oView As Inventor.DrawingView In oSheet.DrawingViews
			If oView.UpToDate = False
	        ThisApplication.StatusBarText = "Checking if view is raster"
	        If oView.IsRasterView Then ' Check if view is raster
	            ThisApplication.StatusBarText = "View is raster so changing to precise"
	            oView.IsRasterView = False ' Set view to precise / not a raster
	        End If

	        ' Wait for view to update
	        ThisApplication.StatusBarText = "Checking if view is updated"
	        Do While oView.IsUpdateComplete = False
	            Wait_Inventor(1) ' Just wait for one second, don't do anything
	            ThisApplication.StatusBarText = "Updating drawing views"
	        Loop
		End If

 

 

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

Message 3 of 10

g.georgiades
Advocate
Advocate
Accepted solution

Can you confirm that the sleep line

  System.Threading.Thread.Sleep(10)

 

is not interfering with the main thread execution? Does its inclusion/exclusion affect anything?

 

Can you put a timer around the while loop to see how long it takes to evaluate each view?

 

Definitely put in the DrawingView cast that brad included in his code snippet to eliminate the late binding calls in the for loop. Actually every call to oView.IsUpadteComplete in while loop is a late bind call so that can consume a ton of time.

 
 
Message 4 of 10

matt_jlt
Collaborator
Collaborator

Thanks for your help.

Do you have an example of a timer i could use? I found so many different types of timers, some notes on them said they also affect performance, not 100% sure on which to use.

 

I didn't even realise there was a properly called ".UpToDate". I added that into my code, but I didn't nest the raster check into the "If" function. I added it just below the raster section and it has definitely increased performance significantly. I guess the "IsUpdateCompleted" property doesn't necessarily mean a view isn't up to date.

I have also added a timeout function so it doesn't ever get stuck in an endless loop just in case.

With regard to setting the object type / cast, not sure why my github script didnt have it and my local copy did, but thanks for that pickup aswell. I also didnt know it had that much of a performance impact.
Thankyou both.

I still want to test out the difference of having the 1 second wait with timer just to check the difference.

0 Likes
Message 5 of 10

Ralf_Krieg
Advisor
Advisor

Hello

 

Would it be an option to use the DrawingDocument.MakeAllViewsPrecise()  method instead of iterating through all sheets and views manually? I think this method would use the multithreaded drawing views update and should hopefully increase performance. And it should "stop" your code until finished, so you don't have to check if update is finished or not.


R. Krieg
RKW Solutions
www.rkw-solutions.com
Message 6 of 10

matt_jlt
Collaborator
Collaborator

I have that commented out in my code, I was under the assumption that it tries to set all views to be precise, instead of checking first and only setting it if needed.

 

As there really isn't any good explanation on how the function works that I could find, i had my code iterate through each view and check first; i thought it would have been quicker.

 

With the checking for update comment, I have had a few instances where the view wasnt finished updating completely and failed on DXF export aswell as left raster views. the only way around it that i found was to check each view.

 

Your Point of multi-threaded performance increase makes sense, I might give it a try. I don't know how i would exactly measure the increase in performance though, I would have to run a test of some sort.

 

Ideally I want to get this printing script as efficient as possible and i'll leave it on github so anyone can use it.

 

Thanks again for your help.

0 Likes
Message 7 of 10

g.georgiades
Advocate
Advocate
I typically use StopWatch for my timers, but you can also just compare using DateTime.Now. I am not sure if there will be a significant performance impact or if it will matter much since you mentioned these are massive views. you can always run with the same views/code a few times to gauge how different the times are.

As for the MakeAllViewsPrecise function; Inventor is mostly single threaded, so I wouldn't be surprised if it was faking mulithreading in some way. You will just have to test it I guess. A possible/dirty test could be to look at the task manager cpu thread graph and see if more than one spikes while running it.

A note for your sleep waiting. iLogic rules essentially execute in the main thread of inventor (or just pause it until the iLogic is finished), its why you can freeze inventor so easily using iLogic. Inventor has a builtin trick to partially pass execution back called DoEvents(). That means any calls to System.Threading.Thread.Sleep() inside an iLogic rule will essentially freeze the main thread of inventor. Having the DoEvents right after this call will process inventor, but then inventor will freeze again for that time. When in an iLogic Rule, DoEvents is the only way inventor's main thread will run, so its best to let it run uninterrupted. You can actually see this happen by setting a test with an infinite? loop and a long sleep. As you move the mouse around, inventor will be sluggish to highlight items, buttons, etc. In fact inventor's own sample code for interaction events does not sleep. So if view un-rasterization is not truly multithreaded, then your sleep code is most likely slowing it down. It seems your intention is to reduce calls since the views take a while to process. If the views have to phone-home in any way, then they have to wait for your DoEvents to be called.

Since your goal is max efficiency, although unlikely, ThisApplication.ScreenUpdating = False might speed it up some? Just don't forget to set it back to true.
0 Likes
Message 8 of 10

matt_jlt
Collaborator
Collaborator

Thanks for the info, i didn't even think about it locking up the main thread. As most of my code are addins except this one, i have used it previously and mistakenly assumed it had the same functionality in iLogic.

 

Would you have another recommendation for me to have a time-out feature. The only thing i want to do is make sure it doesn't get stuck in an endless loop. If i added a timer, would it ne doing the same as a thread sleep?

 

With the ScreenUpdating, i typically try to avoid using this, purely because i have had crashes in the past where screenupdating was set to false, then it got stuck there and the user had to crash the program / losing any file progress.

 

Thanks, Matt.

 

0 Likes
Message 9 of 10

g.georgiades
Advocate
Advocate

Addins can see the same issues with looping and sleeping, but they do seem to be handled a bit differently, especially exceptions.

 

As for timeouts - thread sleep calls are definitely worse than just checking a timer value or datetime.now. Though I encourage you to test this! Ideally you'd want to use waithandles/events over anything else... but that would get into multi-threading which is not the most stable in inventor and causes buggy execution and crashes in my experience.

 

When I say timeout - I only mean it as insurance that the infinite loop will stop. the inner loop code should still run unabated. and with as few operations as possible. There is no getting around the time it takes to query the CPU for the current time, but there is no better option that is not event driven.

While actioncomplete = false orelse timer < 2 minutes
  DoEvents()
End While

Here is a posting praising stopwatch over datetime which I agree with.

https://stackoverflow.com/questions/6986147/net-stopwatch-performance-penalty

 

Side note: does the drawing view event OnViewUpdate have any use in this context? - if the view is not up to date and you call to update it, does this event fire on completion?

https://help.autodesk.com/view/INVNTOR/2022/ENU/?guid=GUID-F258B6DB-A66A-4C44-8EB6-527BC19AECCA

 

As for screenupdating, like transactions, make sure to wrap everything into try/finally to ensure it gets handled properly.

Message 10 of 10

matt_jlt
Collaborator
Collaborator

I ended up using a stopwatch and checking time elapsed as a safe-guard against an endless loop. Thankyou again for your assistance.

0 Likes