Author Topic: Force animated Corona Proxy to display as mesh instead of box  (Read 3360 times)

2023-07-19, 10:51:18

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Hi. As per the title, is there a way to force Corona Proxys to display as a mesh instead of the box that appears (which I know is to maintain viewport performance)? So that we're able to do viewport animation previews? And can this be automated with maxscript for example?  What is the mechanism that tells the proxy to stop needing to display the box and show the mesh again? Is it simply a time delay per frame?  Is it an fps requirement? Or something else?

I'm currently trying to write a tool with maxscript to automate the creation of animated viewport previews to mp4 instead of avi, and theorised that I could iterate through the timeline and save each frame as a still image and then get that image sequence converted to the mp4.  I've tried doing forceRedraw(), as well as disable and enableSceneRedraw() in tandem with a time delay hoping this would allow the proxy to revert to a mesh again before the next frame is captured. None of these things have worked so far.

So is anyone able to give some incite into this?

Thanks in advance for the help.

2023-07-19, 12:19:46
Reply #1

Avi

  • Corona Team
  • Active Users
  • ****
  • Posts: 796
    • View Profile
Try this

Code: [Select]
for obj in objects where classof obj == CProxy do (
    obj.previzType = 3
)
redrawViews()
Arpit Pandey | chaos-corona.com
3D Support Specialist - Corona | contact us

2023-07-19, 12:35:18
Reply #2

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Hi Avi.  Thanks for the reply. I just tried your suggestion and it still resulted in a box being used for the preview unfortunately.  I had actually already tried this, as well as setting the proxy back to something other than a mesh, and then back to a mesh on each frame to see if that would kick start it, but that also didn't work.

I think that there's something going on under the hood that's telling the proxy to go into performance mode, and revert the mesh to a box to maintain viewport performance.

Under normal circumstances that would be fine, if I'm just navigating the viewport, but in this instance I'm trying to get an animation preview of the scene, so need to be able to see the mesh animation from the proxy otherwise it's worthless.

Are you able to find out what it is that's telling the proxy to switch between mesh and this performance mode to see if it can be subverted via maxscript?

Thanks in advance for the help.

2023-07-21, 11:33:04
Reply #3

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Morning. Any further thoughts on this?  I've now also tried simulating a left mouse button click randomly in the 3ds max window to see if that simulated user interaction would work, but this also fails. Would appreciate some insight from devs, or anyone in the know, as to what interaction causes the proxy to switch between mesh and the "performance" box.  Otherwise I guess I'll just have to keep throwing ideas at the wall to see if anything sticks....

2023-07-21, 13:07:37
Reply #4

Aram Avetisyan

  • Corona Team
  • Active Users
  • ****
  • Posts: 909
    • View Profile
Hi. As per the title, is there a way to force Corona Proxys to display as a mesh instead of the box that appears (which I know is to maintain viewport performance)? So that we're able to do viewport animation previews? And can this be automated with maxscript for example?  What is the mechanism that tells the proxy to stop needing to display the box and show the mesh again? Is it simply a time delay per frame?  Is it an fps requirement? Or something else?

I'm currently trying to write a tool with maxscript to automate the creation of animated viewport previews to mp4 instead of avi, and theorised that I could iterate through the timeline and save each frame as a still image and then get that image sequence converted to the mp4.  I've tried doing forceRedraw(), as well as disable and enableSceneRedraw() in tandem with a time delay hoping this would allow the proxy to revert to a mesh again before the next frame is captured. None of these things have worked so far.

So is anyone able to give some incite into this?

Thanks in advance for the help.

Hi,

This has been reported already.
You can check this thread: https://forum.corona-renderer.com/index.php?topic=39419

Unfortunately this is a drawback of faster/asynchronous loading of proxies.
Aram Avetisyan | chaos-corona.com
Chaos Corona QA Specialist | contact us

2023-07-21, 13:49:15
Reply #5

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Hi Aram. Yes I'd seen the other posts about this thanks and was aware that it was due to the change to asynchronous loading with corona 7.  What I'd ideally like to know is what is telling the proxy to change back to displaying the full mesh as nothing I've tried as outlined above seems to have worked.  Something must trigger it somewhere otherwise how does it know to change at all?

2023-07-21, 19:57:06
Reply #6

Aram Avetisyan

  • Corona Team
  • Active Users
  • ****
  • Posts: 909
    • View Profile
