macroScript ViewportGrabber category:"Piranha-Bytes" buttonText:"VPGrab" toolTip:"Viewport Grabber" ( /**********************************************************************************/ /* */ /* Viewport Grabber by Andre Hotz @ Piranha-Bytes */ /* */ /* */ /* Description: */ /* */ /* Grabs active Viewport and saves it to disk */ /* */ /* */ /* Options: */ /* */ /* Grab FPS: The Grabbing speed in frames per second */ /* */ /* AutoGrab: When checked, every time you change something in the viewport, */ /* it will be grabbed */ /* */ /* Capture MouseBt: Enables/Disables capturing while a mousebutton is pressed */ /* */ /* Save as: Specify a filename, path and imagetype for grabbing */ /* */ /* Start Grabbing: Starts the timer for grabbing */ /* */ /* Output Options: */ /* */ /* Get Size From View: Sets the output resolution to current Viewport Size */ /* */ /* X, Y: Set output resolution */ /* */ /* Add Mousepointer: Adds a white Crosshair Mousepointer to the output image */ /* */ /* */ /* Install: Put ViewPortGrabber.mcr into \ui\macroscripts\, restart 3DSMax, */ /* Goto Customize->Customize User Interface->Toolbars */ /* Select Category "ViewportGrabber" and drag it to your toolbar */ /* */ /* */ /* Use at your own risk !!! */ /* */ /* andre@piranha-bytes.com */ /* www.gothic2.com */ /**********************************************************************************/ global saveName = undefined global saveType = undefined global mbCapture = #{1,2,3} global vpGrab = undefined global ro_VPGrabber global addCross, saveRedraw global addPointer = false global grab_pause = false, grab_start = false, grab_change = true local capX = 320, capY = 240 function addCross = ( winX = gw.getWinSizeX() winY = gw.getWinSizeY() wi = vpGrab.width he = vpGrab.height xp = mouse.pos[1] * ((wi as float) / (winx as float)) yp = mouse.pos[2] * ((he as float) / (winy as float)) nsx = sizex = 30 nsy = sizey = 30 xp = xp - (sizex/2) if ((xp > 0) and (yp > 0)) do ( if ((xp+sizex) > wi) then nsx = sizex - (xp+sizex-wi) if ((yp+(sizey/2)) > he) then nsy = sizey - (yp+(sizey/2)-he) plist = #() for c=1 to nsx do append plist white setpixels vpGrab [xp,yp] plist for c=1 to nsy do setpixels vpGrab [xp+(sizex/2),(yp-(sizey/2))+c] #(white) ) ) function saveRedraw = ( if ((grab_start == true) and (grab_pause == false) and (grab_change == true)) do ( mb = mouse.buttonstates if ((mbCapture[1] == false and mb[1] == true) or (mbCapture[2] == false and mb[2] == true) or (mbCapture[3] == false and mb[3] == true)) == FALSE then ( ro_VPGrabber.grabTimer.ticks += 1 t = ro_VPGrabber.grabTimer.ticks as string ro_VPGrabber.lbl_Frames.caption = "Frames: " + t ro_VPGrabber.lbl_Frames.pos = [75,55] newVP = gw.getViewportDib() copy newVP vpGrab if addPointer then addCross() if ((savetype != ".avi") AND (savetype != ".mov") AND (savetype != ".mpg") AND (savetype != ".mpeg")) do ( addzeros = 5 - t.count zeroString = "" for z=1 to addzeros do append zeroString "0" vpGrab.filename = saveName + "_" + zeroString + t + saveType ) save vpGrab ) ) ) rollout ro_ChangeCapSize "Output Options:" ( button ui_UseFromVP "Get Size from View" pos:[5,5] width:117 height:20 tooltip:"Get the output size from current active Viewport" spinner ui_SizeX "X:" pos:[5,30] fieldwidth:35 scale:1 type:#integer range:[1,9999,capX] spinner ui_SizeY "Y:" pos:[65,30] fieldwidth:35 scale:1 type:#integer range:[1,9999,capY] checkbox ui_AddPointer "Add Mousepointer" pos:[5,55] checked:addPointer tooltip:"Add a Crosshair Mousepointer to output images" on ui_UseFromVP pressed do ( capX = gw.getWinSizeX() capY = gw.getWinSizeY() ui_SizeX.value = capX ui_SizeY.value = capY ) on ui_SizeX changed val do capX = val on ui_SizeY changed val do capY = val on ui_Addpointer changed state do addpointer = state ) rollout ro_VPGrabber "pb Viewport Grabber" ( spinner ui_Interval "Grab FPS:" pos:[5,10] fieldwidth:25 range:[0,50,1] scale:1 type:#integer checkbutton ui_GrabChanges "AutoGrab" pos:[95,10] width:55 height:16 checked:true tooltip:"AutoGrab every Viewport Change" label lbl_MouseCapture "Capture MouseBt:" pos:[5,32] checkbutton ui_CaptureLMB "L" pos:[95,30] width:16 height:16 checked:mbCapture[1] tooltip:"Capture while Left Mousebutton is down" checkbutton ui_CaptureMMB "M" pos:[115,30] width:16 height:16 checked:mbCapture[2] tooltip:"Capture while Middle Mousebutton is down" checkbutton ui_CaptureRMB "R" pos:[134,30] width:16 height:16 checked:mbCapture[3] tooltip:"Capture while Right Mousebutton is down" button ui_Save "Save As..." pos:[5,51] height:20 width:60 tooltip:"No file selected!" label lbl_Frames "Frames: 0" pos:[75,55] checkbutton ui_grab "Start Grabbing!" pos:[5,75] height:20 width:90 enabled:false button ui_Size "Options" pos:[100,75] height:20 width:50 tooltip:"Output Size and Mousepointer Options" checkbutton ui_Pause "Pause" pos:[100,75] height:20 width:50 visible:false timer grabTimer active:false local oldsave = undefined local moveWindow = FALSE local VPWindowPos = [0,0] on ro_VPGrabber lbuttonDown mpos do ( moveWindow = true VPWindowPos = mpos ) on ro_VPGrabber lbuttonup mpos do ( moveWindow = false VPWindowPos = [0,0] ) on ro_VPGrabber mousemove mpos do ( if (moveWindow == TRUE) do ( dpos = getDialogPos ro_VPGrabber ofpos = dpos + (mpos - VPWindowPos) SetDialogPos ro_VPGrabber ofpos ) ) on grabTimer tick do ( if grab_Pause == true then grabTimer.ticks -= 1 else ( mb = mouse.buttonstates if ((mbCapture[1] == false and mb[1] == true) or (mbCapture[2] == false and mb[2] == true) or (mbCapture[3] == false and mb[3] == true)) then grabTimer.ticks -= 1 else ( t = grabTimer.ticks as string lbl_Frames.caption = "Frames: " + t lbl_Frames.pos = [75,55] newVP = gw.getViewportDib() copy newVP vpGrab if addpointer then addcross() if ((savetype != ".avi") and (savetype != ".mov") and (savetype != ".mpg") and (savetype != ".mpeg")) do ( addzeros = 5 - t.count zeroString = "" for z=1 to addzeros do append zeroString "0" vpGrab.filename = saveName + "_" + zeroString + t + saveType ) save vpGrab ) ) ) on ui_CaptureLMB changed state do mbCapture[1] = state on ui_CaptureMMB changed state do mbCapture[2] = state on ui_CaptureRMB changed state do mbCapture[3] = state on ui_grabChanges changed state do grab_change = state on ui_Pause changed state do grab_pause = state on ui_Size pressed do if (ro_ChangeCapSize.open == FALSE) then createDialog ro_ChangeCapSize width:130 style:#(#style_sysmenu, #style_toolwindow) on ro_VPGrabber close do ( grabTimer.active = false unregisterRedrawViewsCallback saveRedraw savename = undefined savetype = undefined mbCapture = undefined destroyDialog ro_ChangeCapSize vpGrab = undefined addcross = undefined freeSceneBitmaps() gc() ) on ui_Save pressed do ( savename = getBitMapSaveFileName caption:"Save Images to:" if savename != undefined do ( ext = getFileNameType savename saveType = ext savename = substring savename 1 (savename.count - ext.count) lbl_Frames.caption = "Frames: 0" lbl_Frames.pos = [75,54] ui_Save.tooltip = savename ui_save.caption = (getFilenameFile savename) + ext ui_grab.enabled = TRUE if (ro_ChangeCapSize.open == FALSE) then createDialog ro_ChangeCapSize width:130 style:#(#style_sysmenu, #style_toolwindow) ) if savename == undefined do ( ui_save.tooltip = "No file selected!" ui_save.caption = "Save As..." ui_Grab.enabled = false ) ) on ui_interval changed val do ( if val > 0 do ( grabTimer.interval = 1000 / val if ui_grab.state == true then grabTimer.active = true ) if val == 0 then grabTimer.active = false ) on ui_grab changed state do ( if state == true do ( overwrite = TRUE if savename == undefined then ui_save.pressed() if savename != undefined do ( if savename == oldsave then overwrite = querybox "Same filename, overwrite ?" title:"Warning!" if overwrite == TRUE do ( ui_grab.caption = "Stop" ui_Size.visible = false ui_pause.visible = true grab_Pause = false ui_pause.checked = grab_pause ui_save.enabled = false grab_start = true grabTimer.ticks = 0 lbl_Frames.caption = "Frames: 0" lbl_Frames.pos = [75,78] destroyDialog ro_ChangeCapSize if ((savetype == ".avi") or (savetype == ".mov") or (savetype == ".mpg") or (savetype == ".mpeg")) then ( w = capX - (mod capX 4) h = capY - (mod capY 4) vpGrab = bitmap w h filename:(saveName + saveType) ) else vpGrab = bitmap capX capY filename:(saveName + "_00000" + saveType) if ui_interval.value > 0 then grabTimer.active = true if ui_GrabChanges.checked == true then registerRedrawViewsCallback saveRedraw ) ) if ((savename == undefined) or (overwrite == false)) then ui_Grab.state=false ) if state == false do ( ui_Size.visible = true ui_Pause.visible = false ui_grab.caption = "Start Grabbing!" grabTimer.active = false grab_start = false ui_save.enabled = true ui_interval.enabled = true ui_grabChanges.enabled = true unregisterRedrawViewsCallback saveRedraw close vpGrab vpgrab = undefined freeSceneBitmaps() grab_Pause = false oldsave = savename gc() ) ) ) createDialog ro_VPGrabber width:155 style:#(#style_toolwindow, #style_sysmenu) )