def main(state='custom'): """ Toggles a scenes or selection hierarchies instances to Bounding Box or Default Display. Args: state: Custom or Default Returns: Nothing """ start_timer = bd_helpers.timer() scene = modo.Scene() selected = scene.selected drawShape = state # default / custom if len(selected) == 0: for item in scene.iterItemsFast(itype='meshInst'): item.channel('drawShape').set(drawShape) else: for item in selected: if item.type == "meshInst": item.channel('drawShape').set(drawShape) for child in item.children(recursive=True, itemType='meshInst'): child.channel('drawShape').set(drawShape) bd_helpers.timer(start_timer, ' Overall')
def main(): start_timer = bd_helpers.timer() scene = modo.Scene() try: group = scene.item('textureLocators_group') except: group = scene.addItem(lx.symbol.sITYPE_GROUPLOCATOR, name='textureLocators_group') for i in scene.iterItemsFast(lx.symbol.sITYPE_TEXTURELOC): if not i.parent == group: print("Re-parenting {} to {}".format(i.name, group.name)) i.setParent(newParent=group) bd_helpers.timer(start_timer, os.path.splitext(os.path.basename(__file__))[0])
def main(type="alpha"): start_timer = bd_helpers.timer() scene = modo.Scene() sel = scene.selectedByType(lx.symbol.sITYPE_MASK) if len(sel) == 0: lx.out('No Material Groups selected!') else: outputs = [] for mask in sel: color = False alpha = False for child in mask.children(): if child.type == lx.symbol.sITYPE_RENDEROUTPUT: effect = child.channel( lx.symbol.sICHAN_TEXTURELAYER_EFFECT).get() if effect == lx.symbol.s_FX_OUTPUT_ALPHA: print("{} has already an Alpha output.".format( mask.name)) alpha = True if effect == lx.symbol.s_FX_OUTPUT_FINAL_COLOR: print("{} has already a RGB output.".format(mask.name)) color = True if not color: if type == "both" or type == "color": print('Adding RGB output to {}'.format(mask.name)) outputs.append( addmask(mask, lx.symbol.s_FX_OUTPUT_FINAL_COLOR)) if not alpha: if type == "both" or type == "alpha": outputs.append(addmask(mask, lx.symbol.s_FX_OUTPUT_ALPHA)) print('Adding Alpha output to {}'.format(mask.name)) scene.select(outputs, add=False) bd_helpers.timer(start_timer, ' Overall')
def main(comment=False, commentstring=""): start_timer = bd_helpers.timer() scene = modo.Scene() regex = "(.+)_v(\d+)(\w+)?" # Grab anything that has a character sequence followed by a _v and some number filepath = scene.filename if filepath: filename = os.path.splitext(os.path.basename(filepath)) filepath = os.path.dirname(filepath) fileextension = filename[1] filename = filename[0] match = re.match(regex, filename) if match: version = match.group(2) filename = match.group(1) filecomment = match.group(3) result = "yes" else: message = "The provided file ({}{}) contains no version info (we are looking for a '_v000' here).\n\n" \ "Do you want to start versioning this file?".format(filename, fileextension) result = modo.dialogs.yesNo("Missing Version", message) if result == "yes": version = "00" if result == "yes": print('Current file "{}" is at Version {}.'.format(filename, version)) created = False zfill = len(version) if comment: filecomment = commentstring.replace(" ","_").lower() filecomment = bd_helpers.format_filename(filecomment) else: filecomment = False while created is False: version = str(int(version) + 1).zfill(zfill) if filecomment: newfile = os.path.join(filepath, "{}_v{}_{}{}".format(filename, version, filecomment, fileextension)) else: newfile = os.path.join(filepath, "{}_v{}{}".format(filename, version, fileextension)) if os.path.isfile(newfile): print("Version " + version + " already exists. Increasing version count.") pass else: print("Saving as Version " + version) try: lx.eval('scene.saveAs {%s}' % newfile) except: lx.eval('layout.createOrClose EventLog "Event Log_layout" ' 'title:@macros.layouts@EventLog@ width:600 height:600 persistent:true ' 'open:true') print("ERROR Scene save failed with ", sys.exc_info()) created = True else: message = "The provided file has not been saved yet." modo.dialogs.alert("Missing Version!", message, dtype='error') bd_helpers.timer(start_timer, ' Overall')
def main(): start_timer = bd_helpers.timer() scene = modo.Scene() item = scene.selected if len(item) > 1: message = "Please select only one item." modo.dialogs.alert(message, message, dtype='error') elif len(item) == 0: message = "Please select at least one camera." modo.dialogs.alert(message, message, dtype='error') elif item[0].type != "camera": message = "Please select a camera." modo.dialogs.alert(message, message, dtype='error') else: cam = item[0] bake_cam_name = os.path.splitext(scene.name)[0] + "_bakeCam" bake_cam = scene.addCamera(name=bake_cam_name) # Parent to animated camera scene.select(bake_cam) scene.select(cam, add=True) lx.eval("constraintTransform type:pos") scene.select(bake_cam) scene.select(cam, add=True) lx.eval("constraintTransform type:rot") # Link relevant channels cam.channel("focalLen") >> bake_cam.channel("focalLen") cam.channel("apertureX") >> bake_cam.channel("apertureX") cam.channel("apertureY") >> bake_cam.channel("apertureY") cam.channel("offsetX") >> bake_cam.channel("offsetX") cam.channel("offsetY") >> bake_cam.channel("offsetY") cam.channel("focusDist") >> bake_cam.channel("focusDist") cam.channel("fStop") >> bake_cam.channel("fStop") # Bake Animation scene.select(bake_cam) lx.eval("?item.bake 0") # Bake non-transform channels lx.eval("select.drop channel") lx.eval("select.channel {{{0}:focalLen}} add".format(bake_cam.id)) lx.eval("select.channel {{{0}:apertureX}} add".format(bake_cam.id)) lx.eval("select.channel {{{0}:apertureY}} add".format(bake_cam.id)) lx.eval("select.channel {{{0}:offsetX}} add".format(bake_cam.id)) lx.eval("select.channel {{{0}:offsetY}} add".format(bake_cam.id)) lx.eval("select.channel {{{0}:focusDist}} add".format(bake_cam.id)) lx.eval("select.channel {{{0}:fStop}} add".format(bake_cam.id)) lx.eval("?channel.bake 0") scene.select(bake_cam) lx.eval("item.selectChannels anim") # FBX Export export_value = lx.eval("user.value sceneio.fbx.save.exportType ?") lx.eval("user.value sceneio.fbx.save.exportType FBXExportSelection") if scene.filename: filename = scene.filename else: filename = os.path.join(os.path.expanduser('~'), "untitled.lxo") newpath = os.path.splitext(filename)[0] + "_camera_bake.fbx" print "Exporting to {0}".format(newpath) lx.eval("scene.saveAs {0} fbx true".format(newpath)) # Cleanup scene.removeItems(bake_cam) lx.eval( "user.value sceneio.fbx.save.exportType {0}".format(export_value)) modo.dialogs.alert( title="Export Finished", message="The camera has been exported to {0}".format(newpath)) subprocess.Popen(['open', os.path.dirname(newpath)]) bd_helpers.timer(start_timer, ' Overall')
def main(proc='manual', use_scene_range=True, frame_range="1001-1250x1", passname="", batchsize=10, pattern="", preview=False, time=5.0, perFrame='frame', conv=0.975, geoUpdate=False): start_timer = bd_helpers.timer() scene = modo.Scene() scene_path = scene.filename if passname != "None": passname = "group:{}".format(scene.item(passname).name) else: passname = "" if sys.platform == "darwin": headless_path = lx.eval( "query platformservice path.path ? exename") + "_cl" else: headless_path = lx.eval( "query platformservice path.path ? exename") + "_cl.exe" if not scene_path: modo.dialogs.alert('Warning', 'Please save scene first!', dtype='warning') else: # bd_render_paths.main() lx.eval('bd.update_render_paths') if use_scene_range: first_frame, last_frame, frame_step = get_input_range( get_scene_range()) else: first_frame, last_frame, frame_step = get_input_range(frame_range) region = renderRegionCheck() batch_base_path = os.path.join( os.path.dirname(scene_path), "_batch", os.path.splitext(os.path.basename(scene_path))[0]) frames = "_Frames{}-{}".format(first_frame, last_frame) batch_path = os.path.normpath("{}{}.bat".format( batch_base_path, frames)) bash_path = os.path.normpath("{}{}.sh".format(batch_base_path, frames)) framelist = range(int(first_frame), int(last_frame) + 1, int(frame_step)) framelist = chunker(framelist, batchsize) all_commands = [] all_commands_win = [] for framegroup in framelist: scene_dict = {} first_batch_frame = min(int(minframe) for minframe in framegroup) last_batch_frame = max(int(maxframe) for maxframe in framegroup) command_path = os.path.normpath( os.path.join( batch_base_path, "{filename}_batchrender_frames_{first}-{last}.txt".format( filename=os.path.splitext( os.path.basename(scene_path))[0], first=first_batch_frame, last=last_batch_frame))) if not os.path.exists(os.path.dirname(command_path)): os.makedirs(os.path.dirname(command_path)) command_path_win = os.path.normpath( os.path.join( "{}_win".format(batch_base_path), "{filename}_batchrender_frames_{first}-{last}.txt".format( filename=os.path.splitext( os.path.basename(scene_path))[0], first=first_batch_frame, last=last_batch_frame))) if not os.path.exists(os.path.dirname(command_path_win)): os.makedirs(os.path.dirname(command_path_win)) scene_dict[first_batch_frame] = { 'path': scene_path, 'first': first_batch_frame, 'last': last_batch_frame, 'step': frame_step, 'pattern': pattern, 'passes': passname, 'region': region, 'time': time, 'perFrame': perFrame, 'conv': conv, 'geoUpdate': geoUpdate } if preview: modo_command = build_modo_preview_render_command( scenes=scene_dict, pathaliases={ 'WorkingProjects': bd_globals.bdconfig()['projects dir'] }) else: modo_command = build_modo_render_command( scenes=scene_dict, pathaliases={ 'WorkingProjects': bd_globals.bdconfig()['projects dir'] }) with open(command_path, mode='w+') as command: command.write(modo_command) command.close() all_commands.append(command_path) if preview: modo_command_win = build_modo_render_command_win( scenes=scene_dict, pathaliases={ 'WorkingProjects': os.path.normpath( os.path.join( bd_globals.bdconfig()['alt drive'], bd_globals.bdconfig()['projects location'])) }) else: modo_command_win = build_modo_render_command_win( scenes=scene_dict, pathaliases={ 'WorkingProjects': os.path.normpath( os.path.join( bd_globals.bdconfig()['alt drive'], bd_globals.bdconfig()['projects location'])) }) with open(command_path_win, mode='w+') as command: command.write(modo_command_win) command.close() all_commands_win.append(command_path_win) modo_batch = build_modo_batch(commands=all_commands_win) modo_bash = build_modo_bash(commands=all_commands, headless=headless_path, render_range={ 'first': first_frame, 'last': last_frame }) with open(batch_path, mode='w+') as batch: batch.write(modo_batch) batch.close() with open(bash_path, mode='w+') as bash: bash.write(modo_bash) bash.close() os.chmod(bash_path, 0755) lx.eval('scene.save') if proc == 'manual': if sys.platform == "darwin": pyperclip.copy(bash_path) subprocess.Popen([ 'open', '-a', '/Applications/Utilities/Terminal.app', '-n' ]) else: pyperclip.copy(batch_path) os.system("start /B start cmd.exe") else: if sys.platform == "darwin": proc = subprocess.Popen([bash_path]) print proc.pid else: proc = subprocess.Popen([batch_path]) print proc.pid bd_helpers.timer(start_timer, 'Headless Batch Creator')
def main(mode='resolution', newsize='2016x1134'): regex = "(\d+)(?:\D+)(\d+)" start_timer = bd_helpers.timer() scene = modo.Scene() # Get current scene values old_width = scene.renderItem.channel( lx.symbol.sICHAN_POLYRENDER_RESX).get() old_height = scene.renderItem.channel( lx.symbol.sICHAN_POLYRENDER_RESY).get() old_apertureX = scene.renderCamera.channel( lx.symbol.sICHAN_CAMERA_APERTUREX).get() old_apertureY = scene.renderCamera.channel( lx.symbol.sICHAN_CAMERA_APERTUREY).get() print("Old Render Resolution: {}x{}px".format(old_width, old_height)) print("Old Camera Aperture: {}mmx{}mm".format(old_apertureX, old_apertureY)) if mode == "scale": try: scale = float(newsize.replace(",", ".")) new_width = int(old_width * scale) new_height = int(old_height * scale) except: modo.dialogs.alert( "Wrong Scale Format", "Unable to parse the given scale. Please use a floating point number.", dtype='error') else: try: float(newsize.replace(",", ".")) except: match = re.match(regex, newsize) if match and len(match.groups()) == 2: new_width = int(match.group(1)) new_height = int(match.group(2)) else: modo.dialogs.alert( "Wrong Resolution Format", "Unable to parse the given resolution. Please use the format <width> x <height>.", dtype='error') # Apply Overscan formula to width and height new_apertureX = old_apertureX * (new_width / float(old_width)) new_apertureY = old_apertureY * (new_height / float(old_height)) # Set new scene values scene.renderItem.channel(lx.symbol.sICHAN_POLYRENDER_RESX).set(new_width) scene.renderItem.channel(lx.symbol.sICHAN_POLYRENDER_RESY).set(new_height) scene.renderCamera.channel( lx.symbol.sICHAN_CAMERA_APERTUREX).set(new_apertureX) scene.renderCamera.channel( lx.symbol.sICHAN_CAMERA_APERTUREY).set(new_apertureY) print("New Render Resolution: {}x{}px".format(new_width, new_height)) print("New Camera Aperture: {}mmx{}mm".format(new_apertureX, new_apertureY)) bd_helpers.timer(start_timer, ' Overall')
def main(center_action): start_timer = bd_helpers.timer() print '#' * 20 print 'Adjusting Instance Source Centers' print center_action scene = modo.Scene() save_selection = scene.selected # Save selection for later # Weed out non-sources and find sources for any selected instances. sources = [] already_seen = [] instances = {} for item in save_selection: if item.type == "mesh": graph = item.itemGraph('meshInst').forward() # Find any connected instances. if len(graph) > 0: sources.append(item) instances[item] = [graph] if item.type == "meshInst": if item in already_seen: pass # print('already got this source') else: # print('new source') graph = item.itemGraph('meshInst').reverse() # Find the source mesh sources.append(graph[0]) already_seen.extend(graph[0].itemGraph('meshInst').forward()) instances[graph[0]] = [graph[0].itemGraph('meshInst').forward()] sources = list(set(sources)) # Strip all duplicates if len(sources) == 0: print('No source meshes found. Please select at least one instance or source mesh.') else: for mesh in sources: print("Adjusting mesh {0} of {1}".format(sources.index(mesh), len(sources))) # We found instances. Now the fun begins. Grab all the instances and save positions for later instance_array = [] for values in instances[mesh]: for value in values: instance_array.append(value) instances_dict = {} for instance in instance_array: instance_pos_x = modo.LocatorSuperType(instance).position.x.get() instance_pos_y = modo.LocatorSuperType(instance).position.y.get() instance_pos_z = modo.LocatorSuperType(instance).position.z.get() instances_dict[instance] = [instance_pos_x, instance_pos_y, instance_pos_z] # Grab the source mesh's position, adjust the Center and get the new (offset) position original_pos_x = mesh.position.x.get() original_pos_y = mesh.position.y.get() original_pos_z = mesh.position.z.get() mesh.select(replace=True) if center_action == 'center.matchWorkplane pos': lx.eval('select.convert center') lx.eval(center_action) lx.eval('select.type item') else: lx.eval(center_action) new_pos_x = mesh.position.x.get() new_pos_y = mesh.position.y.get() new_pos_z = mesh.position.z.get() # Move the item back to the original position. We are using an extra position channel for the offset. # This is so Instances don't need to be calculated with hard vector math. mesh.position.x.set(original_pos_x) mesh.position.y.set(original_pos_y) mesh.position.z.set(original_pos_z) modo.LocatorSuperType(mesh).transforms.insert(xfrmType='position', placement='append', values=(new_pos_x, new_pos_y, new_pos_z), name='OffsetCompensate') for instance in instance_array: modo.LocatorSuperType(instance).transforms.insert(xfrmType='position', placement='append', values=(new_pos_x, new_pos_y, new_pos_z), name='OffsetCompensate') scene.select(save_selection) bd_helpers.timer(start_timer, 'Overall') print('Finished adjusting the instance centers. Adjusted {0} sources.'.format(len(sources)))
def main(): start_timer = bd_helpers.timer() scene = modo.Scene() sel = scene.selected path = modo.dialogs.dirBrowse(" V-Ray Proxy Path") if path: proxies = get_proxies(path) all_items = [] meshes = [] # Get all mesh items in the selected hierarchy for i in sel: all_items.append(i) children = i.children(recursive=True, itemType=lx.symbol.sITYPE_MESH) if len(children) > 0: all_items += children all_items = set(all_items) # Filter out any non-meshes for i in all_items: if i.type == lx.symbol.sITYPE_MESH: meshes.append(i) meshes = set(meshes) if len(meshes) > 0: found = False m = lx.Monitor(len(proxies)) m.init(len(proxies) * 2) # Go through all proxy files and compare their names to the mesh names for proxy in proxies: regex = "{}".format(re.escape(proxy)) m.step(1) for i in meshes: match = re.match(regex, i.name) if match: found = True try: convert_proxy(i, proxy, path) except: pass # Second round with looser regex to catch any misses reduced = [] for i in meshes: if i.type == lx.symbol.sITYPE_MESH: reduced.append(i) meshes = set(reduced) if len(meshes) > 0: for proxy in proxies: regex = "{}[ _\d]*$".format(re.escape(proxy)) m.step(1) for i in meshes: match = re.match(regex, i.name) if match: found = True print i print proxy try: convert_proxy(i, proxy, path) except: pass else: m.step(len(proxies)) if not found: print("No V-Ray Proxies found for the selected meshes.") else: print("No meshes to replace. Please select some meshes first.") bd_helpers.timer(start_timer, os.path.splitext(os.path.basename(__file__))[0])
def main(): start_timer = bd_helpers.timer() scene = modo.Scene() scene_path = scene.filename if not scene_path: modo.dialogs.alert('Warning', 'Please save scene first!', dtype='warning') else: file = os.path.basename(scene_path) shot = bd_globals.find_shot_version(scene_path) lx.out('File {} is at Version {}.'.format(shot['shotname'], shot['version'])) project = bd_globals.find_project(scene_path) project_config = bd_globals.projectconfig(scene_path) output = os.path.join( project['project_dir'], project_config['images/parent folder'], project_config['images/3d'], shot['sequence'], shot['shotname'], os.path.splitext(file)[0] ) lx.out("The renders will be located at: {}".format(output)) if not os.path.exists(output): os.makedirs(output) for item in scene.iterItemsFast(lx.symbol.sITYPE_RENDEROUTPUT): outputtype = item.channel(lx.symbol.sICHAN_TEXTURELAYER_EFFECT).get() filepath = item.channel(lx.symbol.sICHAN_RENDEROUTPUT_FILENAME).get() enabled = item.channel(lx.symbol.sICHAN_TEXTURELAYER_ENABLE).get() if enabled: if filepath: fileformat = enabled = item.channel(lx.symbol.sICHAN_RENDEROUTPUT_FORMAT).get() if fileformat is None or "$FLEX": if outputtype == lx.symbol.s_FX_OUTPUT_SHADING_NORMAL \ or outputtype == lx.symbol.s_FX_OUTPUT_WORLD_COORDINATES \ or outputtype == lx.symbol.s_FX_OUTPUT_UV_COORDINATES\ or outputtype == lx.symbol.s_FX_OUTPUT_DEPTH\ or outputtype == lx.symbol.s_FX_OUTPUT_MOTION: fileformat = "openexr_32" else: fileformat = "openexr" if item.name == "rgba": renderpasspath = os.path.join(output, "") else: renderpasspath = os.path.join(output, item.name.replace(" ", "_"), "") renderoutputpath = os.path.join(renderpasspath, os.path.splitext(file)[0] + "_") lx.out("RenderOutput " + item.name + " will be located at: " + renderpasspath) if not os.path.exists(renderpasspath): os.makedirs(renderpasspath) lx.out("Setting Render Output path to: " + renderoutputpath) item.channel(lx.symbol.sICHAN_RENDEROUTPUT_FILENAME).set(renderoutputpath) lx.out("Setting Render Output format to: " + fileformat) item.channel(lx.symbol.sICHAN_RENDEROUTPUT_FORMAT).set(fileformat) else: pass # lx.out('Skipping {} as it is either disabled or has no "PATH" filled in'.format(item.name)) bd_helpers.timer(start_timer, 'Render Path Update')