I am not sure what exactly are you doing and how exactly you try to do it, but as I understand, you need to do the Tools > Preview - Grab Viewport > Create Preview animation with a custom delay, so CoronaProxies are able to "refresh" themselves and be previewed as full mesh, right?

In this case the algorithm should be:
• Move to next frame
• Wait till CoronaProxy loads preview, or make it load, depending on how the script works
• Grab the screen
• Repeat

Not sure how forceRedraw() and enableSceneRedraw() work in regards to CoronaProxy, but I will ask these questions to devs and if there is a reply I will get back to you.
Aram Avetisyan | chaos-corona.com
Chaos Corona QA Specialist | contact us

2023-07-21, 21:02:18
Reply #7

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Hi Aram

Yes that's all correct.  I've tried waiting for several seconds before trying to capture the next frame but this doesn't appear to work so far, so any insight you can get from the devs would be much appreciated.  I can upload the script but it's gone through several iterations, trying several different approaches, so it's quite messy at the moment. Let me know if you think it would be helpful though.

Thanks in advance.
« Last Edit: 2023-07-21, 21:09:35 by cherrypicker »

2023-07-24, 10:22:47
Reply #8

Aram Avetisyan

  • Corona Team
  • Active Users
  • ****
  • Posts: 909
    • View Profile
Yes, the script will be helpful.
At least as a starting point or for fixing it.
You can upload it here or send as a ticket here.
Aram Avetisyan | chaos-corona.com
Chaos Corona QA Specialist | contact us

2023-07-24, 16:24:47
Reply #9

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Hi Aram

I've tidied up and collated the latest version of the script below.  I've removed all the rollout elements and things, so hopefully I've not missed anything.  Currently the script is waiting for 0.1s, then simulating a left click in the viewport, running a complete redraw and then capturing the next preview frame.

Thanks

fname = getFilenameFile(maxFileName)
previewFolder = (GetDir #preview) + "\\MP4 Previews\\" + fname + "\\"
if (doesDirectoryExist previewFolder == false) do (makeDir previewFolder)

function makeParam LoWord HiWord =
(
bit.or (bit.shift HiWord 16) (bit.and LoWord 0xFFFF)
)

function LeftMouseButtonClick x y =
(
   WM_LBUTTONDOWN = 0x0201
   WM_LBUTTONUP    = 0x0202      
   MK_LBUTTON = 0x0001

   stopLoop = false
   hwnd = undefined
   for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" while stopLoop == false do
   (
      hwnd = w[1]
      stopLoop = true            
   )
   hwnd = (windows.getChildrenHWND hwnd)[1][1]
   p0 = makeParam x y

   windows.postmessage  hwnd WM_LBUTTONDOWN 0 p0
   windows.postmessage  hwnd WM_LBUTTONUP 0 p0
   format "Clicked % %!\n" x y
)

version = 001
if (viewport.getType() == #view_camera) then
(
   cam = viewport.getCamera()
   preview_name = previewFolder + fname + "_" + cam.name + "_v" + (formattedPrint version format:"03d") + ".avi"
)

else (preview_name = previewFolder + fname + ".jpg")
resWidth = renderWidth
resHeight = renderHeight
fstart = animationrange.start
fend = animationrange.end
count = fstart as integer
sliderTime = fstart
for t = fstart to fend do
(
   strNum = count as string
   if strNum.count < 4 then
   (
      str = ""
      for i=1 to (4 - strNum.count) do (str += "0")
      strNum = str + strNum
   )
   else (strNum = strNum)
   local preview_name = previewFolder + fname + "_" + strNum + ".jpg"
   local anim_bmp = bitmap resWidth resHeight filename:preview_name
   local targetTime = timeStamp() + (0.1s).ticks
   while timeStamp() < targetTime do ()
   LeftMouseButtonClick (random 200 800) (random 200 800)
   CompleteRedraw()
   dib = gw.getViewportDib()
   copy dib anim_bmp
   save anim_bmp
   close anim_bmp   
   count += 1
   sliderTime += 1
)

2023-07-27, 11:53:08
Reply #10

Aram Avetisyan

  • Corona Team
  • Active Users
  • ****
  • Posts: 909
    • View Profile
Hi,

Sorry for the delay, we were experimenting with scripts around.
I think the script can be simplfied to:

Code: [Select]
sliderTime = 0

while sliderTime as string != "10f" do
(
bmpFilePath = (maxfilepath + "images\\" + getFileNameFile maxfilename + "_" +(sliderTime as string) + ".jpg")
vptGrabBMP = gw.getViewportDib()
vptGrabBMP.filename = bmpFilePath
save vptGrabBMP
sliderTime += 1
)

We just need to figure out how to add a "wait" after sliderTime +=1, so the proxy preview is updated.

The sliderTime = 0 is the starting frame for the animation, the one in the while loop is for the end frame.
This works pretty fast but the delay/wait/sleep part is still unknown how to implement.
« Last Edit: 2023-07-27, 12:59:53 by Aram Avetisyan »
Aram Avetisyan | chaos-corona.com
Chaos Corona QA Specialist | contact us

2023-07-27, 14:01:21
Reply #11

Frood

  • Active Users
  • **
  • Posts: 2002
    • View Profile
    • Rakete GmbH
Hi Aram,

try to use those as the first two lines in the loop:

Code: [Select]
sleep(2)
windows.processPostedMessages()

Usually you'd have to work with threads/background workers/timers because the UI is locked if you just execute the code without creating a new thread, this is a simple option that works often enough.


Good Luck



Never underestimate the power of a well placed level one spell.

2023-07-27, 17:49:32
Reply #12

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Amazing thanks Aram and Frood. I seem to have a working script now.  Tested dropping the sleep down all the way to 0.01 for a speedier preview, but I anticipate this scaling with scene complexity. Will test. Thanks again for the help getting this workaround working.  If a future corona update could avoid the need for a workaround though that would be good too :-)
« Last Edit: 2023-07-28, 13:11:14 by cherrypicker »

2023-07-29, 12:47:45
Reply #13

Aram Avetisyan

  • Corona Team
  • Active Users
  • ****
  • Posts: 909
    • View Profile
Amazing thanks Aram and Frood. I seem to have a working script now.  Tested dropping the sleep down all the way to 0.01 for a speedier preview, but I anticipate this scaling with scene complexity. Will test. Thanks again for the help getting this workaround working.  If a future corona update could avoid the need for a workaround though that would be good too :-)

