Why are scripted redraws so sloooooowwww...?


#1

I have a medium complex mesh model - about 400K polys total with 500 different parts. My dynamic display is great - I can spin it as fast as I can move the mouse and no stuttering, TestMaxSpeed is 1.3 seconds for 100 redraws… (Quadro K2000)

Now, I want to rotate the model (not the camera) 360 degrees in 4 degree increments - so 90 rotations/redraws. The operation takes 5.2 seconds and there is noticeable stuttering; the speed of rotation is not constant.

Certainly, there is the actual calculation and transformation of the objects that adds to the load. To see how much that is, I cut the redraw and ran the script. It takes about 2.5 seconds. So if I remove that from the 5.2 second results, I get about 2.7 seconds left which should be the time used to to redraw the 90 rotations. That’s only half the rate that TestMaxSpeed gets. (And mouse tumbling is way faster than TestMaxSpeed, but I guess some display trickery is used to drop frames that are not needed…)

Why this is a problem: I’m scripting an animation in which I am rotating 300 different objects like the one above 360 degrees about their center, one by one… And the thing just bogs down tremendously. I cannot get a rotation speed as fast as I would like, but I am prepared to live with the 5 seconds per object…

What is a problem is that I cannot get smooth rotational movement out of it no matter how much I try. I need to use RhinoApp.Wait() to make sure it waits to redraw before doing the next rotate - otherwise it just freezes about halfway through, skips the last half of of the rotations and just finishes at the final position. But, as I said, the incremental rotations don’t all take the same time, so the movement is jumpy. I’ve tried to even it out by adding a dwell time after each rotation, but that is simply added after the RhinoApp.Wait(), so all it does is slow the unevenness down, not eliminate it.

It would be cool to use something like Bongo to do this, but I don’t know if it’s possible to program a rotation and then loop through it with 300 objects like you can with a script. So, any other way to insure that the redraws happen at a more constant rate?

I can provide some cooked-up samples (I can’t post the real stuff yet) if necessary…

–Mitch


#2

I’m not sure what TestMaxSpeed actually does to the scene, but rotating the view with the mouse in an ideal world just changes the world transformation that is applied to each vertex when it is drawn to screen. Since that world transformation should be entirely done inside the GPU and no data be modified, the framerate should be independent from the rotation and entirely depending on scene complexity.

Now if you are actually rotating the meshes, you need to apply another transformation to each vertex and maybe reupload the modified geometry to the GPU. You accounted for the modification but transfer and scene initialization may take additional time that is not necessary when only modifying the camera.

As for frame sync: you typically get the timer ticks(milliseconds) from entering the frame, then another time after finishing the calculation. Then you can calculate the ticks already spent and wait the rest of the given ticks per frame.


#3

Thanks for the insights HaLo…

Yeah, that’s what I was considering doing last night… It just seemed like a lot of overhead to add… :unamused:

–Mitch


#4

Considering the time spent transforming 400k polys, two calls to get the current timer shouldn’t be too much of an overhead.

The other way is to set up a timer thread, that checks on your calculation in constant intervals and starts the next frame of you’re done. That’s a little less overhead in your calculation routine and with most parts of rhino being single threaded, another thread should do no harm. But you will drop an entire frame if the calculation isn’t done in time.

Then again, the timing thread might check back in shorter intervals if the first deadline was not met, then continue in regular intervals after the longer frame is done.


#5

Yeah, just been checking this, the overhead is relatively small…

Most of the objects to be processed are not 400K polys, that was the “worst case scenario”, so I’m looking into reducing the poly count on the worst cases to help things along a bit…

Thanks, --Mitch


#6

The odd thing is, on the worst case scenario, the time it takes to calculate spikes periodically - which is what I’m seeing as jerky motion. In order to eliminate the spikes, I need to slow everything down to the the worst case… Below is a list of the time actually used to accomplish and redraw each rotation increment for 90 rotations - notice the repeating pattern of two successive rotations every 12 or so that take more than 3x the others, as well as the slowly increasing time for everything (+60% at the end) as the script rolls along… (sorry for the list length)

Curious, no?

0.0540390014648
0.0510330200195
0.0510482788086
0.183143615723
0.153099060059
0.0540313720703
0.0520248413086
0.0552597045898
0.056022644043
0.0570220947266
0.0580520629883
0.0550155639648
0.0610427856445
0.056037902832
0.193161010742
0.154098510742
0.0591354370117
0.0595092773438
0.0580444335938
0.0600433349609
0.0600433349609
0.0590515136719
0.0610427856445
0.0622406005859
0.0630416870117
0.199165344238
0.157112121582
0.0650405883789
0.0640487670898
0.0620422363281
0.0640487670898
0.0652160644531
0.0640640258789
0.0650863647461
0.066047668457
0.066047668457
0.196144104004
0.160118103027
0.066047668457
0.0671768188477
0.0681762695313
0.0678024291992
0.0680618286133
0.0690460205078
0.0720520019531
0.0700531005859
0.0700378417969
0.2021484375
0.164558410645
0.0710525512695
0.0730590820313
0.0713882446289
0.0720443725586
0.0724105834961
0.0730667114258
0.0737838745117
0.0710525512695
0.0750579833984
0.205307006836
0.172119140625
0.0770492553711
0.0770721435547
0.0750427246094
0.0762329101563
0.0770568847656
0.0770568847656
0.0790634155273
0.0770568847656
0.0790557861328
0.208168029785
0.173118591309
0.0790557861328
0.0810470581055
0.0810623168945
0.0800476074219
0.0800552368164
0.0840759277344
0.0820617675781
0.0820617675781
0.0832748413086
0.213157653809
0.17813873291
0.0850677490234
0.0850830078125
0.0840682983398
0.0860595703125
0.0850524902344
0.086067199707
0.107086181641
0.0870742797852


#7

That is weird. Are those figures with or without drawing?


#8

With… I start the timer before I run the rotation and stop it after RhinoApp.Wait() - which means it should wait until the redraw catches up. My feeling is it’s writing stuff to memory periodically or something… as the memory usage dramatically goes up as the script executes and I have to script ClearUndo after each 360° rotation. Just one of those makes the “idle” RAM usage go from around 275Mb to somewhere around 2Gb. If I don’t clear the Undo, in a few of those, my 16 Gigs are gone…

for i in range(90):
        tickStart=time.time()
        rs.RotateObjects(objs,orig,4.0,copy=False)
        Rhino.RhinoApp.Wait()
        print time.time()-tickStart

–Mitch


#9

That sounds like a memory management problem. Looks like the undo buffer is expanded in regular intervals. The memory allocation will take some time.

Any way to disable undo for your script?

That might sound ridiculous but how about ClearUndo every other step or so? Don’t know how rhino handles those calls but that might at least prevent the spiking. If the undo records are just invalidated in the undo buffer to be overwritten or garbage collected later on, that might even be of little to no impact.


#10

I don’t know if there is a scripted way to “suspend” the collection of undo - maybe I can just try temporarily allocating 0 undos and 0 memory to undo in Rhino General options… Nope, doesn’t help…

Tried that too, no help, same results…

–Mitch


#11

Yeah I’ve read here that Bongo itself has to do some convoluted hacks to avoid this exact thing.


#12

Hi Mitch, I just updatet Rhino to the latest SR and I get this same jaggyness. Spins, pauses, spins, pauses and so on.
I noticed as rotating a scene with 1000 cubes had this laggy navigation, so I tested testmaxspeed and saw the same there. The lag appears about every second.

My system has never been like this before.
Win7 Quadro 4000.


#13

And a dual reboot fixed that again.