macroScript BatchCameraRender category:"Sergo Pogosyan" toolTip:"Render scene cameras with specified rendering parameters" buttonText:"BatchCameraRender" ( --########################-- --GLOBAL VARS-- --########################-- --cameras CAMERA_LIST = for obj in cameras where iskindof obj camera collect obj --lights LIGHT_LIST = for obj in lights where iskindof obj light collect obj --this should be also initated when user press render button. --lighting state array structure: #( #(light_name, on/off), #(light_name, on/off), #(light_name, on/off) ... ) LIGHTING_STATE = #() --render size presets RESOLUTIONS = #([640,480],[768,576],[900,600],[1200,800],[1200,960],[1500,1000],[1920,1080],[2400,1200],[2400,1920]) --file name to render to IMAGE_FILE_NAME = undefined --main rollout batchCameraRender_mainRollOut Output_Size_Rollout Render_Output_Rollout Frame_Range_Rollout Scene_States_Rollout Light_Assignement_Rollout Net_Render_Options_Rollout global batchCameraRender_floater --pixel aspect PIXEL_ASPECT = 1.333 --listView items array LV_ITEMS = #() --default vray image file saving state SAVE_VRAY_IMAGE_FILE_STATE = false --script version VERSION_STRING = "1.7" --########################-- --Session-wide persistent variables --########################-- global BatchCam_save_file global BatchCam_save_vray_image_file global BatchCam_rollout_state global BatchCam_net_render_state global BatchCam_show_submit_dialog_state global BatchCam_dialog_height global BatchCam_listItem_state global BatchCam_silent_add_path_mode global BatchCam_lock_aspect global BatchCam_netrender_option_mask global BatchCam_netrender_option_server --########################-- --end of session-wide persistent variables --########################-- --########################-- --FUNCTIONS for batch camera render script --version 1.7 --2009-09-27 --########################-- -- --function to switch render buttons' activity state fn render_buttons_active state = ( --main section batchCameraRender_mainRollOut.render_start.enabled = state batchCameraRender_mainRollOut.net_render.enabled = state batchCameraRender_mainRollOut.show_net_submit.enabled = batchCameraRender_mainRollOut.net_render.checked and batchCameraRender_mainRollOut.net_render.enabled ) --function to switch window element's activity state fn elements_active state = ( batchCameraRender_mainRollOut.select_camera.enabled = state batchCameraRender_mainRollOut.set_viewport.enabled = state --net render section if (batchCameraRender_mainRollOut.net_render.checked and batchCameraRender_mainRollOut.net_render.enabled) \ and not batchCameraRender_mainRollOut.show_net_submit.checked then for control_element in Net_Render_Options_Rollout.controls do control_element.enabled = true else for control_element in Net_Render_Options_Rollout.controls do control_element.enabled = false --filename section for control_element in Render_Output_Rollout.controls do control_element.enabled = state if (findString ((classof (renderers.current)) as string) "v_ray") != undefined then Render_Output_Rollout.save_vray_image_file.enabled = state --lights section for control_element in Light_Assignement_Rollout.controls do control_element.enabled = state --frame range section for control_element in Frame_Range_Rollout.controls do control_element.enabled = state --resolution section for control_element in Output_Size_Rollout.controls do control_element.enabled = state if Output_Size_Rollout.lock_aspect.checked then Output_Size_Rollout.pixel_aspect_spinner.enabled = false --scene state section for control_element in Scene_States_Rollout.controls do control_element.enabled = state ) --function to set all elements "enabled" state depending on list item's selection fn ui_elements_refresh list_items = ( --if there's no elements in list then deactivate all elements if list_items.count == 0 then ( --no camera in scene --deactivate render buttons render_buttons_active false --and all other elements too for control_element in batchCameraRender_mainRollOut.controls do control_element.enabled = false ) else --if there is something... ( --if something is checked then activate render buttons --checked state brought from the state variable --checked state from the list items is somethis broken. Don't know --check if some list item is checked --if checked then activate render buttons checked_items = #() for state in BatchCam_listItem_state do ( if ((state != undefined) and state ) then append checked_items true ) render_buttons_active (checked_items.count > 0) --if something selected activate all elements and fill some fields selected_items = #() for item in list_items do ( if item.selected then append selected_items true ) elements_active (selected_items.count > 0) if selected_items.count > 1 then batchCameraRender_mainRollOut.set_viewport.enabled = false ) --if one element selected activate some elements and fill others ) fn leadingZero num digitCount= ( str = num as string while str.count < digitCount do str = "0" + str str ) fn netrender_submit_progress total current = ( format "Progress: completed % out of %\n" current total ) --function to submit current scene to backburner manager fn net_render_auto_submit camera_name = ( batchManager = NetRender.GetManager() --get NetRender Interface --batchManager.connect #manual [port:] --batchManager.connect #automatic [port:] --batchManager.connect #manual managerName netrender_port = Net_Render_Options_Rollout.Port.text as integer -- if port edit text contains something not integer then use default port - 3234 if netrender_port == undefined then netrender_port = 3234 if not (batchManager.connect (if Net_Render_Options_Rollout.Auto_Search.checked then #automatic else #manual) Net_Render_Options_Rollout.Name_Or_Mask.text port:netrender_port) then --throw error to catch at main try block in on_start_render event handler throw ("Failed to connect to manager "+ (Net_Render_Options_Rollout.Name_Or_Mask.text) + " , port:" + (netrender_port as string)) else ( batchJob = batchManager.NewJob() batchJob.renderCamera = camera_name jobName = batchJob.name + " " + batchJob.renderCamera --add camera name to job name nameCounter = 1 alreadyHasName = true -- do loop to correctly name render job. -- job names composed of scene name + camera name + counter number. do ( tempjobName = jobName + " " + (leadingZero nameCounter ((nameCounter as string).count + 1)) existingJobs = batchManager.getjobs filter:#name key:tempjobName if existingJobs.count == 0 then ( alreadyHasName = false batchJob.name = tempjobName ) else nameCounter = nameCounter + 1 ) while alreadyHasName ) --set render frames from max render dialog batchJob.nthFrame = rendNThFrame if rendTimeType == 3 then ( batchJob.fromFrame = rendStart batchJob.toFrame = rendEnd ) else if rendTimeType == 4 then ( batchJob.frames = rendPickupFrames batchJob.nonSeqFrames = true ) else --if frame range paramter is undefined then render one current frame ( batchJob.fromFrame = currentTime.frame batchJob.toFrame = currentTime.frame ) batchJob.Submit() -- doesn't work -- batchManager.setCallback #progress netrender_submit_progress -- format "callback after set:%\n" (batchManager.getCallback #update ) batchManager.Disconnect() ) --returns min and max frames from object's animation or (0f, 0f) for non animated camera fn get_key_range obj= ( frame_array = #() --standard transformation section try if obj.pos.controller.keys.count > 0 then frame_array = frame_array + (for i in obj.pos.controller.keys collect i.time) else append frame_array 0f catch () try if obj.rotation.controller.keys.count > 0 then frame_array = frame_array + (for i in obj.rotation.controller.keys collect i.time) else append frame_array 0f catch () try if obj.scale.controller.keys.count > 0 then frame_array = frame_array + (for i in obj.scale.controller.keys collect i.time) else append frame_array 0f catch () --object properties section prop_controller_array = for prop in getPropNames obj where isPropertyAnimatable obj prop collect (getPropertyController obj prop) --get controllers prop_controller_array = for prop in prop_controller_array where prop != undefined collect prop --collect only existing controller if prop_controller_array.count > 0 then for controller in prop_controller_array do ( key_array = controller.keys if key_array.count > 0 then frame_array = frame_array + (for i in key_array collect i.time) else append frame_array 0f ) --object modifers section if obj.modifiers.count > 0 then for one_modifier in obj.modifiers do ( modifier_controller_array = for prop in getPropNames one_modifier where isPropertyAnimatable one_modifier prop collect (getPropertyController one_modifier prop) modifier_controller_array = for prop in modifier_controller_array where prop != undefined collect prop if modifier_controller_array.count > 0 then for controller in modifier_controller_array do ( key_array = controller.keys if key_array.count > 0 then frame_array = frame_array + (for i in key_array collect i.time) else append frame_array 0f ) ) result = #() append result (amin frame_array) append result (amax frame_array) result ) --function to set scene state to selected cameras in listitems fn set_scene_state cameraItems state = ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name setUserProp obj_itself "BatchCameraRender_scene_state" (state as string) (i.SubItems.Item "scene_state").text = (state as string) --set text to activex control (i.SubItems.Item "scene_state").ForeColor = (i.SubItems.Item "scene_state").ForeColor.Black ) ) ) --function to set frame size to selected cameras in listitems fn set_resolution cameraItems width height = ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name x_res = width as integer y_res = height as integer setUserProp obj_itself "BatchCameraRender_frame_width" x_res setUserProp obj_itself "BatchCameraRender_frame_heigth" y_res (i.SubItems.Item "resolution").text = x_res as string + " x " + y_res as string --set text to activex control (i.SubItems.Item "resolution").ForeColor = (i.SubItems.Item "resolution").ForeColor.Black ) ) ) fn set_render_output cameraItems fullfilename= ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name fullfilename = pathConfig.convertPathToAbsolute fullfilename setUserProp obj_itself "BatchCameraRender_render_output" (fullfilename as string) (i.SubItems.Item "path").text = fullfilename as string --set text to activex control (i.SubItems.Item "path").ForeColor = (i.SubItems.Item "path").ForeColor.Black ) ) ) fn set_render_folder cameraItems foldername= ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name temp_string = getUserProp obj_itself "BatchCameraRender_render_output" --get path from function parameters temp_path = foldername if temp_string != undefined then ( --get name from camera properties temp_name = filenameFromPath temp_string --exclude file name temp_fullname = pathConfig.appendPath temp_path temp_name --append new folder path to the file name temp_fullname = pathConfig.convertPathToAbsolute temp_fullname setUserProp obj_itself "BatchCameraRender_render_output" (temp_fullname as string) (i.SubItems.Item "path").text = temp_fullname as string --set text to activex control (i.SubItems.Item "path").ForeColor = (i.SubItems.Item "path").ForeColor.Black ) ) ) ) fn set_render_file cameraItems file_name_only= ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name temp_string = getUserProp obj_itself "BatchCameraRender_render_output" --full path from camera object --get name from function parameters temp_name = filenameFromPath file_name_only --exclude file name from function argument, in case file path given along with file name if temp_string != undefined then ( --get path from camera properties temp_path = getFilenamePath temp_string --exclude path from full name temp_fullname = pathConfig.appendPath temp_path temp_name --create new full name with path and file name from function argument temp_fullname = pathConfig.convertPathToAbsolute temp_fullname setUserProp obj_itself "BatchCameraRender_render_output" (temp_fullname as string) (i.SubItems.Item "path").text = temp_fullname as string --set text to activex control (i.SubItems.Item "path").ForeColor = (i.SubItems.Item "path").ForeColor.Black ) ) ) ) --populate frame range parameters fn populate_framerange cameraItems = ( lis = cameraItems rendType1 = Frame_Range_Rollout.rendType1 rendType2 = Frame_Range_Rollout.rendType2 rendType3 = Frame_Range_Rollout.rendType3 rendType5 = Frame_Range_Rollout.rendType5 render_from = Frame_Range_Rollout.render_from render_to = Frame_Range_Rollout.render_to render_anim_from = Frame_Range_Rollout.render_anim_from render_anim_to = Frame_Range_Rollout.render_anim_to render_frames = Frame_Range_Rollout.render_frames render_single = Frame_Range_Rollout.render_single --exclude selected items selected_items = #() for i in lis do if i.selected then append selected_items i if selected_items.count == 1 then ( i = selected_items[1] obj_name = i.text obj_itself = getNodeByName obj_name temp_string1 = getUserProp obj_itself "BatchCameraRender_frames" temp_string2 = getUserProp obj_itself "BatchCameraRender_framerange_from" temp_string5 = getUserProp obj_itself "BatchCameraRender_anim_frame_range" if (temp_string5 != undefined and temp_string5 != "undefined") then ( --render_frames rendType1.state = 0 rendType2.state = 0 rendType3.state = 0 rendType5.state = 1 render_anim_from.enabled = render_anim_to.enabled = true render_single.enabled = render_frames.enabled = render_from.enabled = render_to.enabled = false temp_frame_range = get_key_range obj_itself render_anim_from.text = (temp_frame_range[1].frame as integer) as string render_anim_to.text = (temp_frame_range[2].frame as integer) as string ) else if (temp_string1 != undefined and temp_string1 != "undefined") then ( --render_frames rendType1.state = 0 rendType2.state = 0 rendType3.state = 1 rendType5.state = 0 render_frames.text = temp_string1 as string render_from.enabled = render_to.enabled = false render_frames.enabled = true ) else if (temp_string2 != undefined and temp_string2 != "undefined") then ( temp_string3 = getUserProp obj_itself "BatchCameraRender_framerange_to" if (temp_string2 as integer == temp_string3 as integer) then ( --single frame rendType1.state = 1 rendType2.state = 0 rendType3.state = 0 rendType5.state = 0 render_from.enabled = render_to.enabled = render_frames.enabled = false render_single.value = temp_string2 as integer ) else ( --frame range rendType1.state = 0 rendType2.state = 1 rendType3.state = 0 rendType5.state = 0 render_single.enabled = false render_from.enabled = render_to.enabled = true render_from.value = temp_string2 as integer render_to.value = temp_string3 as integer ) ) ) else --multiple selection ( ) ) --parser function --replaces special keywords in string with values from argument dictionary --dictionary syntax is (keyword, value) --sample dictionary: /* param_dictionary = #( #("cameraname", "CAMERANAME"), #("scenestate", "SCENESTATE"), #("resolution", "RESOLUTION"), #("date", "DATE"), #("var:varname", "VARNAME"), #("scenename", "SCENENAME") #("projectfolder", "PROJECTNAME") ) */ fn parse_file_name_template input_string dictionary = ( found_count = 0 found_any = false result_substring = input_string i_emergency = 0 --emergency counter - some sort of emergency stop in case of infinite loop :) do ( i_emergency += 1 keyword_start = findString result_substring "%" --search for start of the keyword if keyword_start != undefined then ( keyword_substring = substring result_substring (keyword_start+1) -1 -- remaining of the string possibly with keyword keyword_end = findString keyword_substring "%" --search for end of the keyword found_any = true found_count += 1 if keyword_end != undefined then ( found_count += 1 keyword = substring keyword_substring 1 (keyword_end-1) --exclude the keyword - since we using substring here, keyword is always as start of the string -- format "keyword: %\n" keyword --replace keyword with actual value --get keywords and values from argument dictionary was_found = false --this flag remains false if none of the dictionary keywords would not equal to template keyword for i=1 to dictionary.count do ( if keyword == dictionary[i][1] then ( was_found = true --set flag to true if keyword is found result_substring = replace result_substring keyword_start (keyword_end+1) dictionary[i][2] --replace keyword with word from dictionary ) ) if not was_found then --if flag is not raised then replace quoted keyword with unquoted keyword ( result_substring = replace result_substring keyword_start (keyword_end+1) keyword ) ) else ( found_any = false --exit loop if end of keyword not found -- here delete trailing %-char --add template error warning ) ) else ( found_any = false ) ) while (found_any and i_emergency < 300) --proceed with the loop until start or end are found --or more then 300 "%" characters found return result_substring ) fn compose_parsing_dictionary camera_name = ( --compose parsing dictionary for given camera parsing_dictionary = #() --camername keyword append parsing_dictionary #("cameraname", (camera_name as string)) camera_obj_itself = getNodeByName camera_name --scenestate keyword append parsing_dictionary #("scenestate", ((getUserProp camera_obj_itself "BatchCameraRender_scene_state") as string)) --resolution keyword xres_prop = getUserProp camera_obj_itself "BatchCameraRender_frame_width" yres_prop = getUserProp camera_obj_itself "BatchCameraRender_frame_heigth" resolution_string = (xres_prop as string + "x" + yres_prop as string ) append parsing_dictionary #("resolution", resolution_string) --date keyword date_array = getLocalTime() separator = "-" date_string = (date_array[1] as string) + separator + ((leadingZero date_array[2] 2) as string) + separator + ((leadingZero date_array[4] 2) as string) append parsing_dictionary #("date", date_string) --scenename keyword scenename_string = getFilenameFile maxFileName append parsing_dictionary #("scenename", scenename_string) --project name keyword projectfolder_string = pathConfig.getCurrentProjectFolder() temp_array = filterString projectfolder_string "\/" projectfolder_string = temp_array[(temp_array.count)] append parsing_dictionary #("projectfolder", projectfolder_string) return parsing_dictionary ) fn populate_filename_fields cameraItems= ( --get selected items --get filename from one item --split to name and path --compare to UIfield text --if differs then enter "varies" text --go to next item lis = cameraItems result_file_name = Render_Output_Rollout.result_file_name file_name = Render_Output_Rollout.file_name file_path = Render_Output_Rollout.file_path --exclude selected items selected_items = #() for i in lis do if i.selected then append selected_items i if selected_items.count == 1 then ( i = selected_items[1] obj_name = i.text obj_itself = getNodeByName obj_name temp_string = getUserProp obj_itself "BatchCameraRender_render_output" if (temp_string != undefined and temp_string != "undefined") then ( --put parsed string in full text textfield result_file_name.text = parse_file_name_template temp_string (compose_parsing_dictionary obj_name) file_name.text = filenameFromPath temp_string file_path.text = getFilenamePath temp_string ) else ( result_file_name.text = "undefined" file_name.text = "undefined" file_path.text = "undefined" ) ) else ( prev_parsed_path = "" prev_templated_path = "" prev_path = "" prev_file = "" for i in selected_items do ( obj_name = i.text obj_itself = getNodeByName obj_name temp_string = getUserProp obj_itself "BatchCameraRender_render_output" if (temp_string != undefined and temp_string != "undefined") then ( --if multiple items are selected --show only similar parts of the filename --if full path of selected items is equal --show all parts -- for the full path textfield consider parsed path string parsed_path = parse_file_name_template temp_string (compose_parsing_dictionary obj_name) --if parsed full paths are similar show all parts if parsed_path == prev_parsed_path then ( result_file_name.text = temp_string file_name.text = filenameFromPath temp_string file_path.text = getFilenamePath temp_string ) --check if template strings are similar --show similar file names and folder name else if temp_string == prev_templated_path then ( result_file_name.text = "Varies" file_name.text = filenameFromPath temp_string file_path.text = getFilenamePath temp_string ) --if full path varies but folder is similar --show the folder path --in other parts show "varies" text else if prev_path == (getFilenamePath temp_string) then ( result_file_name.text = "Varies" file_name.text = "Varies" file_path.text = getFilenamePath temp_string ) --if folder path varies but filename is equal --show the filename part --in other parts show "varies" text else if prev_file == (filenameFromPath temp_string) then ( result_file_name.text = "Varies" file_name.text = filenameFromPath temp_string file_path.text = "Varies" ) --if all parts are different --show "varies" text in all parts else ( result_file_name.text = "Varies" file_name.text = "Varies" file_path.text = "Varies" ) prev_parsed_path = parsed_path prev_templated_path = temp_string prev_path = getFilenamePath temp_string prev_file = filenameFromPath temp_string ) else ( result_file_name.text = "Varies" file_name.text = "Varies" file_path.text = "Varies" --put "undefined" text to UI fields ) ) ) ) fn populate_light_state cameraItems= ( lis = cameraItems solo_lights = Light_Assignement_Rollout.light_box_solo on_lights = Light_Assignement_Rollout.light_box_forceon off_lights = Light_Assignement_Rollout.light_box_forceoff --exclude selected items selected_items = #() for i in lis do if i.selected then append selected_items i if selected_items.count == 1 then ( i = selected_items[1] obj_name = i.text obj_itself = getNodeByName obj_name temp_string1 = getUserProp obj_itself "BatchCameraRender_solo_lights" temp_string2 = getUserProp obj_itself "BatchCameraRender_on_lights" temp_string3 = getUserProp obj_itself "BatchCameraRender_off_lights" if (temp_string1 != undefined and temp_string1 != "undefined") then ( temparray = filterString temp_string1 "," solo_lights.items = temparray ) else ( solo_lights.items = #() ) if (temp_string2 != undefined and temp_string2 != "undefined") then ( temparray = filterString temp_string2 "," on_lights.items = temparray ) else ( on_lights.items = #() ) if (temp_string3 != undefined and temp_string3 != "undefined") then ( temparray = filterString temp_string3 "," off_lights.items = temparray ) else ( off_lights.items = #() ) ) ) --function to populate ui elements with data from selected list items --only selected items should be passed to this function - no checking fn populate_ui_elements selectedItems= ( if selectedItems.count > 0 then ( --populate image size fields if selectedItems.count == 1 then ( --what you should do if one item is selected --fill resolution fields --show scene state name obj_name = selectedItems[1].text obj_itself = getNodeByName obj_name --get frame size temp_width = 0 temp_height = 0 temp_string = getUserProp obj_itself "BatchCameraRender_frame_width" if (temp_string != undefined and temp_string != "undefined") then temp_width = Output_Size_Rollout.frame_width.value = (temp_string as integer) temp_string = getUserProp obj_itself "BatchCameraRender_frame_heigth" if (temp_string != undefined and temp_string != "undefined") then ( temp_height = Output_Size_Rollout.frame_height.value = (temp_string as integer) --set the pixel aspect PIXEL_ASPECT = Output_Size_Rollout.pixel_aspect_spinner.value = (temp_width as float)/(temp_height as float) ) --display scene state in dropdown list temp_string = getUserProp obj_itself "BatchCameraRender_scene_state" if (temp_string != undefined and temp_string != "undefined") then Scene_States_Rollout.scene_states_list.selection = (sceneStateMgr.FindSceneState (temp_string as string)) + 1 -- plus 1 because dropdown list contains "undefined" as firs item ) --get filename --function to populate filename parts populate_filename_fields selectedItems --populate framerandge populate_framerange selectedItems --populate light_state populate_light_state selectedItems ) ) --Function to set frame range to camera objects --Frame range fn set_frame_range cameraItems frame_from frame_to= ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name frame_from = frame_from as integer frame_to = frame_to as integer setUserProp obj_itself "BatchCameraRender_anim_frame_range" undefined setUserProp obj_itself "BatchCameraRender_framerange_from" frame_from setUserProp obj_itself "BatchCameraRender_framerange_to" frame_to setUserProp obj_itself "BatchCameraRender_frames" undefined (i.SubItems.Item "Frames").text = frame_from as string + "..." + frame_to as string --set text to activex control (i.SubItems.Item "Frames").ForeColor = (i.SubItems.Item "Frames").ForeColor.Black ) ) ) --Single frame fn set_frame_single cameraItems frame_num = ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name frame_from = frame_num as integer frame_to = frame_num as integer setUserProp obj_itself "BatchCameraRender_anim_frame_range" undefined setUserProp obj_itself "BatchCameraRender_framerange_from" frame_from setUserProp obj_itself "BatchCameraRender_framerange_to" frame_to setUserProp obj_itself "BatchCameraRender_frames" undefined (i.SubItems.Item "Frames").text = frame_from as string --set text to activex control (i.SubItems.Item "Frames").ForeColor = (i.SubItems.Item "Frames").ForeColor.Black ) ) ) --animated frame range fn set_anim_frame_range cameraItems = ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name temp_frame_range = get_key_range obj_itself frame_from = temp_frame_range[1].frame frame_to = temp_frame_range[2].frame setUserProp obj_itself "BatchCameraRender_anim_frame_range" true setUserProp obj_itself "BatchCameraRender_framerange_from" undefined setUserProp obj_itself "BatchCameraRender_framerange_to" undefined setUserProp obj_itself "BatchCameraRender_frames" undefined (i.SubItems.Item "Frames").text = "anim.range:" + (frame_from as integer) as string + "..." + (frame_to as integer) as string --set text to activex control (i.SubItems.Item "Frames").ForeColor = (i.SubItems.Item "Frames").ForeColor.Black Frame_Range_Rollout.render_anim_from.text = (temp_frame_range[1].frame as integer) as string Frame_Range_Rollout.render_anim_to.text = (temp_frame_range[2].frame as integer) as string ) ) ) --set frames string to render individual frames fn set_frames cameraItems frames = ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name setUserProp obj_itself "BatchCameraRender_anim_frame_range" undefined setUserProp obj_itself "BatchCameraRender_frames" frames as string setUserProp obj_itself "BatchCameraRender_framerange_from" undefined setUserProp obj_itself "BatchCameraRender_framerange_to" undefined (i.SubItems.Item "Frames").text = frames as string --set text to activex control (i.SubItems.Item "Frames").ForeColor = (i.SubItems.Item "Frames").ForeColor.Black ) ) ) --functions to switch the lights fn switch_lights light_name state = ( light_obj = getNodeByName light_name if light_obj != undefined then --check if light_obj exist in scene ( if hasProperty light_obj "on" then light_obj.on = state else if hasProperty light_obj "enabled" then light_obj.enabled = state else if hasProperty light_obj "Area_Enable" then --for MR Lights light_obj.on = state ) else --if doesn't exist ( --throw error to catch at main try block in on_start_render event handler throw ("Light \"" + light_name + "\" not found.") ) ) --function to get one light object state --written to support different light objects fn get_light_state light_obj = ( local light_state if hasProperty light_obj "on" then light_state = light_obj.on else if hasProperty light_obj "enabled" then light_state = light_obj.enabled else if hasProperty light_obj "Area_Enable" then --for MR Lights light_state = light_obj.on light_state ) --function to store lighting state in the scene --stores light state to the 2 dimensional array fn store_lighting_state = ( LIGHTING_STATE = #() local light_state local light_name for light_obj in LIGHT_LIST do ( light_state = get_light_state light_obj light_name = light_obj.name one_light_state = #(light_name, light_state) append LIGHTING_STATE one_light_state ) ) --function restore lighting state in the scene fn restore_lighting_state = ( for light_obj in LIGHTING_STATE do switch_lights light_obj[1] light_obj[2] ) --function to turn on solo lights and switch off all other lights in scene fn turn_solo_lights_on solo_lights = ( -- format "solo lights: %\n" solo_lights local light_obj for light_obj in LIGHT_LIST do ( if finditem solo_lights light_obj.name == 0 then -- turn off lights that are not in sololight list -- format "off light %\n" light_obj.name switch_lights light_obj.name false ) --now turn lights from sololight list one by one to check their existance in scene for light_name in solo_lights do switch_lights light_name true ) --function to force on lights fn force_lights_on forced_on_lights = ( for light_name in forced_on_lights do switch_lights light_name true ) --function to force off lights fn force_lights_off forced_off_lights = ( for light_name in forced_off_lights do switch_lights light_name false ) --function to store light state to the camera properties fn set_light_state cameraItems: solo_lights: on_lights: off_lights: = ( --cameraItems - listItems in activeX control for i in cameraItems do ( if i.selected then ( tempstr = "" --this string contains light names obj_name = i.text --this is camera name obj_itself = getNodeByName obj_name --get the camera to set properties to if solo_lights != unsupplied then ( for str in solo_lights do if tempstr.count != 0 then --if string is empty don't add comma tempstr = tempstr + "," + str as string else tempstr = tempstr + str as string setUserProp obj_itself "BatchCameraRender_solo_lights" tempstr (i.SubItems.Item "solo_lights").text = tempstr as string --set text to activex control if tempstr == "undefined" then (i.SubItems.Item "solo_lights").ForeColor = (i.SubItems.Item "solo_lights").ForeColor.Gray else (i.SubItems.Item "solo_lights").ForeColor = (i.SubItems.Item "solo_lights").ForeColor.Black ) if on_lights != unsupplied then ( for str in on_lights do if tempstr.count != 0 then tempstr = tempstr + "," + str as string else tempstr = tempstr + str as string setUserProp obj_itself "BatchCameraRender_on_lights" tempstr (i.SubItems.Item "on_lights").text = tempstr as string --set text to activex control if tempstr == "undefined" then (i.SubItems.Item "on_lights").ForeColor = (i.SubItems.Item "on_lights").ForeColor.Gray else (i.SubItems.Item "on_lights").ForeColor = (i.SubItems.Item "on_lights").ForeColor.Black ) if off_lights != unsupplied then ( for str in off_lights do if tempstr.count != 0 then tempstr = tempstr + "," + str as string else tempstr = tempstr + str as string setUserProp obj_itself "BatchCameraRender_off_lights" tempstr (i.SubItems.Item "off_lights").text = tempstr as string --set text to activex control if tempstr == "undefined" then (i.SubItems.Item "off_lights").ForeColor = (i.SubItems.Item "off_lights").ForeColor.Gray else (i.SubItems.Item "off_lights").ForeColor = (i.SubItems.Item "off_lights").ForeColor.Black ) ) ) ) --########################-- --ROLLOUT-- --########################-- rollout batchCameraRender_mainRollOut "Camera Manager Settings" ( dotNetControl lv_objects "System.Windows.Forms.ListView" height:170 button select_all "Select All" align:#left width:65 across:6 button select_none "Select None" align:#left width:65 offset: [-5,0] button check_all "Check All" align:#left width:70 offset: [-10,0] button uncheck_all "Uncheck All" align:#left width:70 offset: [-10,0] button set_viewport "Set Viewport" align:#right width:70 offset: [9,0] button get_viewport "Get Viewport" align:#right width:70 offset: [9,0] button render_start "Render" align:#left width:85 offset: [0,0] across:4 checkbox net_render "Net Render" align:#left offset: [-15,4] checkbox show_net_submit "Show Submit Dialog" align:#left offset: [-40,4] button select_camera "Select Camera(s) in Scene" align:#right width:146 offset: [5,0] --#####-- --list button event handlers-- --#####-- on batchCameraRender_mainRollOut resized height do BatchCam_dialog_height = height[2] on net_render changed state do ( BatchCam_net_render_state = state --save state to global var show_net_submit.enabled = state --enable show_net_submit checkbox ui_elements_refresh LV_ITEMS --refresh ui ) on show_net_submit changed state do ( BatchCam_show_submit_dialog_state = state --save state to global var ui_elements_refresh LV_ITEMS ) on select_all pressed do ( for i in LV_ITEMS do i.selected = true lv_objects.HideSelection = false ui_elements_refresh LV_ITEMS ) on select_none pressed do ( for i in LV_ITEMS do i.selected = false lv_objects.HideSelection = false ui_elements_refresh LV_ITEMS ) on check_all pressed do ( for i in LV_ITEMS do i.checked = true ui_elements_refresh LV_ITEMS ) on uncheck_all pressed do ( for i in LV_ITEMS do i.checked = false ui_elements_refresh LV_ITEMS ) on select_camera pressed do ( camera_selection_names = for obj in LV_ITEMS where obj.selected collect obj.text --get camera names from selected items in list camera_selection = for obj in camera_list where ((findItem camera_selection_names obj.name) != 0) collect obj --collect camera objects with names is in previous array select camera_selection ) --function to set selected camera to active viewport on set_viewport pressed do ( camera_name = "" --extract selected item - there should be only one for item in LV_ITEMS do ( if item.selected then camera_name = item.text ) camera_obj = getNodeByName camera_name if (findString ((classof camera_obj) as string) "camera") != undefined then --set viewport camera viewport.setCamera camera_obj ) --function to select active viewport camera in script's list on get_viewport pressed do ( camera_obj = undefined if viewport.getType() == #view_camera then ( camera_obj = viewport.getCamera() camera_name = camera_obj.name list_names = for item in LV_ITEMS collect item.text --find camera in list items index = findItem list_names camera_name for item in LV_ITEMS do item.selected = false LV_ITEMS[index].selected = true --select item populate_ui_elements #(LV_ITEMS[index]) ui_elements_refresh LV_ITEMS ) ) --#####-- --render button event hadler-- --#####-- on render_start pressed do ( --check if render dialog is open query_approved = true if renderSceneDialog.isOpen() then query_approved = queryBox "Render Setup Dialog is open. To proceed with rendering Render Setup Dialog should be closed.\n\nWould you like to close it now?" title:"Caution" if query_approved and getRenderType() != #view and getRenderType() != #normal then query_approved = queryBox ("Render Type set to \"" + (getRenderType() as string) + "\".\n\nWould you like continue?") title:"Caution" if net_render.checked and (not Render_Output_Rollout.save_file.checked) then query_approved = queryBox "You are about to submit network rendering with no assigned file.\n\nDo you want to continue?" title:"Warning:No files saved" if query_approved then ( renderSceneDialog.close() --here we must read all parameters set in camera properties --set these properties to render parameteres --store changed render parameters --start render --restore render parameteres or go to next camera --store parameter old_rendUseActiveView = rendUseActiveView rendUseActiveView = true --store viewport type and camera viewport_type = viewport.getType() if viewport_type == #view_camera then old_camera = viewport.getCamera() --store frame range oldrendType = rendTimeType oldrendStart = rendStart oldrendEnd = rendEnd oldrendPickupFrames = rendPickupFrames oldrendNThFrame = rendNThFrame --store resolution oldrenderWidth = renderWidth oldrenderHeight = renderHeight --store filename oldfilename = rendOutputFilename oldsavestate = rendSaveFile --store V-ray image properties oldoutput_saveRawFile = false oldoutput_rawFileName = "" oldoutput_on = false vr = renderers.current if (findString ((classof vr) as string) "v_ray") != undefined then ( oldoutput_saveRawFile = vr.output_saveRawFile oldoutput_rawFileName = vr.output_rawFileName oldoutput_on = vr.output_on ) --netrender status oldrenderUseNet = rendUseNet --refill light_list in case some lights were removed or added during script running state LIGHT_LIST = for obj in lights where iskindof obj light collect obj --save lights state store_lighting_state() --scene state saving --there's no current scenestate properties in maxscript --oldscenestate = -- THIS SECTION SHOULD BE UNDER TRY-CATCH BLOCK try ( for i in LV_ITEMS do ( if i.checked then ( --get camera name camera_name = i.text camera_to_render = getNodeByName camera_name --set frame range temp_string1 = getUserProp camera_to_render "BatchCameraRender_frames" temp_string2 = getUserProp camera_to_render "BatchCameraRender_framerange_from" temp_string3 = getUserProp camera_to_render "BatchCameraRender_framerange_to" temp_string5 = getUserProp camera_to_render "BatchCameraRender_anim_frame_range" if (temp_string5 != undefined and temp_string5 != "undefined") then ( rendTimeType = 3 temp_frame_range = get_key_range camera_to_render rendStart = temp_frame_range[1].frame rendEnd = temp_frame_range[2].frame ) else if (temp_string1 != undefined and temp_string1 != "undefined") then ( --render_frames rendTimeType = 4 rendPickupFrames = temp_string1 as string ) else if (temp_string2 != undefined and temp_string2 != "undefined") then ( --single frame --frame range rendTimeType = 3 rendStart = temp_string2 as integer rendEnd = temp_string3 as integer ) rendNThFrame = Frame_Range_Rollout.render_every_nth.value as integer --get and set frame resolution xres_prop = getUserProp camera_to_render "BatchCameraRender_frame_width" yres_prop = getUserProp camera_to_render "BatchCameraRender_frame_heigth" if (xres_prop != undefined and xres_prop != "undefined") and (yres_prop != undefined and yres_prop != "undefined") then ( renderWidth = xres_prop as integer renderHeight = yres_prop as integer ) --get and set file name temp_string = getUserProp camera_to_render "BatchCameraRender_render_output" if (temp_string != undefined and temp_string != "undefined") then ( --parse file name template here temp_string = parse_file_name_template temp_string (compose_parsing_dictionary camera_name) --exclude path from full path string temp_path = getFilenamePath temp_string --check if the path exist if not (doesFileExist temp_path) then ( --if silent_mode is on try to create new path if Render_Output_Rollout.silent_add_path_mode.checked then ( if not makeDir temp_path all:true then throw ("Failed to create path: "+ temp_path) --if path making fails throw exception ) else ( throw ("Path does not exist: "+ temp_path) --if path making fails throw exception ) ) rendSaveFile = Render_Output_Rollout.save_file.checked rendOutputFilename = temp_string --V-ray settings vr=renderers.current if (findString ((classof vr) as string) "v_ray") != undefined then ( vr.output_on = Render_Output_Rollout.save_vray_image_file.checked vr.output_saveRawFile = Render_Output_Rollout.save_vray_image_file.checked file_extension = Render_Output_Rollout.vray_extension_list.items[Render_Output_Rollout.vray_extension_list.selection] vr.output_rawFileName = (getFilenamePath temp_string) + (getFilenameFile temp_string) + file_extension ) ) --get lightstate temp_string1 = getUserProp camera_to_render "BatchCameraRender_solo_lights" temp_string2 = getUserProp camera_to_render "BatchCameraRender_on_lights" temp_string3 = getUserProp camera_to_render "BatchCameraRender_off_lights" if (temp_string1 != undefined and temp_string1 != "undefined") then ( temparray = filterString temp_string1 "," turn_solo_lights_on temparray ) else --if solo lights are listed then don't process other light setting ( if (temp_string3 != undefined and temp_string3 != "undefined") then --turn off exclude lights first, then turn on include lights ( temparray = filterString temp_string3 "," force_lights_off temparray ) if (temp_string2 != undefined and temp_string2 != "undefined") then --turn on include lights. ( temparray = filterString temp_string2 "," force_lights_on temparray ) ) --set scene state temp_string = getUserProp camera_to_render "BatchCameraRender_scene_state" if (temp_string != undefined and temp_string != "undefined") then sceneStateMgr.RestoreAllParts temp_string if net_render.checked and (not show_net_submit.checked) then ( net_render_auto_submit camera_name ) else ( --set viewport camera viewport.setCamera camera_to_render --set net render flag rendUseNet = net_render.checked --render max quick render ) --restore lights state --light state have to be restored after each camera iteration restore_lighting_state() ) -- if close ) -- end of for loop ) -- end of try close catch ( messagebox (getCurrentException()) title:"Error" -- format "*** % ***\n" (getCurrentException()) -- --restore lights state restore_lighting_state() ) -- print "run in any case" --restore parameter rendUseActiveView = old_rendUseActiveView --restore frame range rendTimeType = oldrendType rendStart = oldrendStart rendEnd = oldrendEnd rendPickupFrames = oldrendPickupFrames rendNThFrame = oldrendNThFrame --restore resolution renderWidth = oldrenderWidth renderHeight = oldrenderHeight --restore filename rendOutputFilename = oldfilename rendSaveFile = oldsavestate vr = renderers.current if (findString ((classof vr) as string) "v_ray") != undefined then ( vr.output_saveRawFile = oldoutput_saveRawFile vr.output_rawFileName = oldoutput_rawFileName vr.output_on = oldoutput_on ) --restore netrender rendUseNet = oldrenderUseNet --restore viewport type and camera if not silent submit mode if (show_net_submit.enabled and show_net_submit.checked) or (not net_render.checked) then ( if viewport_type == #view_camera then viewport.setCamera old_camera else viewport.setType viewport_type ) ) else ( --cancellation ) ) --############ --ON OPEN event handler --initialization --############ on batchCameraRender_mainRollOut open do ( --dotNet object initialization lv_objects.GridLines = true --same as in ActiveX lv_objects.CheckBoxes = true lv_objects.Sorting = (dotNetClass "System.Windows.Forms.SortOrder").Ascending lv_objects.HeaderStyle = (dotNetClass "System.Windows.Forms.ColumnHeaderStyle").NonClickable lv_objects.View = (dotNetClass "System.Windows.Forms.View").Details lv_objects.FullRowSelect = true --same as in ActiveX --lv_objects.Activation = (dotNetClass "System.Windows.Forms.ItemActivation").Standard lv_objects.HideSelection = false -- layout_def = #("Camera", "Frames", "Resolution", "Path", "Subfolder", "Solo Lights", "Lights On", "Lights Off", "Scene State") layout_def = #("Camera", "Frames", "Resolution", "Path", "Solo Lights", "Lights On", "Lights Off", "Scene State") for i in layout_def do lv_objects.Columns.add i --96 --add column with name and optional width --fill in spreadshit dotNet version ItemsArray = #() --array to collect the list items if CAMERA_LIST.count > 0 then ( listItem_counter = 0 --only to count list items. to save and restore their checked state for camera_obj in CAMERA_LIST do ( listItem_counter += 1 li = dotNetObject "System.Windows.Forms.ListViewItem" camera_obj.name li.UseItemStyleForSubItems = false sub_li = undefined --subitem variable --get framerange temp_string1 = getUserProp camera_obj "BatchCameraRender_frames" temp_string2 = getUserProp camera_obj "BatchCameraRender_framerange_from" temp_string3 = getUserProp camera_obj "BatchCameraRender_framerange_to" temp_string5 = getUserProp camera_obj "BatchCameraRender_anim_frame_range" if (temp_string5 != undefined and temp_string5 != "undefined") then ( --render_frames temp_frame_range = get_key_range camera_obj frame_from = temp_frame_range[1].frame as string frame_to = temp_frame_range[2].frame as string sub_li = li.SubItems.add ("anim.range:" + (frame_from as integer) as string + "..." + (frame_to as integer) as string) sub_li.ForeColor = sub_li.ForeColor.Black ) else if (temp_string1 != undefined and temp_string1 != "undefined") then ( --render_frames sub_li = li.SubItems.add (temp_string1 as string) sub_li.ForeColor = sub_li.ForeColor.Black ) else if (temp_string2 != undefined and temp_string2 != "undefined") then ( if (temp_string2 as integer == temp_string3 as integer) then ( --single frame sub_li = li.SubItems.add (temp_string2 as string) sub_li.ForeColor = sub_li.ForeColor.Black ) else ( --frame range sub_li = li.SubItems.add (temp_string2 as string + "..." + temp_string3 as string) sub_li.ForeColor = sub_li.ForeColor.Black ) ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "frames" --set subitem name for the .Key property in SubItemCollection method --get frame size xres_prop = getUserProp camera_obj "BatchCameraRender_frame_width" yres_prop = getUserProp camera_obj "BatchCameraRender_frame_heigth" if (xres_prop != undefined and xres_prop != "undefined") and (yres_prop != undefined and yres_prop != "undefined") then ( sub_li = li.SubItems.add (xres_prop as string + " x " + yres_prop as string ) sub_li.ForeColor = sub_li.ForeColor.Black ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "resolution" --set subitem name for the .Key property in SubItemCollection method --get filename temp_string = getUserProp camera_obj "BatchCameraRender_render_output" if (temp_string != undefined and temp_string != "undefined") then ( sub_li = li.SubItems.add temp_string sub_li.ForeColor = sub_li.ForeColor.Black ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "path" --set subitem name for the .Key property in SubItemCollection method --get lightstate temp_string = getUserProp camera_obj "BatchCameraRender_solo_lights" if (temp_string != undefined and temp_string != "undefined") then ( sub_li = li.SubItems.add temp_string sub_li.ForeColor = sub_li.ForeColor.Black ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "solo_lights" --set subitem name for the .Key property in SubItemCollection method temp_string = getUserProp camera_obj "BatchCameraRender_on_lights" if (temp_string != undefined and temp_string != "undefined") then ( sub_li = li.SubItems.add temp_string sub_li.ForeColor = sub_li.ForeColor.Black ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "on_lights" --set subitem name for the .Key property in SubItemCollection method temp_string = getUserProp camera_obj "BatchCameraRender_off_lights" if (temp_string != undefined and temp_string != "undefined") then ( sub_li = li.SubItems.add temp_string sub_li.ForeColor = sub_li.ForeColor.Black ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "off_lights" --set subitem name for the .Key property in SubItemCollection method --scene state part temp_string = getUserProp camera_obj "BatchCameraRender_scene_state" if (temp_string != undefined and temp_string != "undefined") then ( sub_li = li.SubItems.add (temp_string as string) sub_li.ForeColor = sub_li.ForeColor.Black ) else ( sub_li = li.SubItems.add ("undefined") sub_li.ForeColor = sub_li.ForeColor.Gray ) sub_li.name = "scene_state" --set subitem name for the .Key property in SubItemCollection method append ItemsArray li --we add the list item to the array ) lv_objects.Items.AddRange ItemsArray--when done, we populate the ListView lv_objects.AutoResizeColumns (dotNetClass "System.Windows.Forms.ColumnHeaderAutoResizeStyle").HeaderSize lv_objects.Refresh() LV_ITEMS = #() --this array contains listview items for convinience for i=0 to (lv_objects.Items.Count - 1) do append LV_ITEMS (lv_objects.Items.Item i) --code to restore list items' checked state --placed here to work with already sorted list of dotnet control items --initialize state varialble if it is undefined or if camera count doesn't match with state's count if BatchCam_listItem_state == undefined then BatchCam_listItem_state = #() --create empty array if there's no state array BatchCam_listItem_state.count = CAMERA_LIST.count --match count --iterate over dotnet list items for i=1 to LV_ITEMS.count do ( if BatchCam_listItem_state[i] == true then --if item's state saved then check it in list LV_ITEMS[i].checked = true else --else - if item's state is false or UNDEFINED then save state as false and uncheck the item ( BatchCam_listItem_state[i] = false LV_ITEMS[i].checked = false ) ) --end of restore code --init ui elements with session persistent variables --net render checkbox if BatchCam_net_render_state != undefined then net_render.checked = BatchCam_net_render_state else ( net_render.checked = false BatchCam_net_render_state = false ) if BatchCam_show_submit_dialog_state != undefined then show_net_submit.checked = BatchCam_show_submit_dialog_state else ( show_net_submit.checked = false BatchCam_show_submit_dialog_state = false ) ) --refresh ui elements ui_elements_refresh LV_ITEMS ) --##########-- --select item event handler - DOTNET VERSION-- --##########-- on lv_objects Click val do ( --create selected Items array selectedItems = #() for i=0 to (lv_objects.SelectedItems.Count - 1) do append selectedItems (lv_objects.SelectedItems.Item i) populate_ui_elements selectedItems ui_elements_refresh LV_ITEMS ) --check event handler --used to save items' checked state on lv_objects ItemCheck val do ( BatchCam_listItem_state[val.index + 1] = (val.CurrentValue.value__ == 0) --I've found this "value__" field in the msdn documentation ui_elements_refresh LV_ITEMS ) on batchCameraRender_mainRollOut rolledUp state do BatchCam_rollout_state[1] = state ) rollout Net_Render_Options_Rollout "Net Render Options" ( -- group "Net Job Naming" -- ( -- label label_jobname_01 "Job name = prefix:" align:#left across:5 enabled:false -- edittext net_job_prefix align:#left fieldWidth:80 offset: [-7,0] enabled:false -- label label_jobname_02 "+ camera name + suffix:" align:#left offset: [-10,0] enabled:false -- edittext net_job_suffix align:#left fieldWidth:80 offset: [8,0] enabled:false -- label label_jobname_03 " + number" align:#left offset: [5,0] enabled:false -- ) group "Connection Options" ( checkbox Auto_Search "Automatic Search" align:#left offset: [0,0] across:2 button save_settings "Save Settings" width:80 align:#right edittext Name_Or_Mask "Manager Name or IP Address:" labelOnTop:true align:#left fieldWidth:180 offset: [0,0] across:2 edittext Port "Port:" labelOnTop:true align:#left fieldWidth:80 offset: [0,0] tooltip:"" ) on Auto_Search changed state do ( if state then ( Name_Or_Mask.caption = "Subnet Mask:" Name_Or_Mask.text = BatchCam_netrender_option_mask as string ) else ( Name_Or_Mask.caption = "Manager Name or IP Address:" Name_Or_Mask.text = BatchCam_netrender_option_server as string ) ) on Name_Or_Mask changed text do ( if auto_search.state then BatchCam_netrender_option_mask = text else BatchCam_netrender_option_server = text ) --save net render settings to .ini file in plugcfg folder --functions taken from soulburn scripts. on save_settings pressed do ( INIFileDir = ((getdir #plugcfg) + "\\BatchCameraRender\\") if (getDirectories INIFileDir).count == 0 then makeDir INIFileDir INIFilename = INIFileDir + "BatchCameraRender.ini" if (doesFileExist INIFilename) then deleteFile INIFilename setINISetting INIFilename "NetRenderOptions" "auto_search" (Auto_Search.state as string) if Auto_Search.state then setINISetting INIFilename "NetRenderOptions" "mask" (Name_Or_Mask.text as string) else setINISetting INIFilename "NetRenderOptions" "server_name" (Name_Or_Mask.text as string) setINISetting INIFilename "NetRenderOptions" "port" (Port.text as string) ) on Net_Render_Options_Rollout open do ( -- try to load rollout parameters from ini file INIFileDir = ((getdir #plugcfg) + "\\BatchCameraRender\\") INIFilename = INIFileDir + "BatchCameraRender.ini" if (doesFileExist INIFilename) then ( Auto_Search.checked = (getINISetting INIFilename "NetRenderOptions" "auto_search") as booleanClass if Auto_Search.state then ( Name_Or_Mask.caption = "Subnet Mask:" BatchCam_netrender_option_mask = Name_Or_Mask.text = getINISetting INIFilename "NetRenderOptions" "mask" ) else ( Name_Or_Mask.caption = "Manager Name or IP Address:" BatchCam_netrender_option_server = Name_Or_Mask.text = getINISetting INIFilename "NetRenderOptions" "server_name" ) tempPort = getINISetting INIFilename "NetRenderOptions" "port" if ((tempPort as integer) != undefined) then Port.text = tempPort else Port.text = "default" ) else ( Auto_Search.checked = True Name_Or_Mask.caption = "Subnet Mask:" Name_Or_Mask.text = "255.255.255.0" Port.text = "Default" ) ) on Net_Render_Options_Rollout rolledUp state do BatchCam_rollout_state[2] = state ) rollout Output_Size_Rollout "Output Size" ( dropdownlist out_size_list width:200 across:2 button clear_resolution "Clear" width:65 align:#right label label1 "Width:" align:#left across:5 spinner frame_width range:[0,100000,640] type:#integer width:70 offset: [-60,0] label label2 "Image Aspect:" align:#left offset: [-20,0] spinner pixel_aspect_spinner range:[0,100000,1.333] type:#float width:70 offset: [-70,0] checkbutton lock_aspect "Lock" width:30 align:#left offset: [-57,-3] label label3 "Height:" align:#left across:6 spinner frame_height range:[0,100000,480] type:#integer width:70 align:#left offset: [-12,0] button double_resolution "x2" width:30 align:#left offset: [12,-2] button half_resolution "1/2" width:30 align:#left offset: [-32,-2] button set_resolution_to_max "to Max" width:50 align:#left offset: [-65,-2] button get_resolution_from_max "from Max" width:50 align:#left offset: [-89,-2] on Output_Size_Rollout open do ( --resolution dropdownlist init temparray = #() for i in RESOLUTIONS do ( append temparray ("" + (i[1] as integer) as string + " x " + (i[2] as integer) as string) ) out_size_list.items = temparray --save lock aspect checked state if BatchCam_lock_aspect != undefined then lock_aspect.checked = BatchCam_lock_aspect else ( lock_aspect.checked = false BatchCam_lock_aspect = false ) ) --##########-- --set render size event handler-- --##########-- on out_size_list selected item do ( frame_width.value = RESOLUTIONS[item][1] frame_height.value = RESOLUTIONS[item][2] pixel_aspect_spinner.value = RESOLUTIONS[item][1] as float / RESOLUTIONS[item][2] as float PIXEL_ASPECT = pixel_aspect_spinner.value --call method to add/update properties to selected camera object set_resolution LV_ITEMS RESOLUTIONS[item][1] RESOLUTIONS[item][2] ) on frame_width changed val do ( val = val as float if lock_aspect.checked then frame_height.value = val / (PIXEL_ASPECT as float) else pixel_aspect_spinner.value = PIXEL_ASPECT = val / (frame_height.value as float) --call method to add/update properties to selected camera object set_resolution LV_ITEMS (frame_width.value) (frame_height.value) ) on frame_height changed val do ( val = val as float if lock_aspect.checked then frame_width.value = val * (PIXEL_ASPECT as float) else pixel_aspect_spinner.value = PIXEL_ASPECT = (frame_width.value as float) / val --call method to add/update properties to selected camera object set_resolution LV_ITEMS (frame_width.value) (frame_height.value) ) on lock_aspect changed state do ( pixel_aspect_spinner.enabled = (state != true) BatchCam_lock_aspect = state ) on pixel_aspect_spinner changed val do ( PIXEL_ASPECT = val as float frame_height.value = frame_width.value / PIXEL_ASPECT set_resolution LV_ITEMS frame_width.value frame_height.value ) on clear_resolution pressed do ( for i in LV_ITEMS do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name setUserProp obj_itself "BatchCameraRender_frame_width" undefined setUserProp obj_itself "BatchCameraRender_frame_heigth" undefined (i.SubItems.Item "resolution").ForeColor = (i.SubItems.Item "resolution").ForeColor.Gray (i.SubItems.Item "resolution").text = "undefined" ) ) ) on double_resolution pressed do ( frame_width.value *= 2 frame_height.value *= 2 set_resolution LV_ITEMS (frame_width.value) (frame_height.value) ) on half_resolution pressed do ( frame_width.value /= 2 frame_height.value /= 2 set_resolution LV_ITEMS (frame_width.value) (frame_height.value) ) on set_resolution_to_max pressed do ( query_approved = true if renderSceneDialog.isOpen() then query_approved = queryBox "Render Setup Dialog is open. To set resolution to Render Setup Dialog it should be closed.\n\nWould you like to close it now?" title:"Caution" if query_approved do ( renderSceneDialog.close() renderWidth = frame_width.value renderHeight = frame_height.value ) ) on get_resolution_from_max pressed do ( query_approved = true if renderSceneDialog.isOpen() then query_approved = queryBox "Render Setup Dialog is open. To properly get resolution from Render Setup Dialog it should be closed.\n\nWould you like to close it now?" title:"Caution" if query_approved do ( renderSceneDialog.close() frame_width.value = renderWidth frame_height.value = renderHeight pixel_aspect_spinner.value = getRendImageAspect() set_resolution LV_ITEMS (frame_width.value) (frame_height.value) ) ) on Output_Size_Rollout rolledUp state do BatchCam_rollout_state[3] = state ) rollout Render_Output_Rollout "Render Output" ( checkbox save_file "Save File" tooltip:"Common property for all camera.\nPersistent during current 3dsmax session" align:#left across:3 checkbox save_vray_image_file "Save V-ray Raw Image File (not saving)" offset:[40,0] align:#left enabled:false checked:SAVE_VRAY_IMAGE_FILE_STATE dropdownlist vray_extension_list width:55 offset: [0,-2] align:#right button file_button "File..." align:#left width:60 across:3 edittext result_file_name width:320 offset: [-90,0] readonly:true button clear_render_output "Clear" width:65 align:#right label label1 "Filename:" align:#left across:3 edittext file_name width:320 offset: [-90,0] button syntax_info "Syntax" width:65 align:#right enabled:false button folder_button "Folder..." align:#left width:60 offset: [0,-2] across:3 edittext file_path width:240 align:#left offset: [-90,0] checkbox silent_add_path_mode "Create New Path Silently" align:#right offset: [0,0] tooltip:"If checked new path will be created automaticaly during rendering.\nIf not checked and path doesn't exist exception will be thrown" button open_current_folder "Open Folder" width:65 align:#left on Render_Output_Rollout open do ( temparray = #(".exr", ".vrimg") vray_extension_list.items = temparray --get settings from global variables --save file state if BatchCam_save_file != undefined then save_file.checked = BatchCam_save_file else ( save_file.checked = true BatchCam_save_file = true ) --save vray image setting if BatchCam_save_vray_image_file != undefined then save_vray_image_file.checked = BatchCam_save_vray_image_file else ( save_vray_image_file.checked = false BatchCam_save_vray_image_file = false ) --save silent mode flag if BatchCam_silent_add_path_mode != undefined then silent_add_path_mode.checked = BatchCam_silent_add_path_mode else ( silent_add_path_mode.checked = true BatchCam_silent_add_path_mode = true ) ) --save settings in global vars. on save_file changed state do BatchCam_save_file = state --save settings in global vars. on save_vray_image_file changed state do BatchCam_save_vray_image_file = state --save silent mode state on silent_add_path_mode changed state do BatchCam_silent_add_path_mode = state on syntax_info pressed do ( info_string = "You can use special keywords in file name and folder paths.\nCurrently supported keywords are:\n\n" info_string += "%cameraname%\n%scenestate%\n%resolution%\n%date%\n%scenename%\n%projectfolder%\n\n" info_string += "Example:\nD:\\Work\\temp\\%projectname%\\%date%\\%cameraname%.jpg" messagebox info_string title:"File name template info" beep:false ) on file_button pressed do ( try IMAGE_FILE_NAME = getBitmapSaveFileName() catch (getCurrentException()) if IMAGE_FILE_NAME != undefined then ( set_render_output LV_ITEMS IMAGE_FILE_NAME populate_filename_fields LV_ITEMS ) ) on file_name entered val do ( --get full path from camera --get filename --change filename --create new fullpath --save full path to camera --go to next camera set_render_file LV_ITEMS val populate_filename_fields LV_ITEMS ) on file_path entered val do ( set_render_folder LV_ITEMS val populate_filename_fields LV_ITEMS ) --set the folder via the dialog box on folder_button pressed do ( folder_name = getSavePath caption:"Choose Folder" initialDir:file_path.text if folder_name != undefined then ( set_render_folder LV_ITEMS folder_name populate_filename_fields LV_ITEMS ) ) on open_current_folder pressed do ( temp_path = getFilenamePath result_file_name.text if (doesFileExist temp_path) then temp_res = ShellLaunch ("explorer.exe") ( "/n, " + temp_path) else messagebox ("Path does not exist: "+ temp_path) title:"Error" ) on clear_render_output pressed do ( for i in LV_ITEMS do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name setUserProp obj_itself "BatchCameraRender_render_output" undefined (i.SubItems.Item "path").ForeColor = (i.SubItems.Item "path").ForeColor.Gray (i.SubItems.Item "path").text = "undefined" ) ) populate_filename_fields LV_ITEMS ) on Render_Output_Rollout rolledUp state do BatchCam_rollout_state[5] = state ) rollout Frame_Range_Rollout "Frame Range" ( radiobuttons rendType1 labels:#("Single") columns:1 default:1 align:#left across:4 spinner render_single range:[-10000,10000,0] type:#integer width:70 align:#left offset: [-50,0] enabled:false button set_current "Set Current" offset: [-66,-3] width:65 align:#left --button to set current frame button clear_frames "Clear" width:65 align:#right radiobuttons rendType2 labels:#("Range") columns:1 default:0 align:#left across:6 spinner render_from range:[0,10000,0] type:#integer width:70 align:#left offset: [-10,0] enabled:false label label1 "To" align:#left offset: [-9,0] spinner render_to range:[0,10000,10] type:#integer width:70 align:#left offset: [-65,0] enabled:false label label2 "Every Nth Frame:(not saving)" align:#right offset: [0,0] spinner render_every_nth range:[1,10000,0] type:#integer width:70 align:#right offset: [0,0] enabled:false radiobuttons rendType3 labels:#("Frames") columns:1 default:0 align:#left across:2 edittext render_frames fieldWidth:250 offset: [-167,0] enabled:false radiobuttons rendType5 labels:#("Anim. Range") columns:1 default:0 align:#left across:3 edittext render_anim_from width:70 offset: [-70,0] readonly:true edittext render_anim_to width:70 offset: [-150,0] readonly:true --#####-- --render type switch event handler-- --#####-- on Frame_Range_Rollout open do ( render_every_nth.value = 1 ) on rendType1 changed val do ( if val==1 then ( rendType2.state = 0 rendType3.state = 0 rendType5.state = 0 render_single.enabled = true render_anim_to.enabled=render_anim_from.enabled= render_from.enabled = render_to.enabled = render_frames.enabled = false set_frame_single LV_ITEMS render_single.value ) ) --button to set current frame on set_current pressed do ( rendType1.state = 1 rendType2.state = 0 rendType3.state = 0 rendType5.state = 0 render_single.enabled = true render_anim_to.enabled=render_anim_from.enabled= render_from.enabled = render_to.enabled = render_frames.enabled = false render_single.value = sliderTime.frame set_frame_single LV_ITEMS render_single.value ) on rendType2 changed val do ( if val==1 then ( rendType1.state = 0 rendType3.state = 0 rendType5.state = 0 render_from.enabled = render_to.enabled = true set_current.enabled = render_single.enabled = render_anim_to.enabled=render_anim_from.enabled= render_frames.enabled = false set_frame_range LV_ITEMS render_from.value render_to.value ) ) on rendType3 changed val do ( if val==1 then ( rendType1.state = 0 rendType2.state = 0 rendType5.state = 0 set_current.enabled = render_anim_to.enabled=render_anim_from.enabled= render_from.enabled = render_to.enabled = false render_frames.enabled = true if render_frames.text != "" then set_frames LV_ITEMS render_frames.text ) ) on rendType5 changed val do ( if val==1 then ( rendType1.state = 0 rendType2.state = 0 rendType3.state = 0 set_current.enabled = render_single.enabled = render_frames.enabled = render_from.enabled = render_to.enabled = false render_anim_to.enabled=render_anim_from.enabled= true set_anim_frame_range LV_ITEMS ) ) --handlers to handle start and end frames on render_from changed val do ( set_frame_range LV_ITEMS render_from.value render_to.value ) on render_to changed val do ( set_frame_range LV_ITEMS render_from.value render_to.value ) on render_single changed val do ( set_frame_single LV_ITEMS render_single.value ) --event handler to prevent entering symbols except digits, commas and "-"-s on render_frames changed val do ( tempstring = "" teststr = #("0","1","2","3","4","5","6","7","8","9","-",","," ") for i=1 to val.count do ( tempchar = val[i] if finditem teststr tempchar != 0 then tempstring = tempstring + tempchar ) render_frames.text = tempstring ) --this event handler calls set_frames function to set frame to render to camera properties --there's no error checking because on_entered handler should filter unwanted symbols --so just copy this string to rendPickupFrames global variable on render_frames entered val do ( rendType1.state = 0 rendType2.state = 0 render_from.enabled = render_to.enabled = false set_frames LV_ITEMS val ) on clear_frames pressed do ( for i in LV_ITEMS do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name setUserProp obj_itself "BatchCameraRender_framerange_from" undefined setUserProp obj_itself "BatchCameraRender_framerange_to" undefined (i.SubItems.Item "frames").ForeColor = (i.SubItems.Item "frames").ForeColor.Gray (i.SubItems.Item "frames").text = "undefined" ) ) ) on Frame_Range_Rollout rolledUp state do BatchCam_rollout_state[4] = state ) rollout Scene_States_Rollout "Scene State" ( label label1 "Scene State" align:#left offset:[0,2] across:3 dropdownlist scene_states_list width:200 align:#left offset:[-85,0] button clear_scene_states "Clear" width:65 align:#right on Scene_States_Rollout open do ( scenestate_count = sceneStateMgr.GetCount() temparray = #("undefined") for i=1 to scenestate_count do append temparray ((sceneStateMgr.GetSceneState i) as string) scene_states_list.items = temparray ) on scene_states_list selected item do ( -- print scene_states_list.selected set_scene_state LV_ITEMS scene_states_list.selected ) on clear_scene_states pressed do ( for i in LV_ITEMS do ( if i.selected then ( obj_name = i.text obj_itself = getNodeByName obj_name setUserProp obj_itself "BatchCameraRender_scene_state" undefined (i.SubItems.Item "scene_state").ForeColor = (i.SubItems.Item "scene_state").ForeColor.Gray (i.SubItems.Item "scene_state").text = "undefined" scene_states_list.selection = 1 ) ) ) on Scene_States_Rollout rolledUp state do BatchCam_rollout_state[6] = state ) rollout Light_Assignement_Rollout "Light Assignement" ( label label1 "Solo Lights"align:#left across:3 label label2 "Lights Forced On" align:#left label label3 "Lights Forced Off" align:#left button add_solo_lights_button "Add..." align:#left width:65 across:6 button clear_solo_lights_button "Clear" align:#right width:45 offset:[-20,0] button add_forceon_lights_button "Add..." align:#left width:65 button clear_forceon_lights_button "Clear" align:#right width:45 offset:[-20,0] button add_forceoff_lights_button "Add..." align:#left width:65 button clear_forceoff_lights_button "Clear" align:#right width:45 offset:[-20,0] MultiListBox light_box_solo height:5 across:3 MultiListBox light_box_forceon height:5 MultiListBox light_box_forceoff height:5 edittext label4 text:"Lists are given in order of priority: If Solo lights are present then Off and On lights are ignored.\r\nOn lights are on even if they're present in Off lights list. " height:32 align:#left readonly:true on add_solo_lights_button pressed do ( --call dialog box to select the lights --store solo-light list --fill multilistbox with light names fn light_filt obj = isKindOf obj Light templights = selectByName title:"Select Lights" buttonText:"Select" filter:light_filt showHidden:true single:false --select objects by name if templights != undefined then ( for i=1 to templights.count do templights[i] = templights[i].name light_box_solo.items = templights --fill in the listbox ui set_light_state cameraItems:LV_ITEMS solo_lights:templights ) ) on clear_solo_lights_button pressed do ( light_box_solo.items = #() set_light_state cameraItems:LV_ITEMS solo_lights:#("undefined") ) on add_forceon_lights_button pressed do ( --call dialog box to select the lights --store solo-light list --fill multilistbox with light names fn light_filt obj = isKindOf obj Light templights = selectByName title:"Select Lights" buttonText:"Select" filter:light_filt showHidden:true single:false if templights != undefined then ( for i=1 to templights.count do templights[i] = templights[i].name light_box_forceon.items = templights --fill in the listbox ui set_light_state cameraItems:LV_ITEMS on_lights:templights ) ) on clear_forceon_lights_button pressed do ( light_box_forceon.items = #() set_light_state cameraItems:LV_ITEMS on_lights:#("undefined") ) on add_forceoff_lights_button pressed do ( --call dialog box to select the lights --store solo-light list --fill multilistbox with light names fn light_filt obj = isKindOf obj Light templights = selectByName title:"Select Lights" buttonText:"Select" filter:light_filt showHidden:true single:false if templights != undefined then ( for i=1 to templights.count do templights[i] = templights[i].name light_box_forceoff.items = templights set_light_state cameraItems:LV_ITEMS off_lights:templights ) ) on clear_forceoff_lights_button pressed do ( light_box_forceoff.items = #() set_light_state cameraItems:LV_ITEMS off_lights:#("undefined") ) on Light_Assignement_Rollout rolledUp state do BatchCam_rollout_state[7] = state ) rollout aboutRoll "About" ( label lb_about "" label lb_author "Sergo Pogosyan" hyperLink lb_email "sergo.pogosyan@gmail.com" address:"mailto:sergo.pogosyan@gmail.com" align:#center hyperLink lb_homepage "www.sergepogosyan.com" address:"http://www.sergepogosyan.com" align:#center label lb_year "2009" on aboutRoll rolledUp state do ( lb_about.text ="Camera Manager " + VERSION_STRING BatchCam_rollout_state[8] = state ) ) try(CloseRolloutFloater batchCameraRender_floater)catch() batchCameraRender_floater = newRolloutFloater ("Batch Camera Render " + VERSION_STRING) 500 (if BatchCam_dialog_height == undefiend then 850 else BatchCam_dialog_height) addRollout batchCameraRender_mainRollOut batchCameraRender_floater addRollout Net_Render_Options_Rollout batchCameraRender_floater addRollout Output_Size_Rollout batchCameraRender_floater addRollout Frame_Range_Rollout batchCameraRender_floater addRollout Render_Output_Rollout batchCameraRender_floater addRollout Scene_States_Rollout batchCameraRender_floater addRollout Light_Assignement_Rollout batchCameraRender_floater addRollout aboutRoll batchCameraRender_floater elements_active false --rollout state store and restore function for i=1 to batchCameraRender_floater.rollouts.count do ( if BatchCam_rollout_state == undefined then ( BatchCam_rollout_state = #() --initial state if no saved state aboutRoll.open = False Light_Assignement_Rollout.open = False Scene_States_Rollout.open = False Net_Render_Options_Rollout.open = False ) if BatchCam_rollout_state[i] != undefined then ( batchCameraRender_floater.rollouts[i].open = BatchCam_rollout_state[i] ) else ( BatchCam_rollout_state[i] = batchCameraRender_floater.rollouts[i].open -- format "roll - %, state - %\n" batchCameraRender_floater.rollouts[i] batchCameraRender_floater.rollouts[i].open ) ) batchCameraRender_mainRollOut.lv_objects.Refresh() --refresh the dotNet control escapeEnable = false )