Glad to hear that!

I don't think this will be addressed on Corona side in future, as with asynchronous loading you get much more significant improvement (much faster loading times and not only) in contrast to Viewport Grab/Animation Preview, which is not used that much or is not of that much importance as the other things coming with asynchronous loading.
I think the workaround is very good and viable - you get the frames and can even "preview" the animation by a photo viewer by quickly going over the frames (of course you can compile them to a video file further on if needed). Thanks Frood for the input!

So the final maxscript code for a viewport grab/Animation preivew will be:
Code: [Select]
sliderTime = 0

while sliderTime as string != "10f" do
(
--sleep(0.2)
windows.processPostedMessages()
bmpFilePath = (maxfilepath + "images\\" + getFileNameFile maxfilename + "_" +(sliderTime as string) + ".jpg")
vptGrabBMP = gw.getViewportDib()
vptGrabBMP.filename = bmpFilePath
save vptGrabBMP
sliderTime += 1
)

• "sliderTime = 0" is the starting frame for the animation. "sliderTime = 1f" will be for the 1st frame, "sliderTime = 10f" will be for 10th frame etc.
• "10f" in the while loop is the final frame for the animation, change it accordingly if needed (e.g. "5f" for until 5th, "200f" for until 200th frame is reached)
• "bmpFilePath =" is for defining the output path and format, the arguments are self explanatory
• "--sleep(0.2)" is commented out. Remove the leading "--" to make sleep work, start with low values of 0.1, 0.2 and increase it until enough time delay is reached for updating the proxy preview, depending on the scene/viewport complexity.

Can be shared in Corona Goodies/User contributions as well.
Aram Avetisyan | chaos-corona.com
Chaos Corona QA Specialist | contact us

2023-07-29, 16:29:27
Reply #14

cherrypicker

  • Active Users
  • **
  • Posts: 9
    • View Profile
Indeed thanks Aram. One thing to note is that this captures the entire viewport, so differs to the usual create preview (which doesn't work with animated corona proxy), which only captures the space within safe frames which is what you typically want when doing a playblast, so some additional scripting is needed to crop down to this.