import traceback from pathlib import Path import gradio as gr from PIL import Image from src import backbone, video_mode from src.core import core_generation_funnel, unload_models, run_makevideo from src.depthmap_generation import ModelHolder from src.gradio_args_transport import GradioComponentBundle from src.misc import * from src.common_constants import GenerationOptions as go # Ugly workaround to fix gradio tempfile issue def ensure_gradio_temp_directory(): try: import tempfile path = os.path.join(tempfile.gettempdir(), 'gradio') if not (os.path.exists(path)): os.mkdir(path) except Exception as e: traceback.print_exc() ensure_gradio_temp_directory() def main_ui_panel(is_depth_tab): inp = GradioComponentBundle() # TODO: Greater visual separation with gr.Blocks(): with gr.Row() as cur_option_root: inp -= 'depthmap_gen_row_0', cur_option_root inp += go.COMPUTE_DEVICE, gr.Radio(label="Compute on", choices=['GPU', 'CPU'], value='GPU') # TODO: Should return value instead of index. Maybe Enum should be used? inp += go.MODEL_TYPE, gr.Dropdown(label="Model", choices=['res101', 'dpt_beit_large_512 (midas 3.1)', 'dpt_beit_large_384 (midas 3.1)', 'dpt_large_384 (midas 3.0)', 'dpt_hybrid_384 (midas 3.0)', 'midas_v21', 'midas_v21_small', 'zoedepth_n (indoor)', 'zoedepth_k (outdoor)', 'zoedepth_nk', 'Marigold v1', 'Depth Anything', 'Depth Anything v2 Small', 'Depth Anything v2 Base', 'Depth Anything v2 Large'], value='Depth Anything v2 Base', type="index") with gr.Box() as cur_option_root: inp -= 'depthmap_gen_row_1', cur_option_root with gr.Row(): inp += go.BOOST, gr.Checkbox(label="BOOST", info="Generate depth map parts in a mosaic fashion - very slow", value=False) inp += go.NET_SIZE_MATCH, gr.Checkbox(label="Match net size to input size", info="Net size affects quality, performance and VRAM usage") with gr.Row() as options_depend_on_match_size: inp += go.NET_WIDTH, gr.Slider(minimum=64, maximum=2048, step=64, label='Net width') inp += go.NET_HEIGHT, gr.Slider(minimum=64, maximum=2048, step=64, label='Net height') with gr.Row(): inp += go.TILING_MODE, gr.Checkbox( label='Tiling mode', info='Reduces seams that appear if the depthmap is tiled into a grid' ) with gr.Box() as cur_option_root: inp -= 'depthmap_gen_row_2', cur_option_root with gr.Row(): with gr.Group(): # 50% of width inp += "save_outputs", gr.Checkbox(label="Save Outputs", value=True) with gr.Group(): # 50% of width inp += go.DO_OUTPUT_DEPTH, gr.Checkbox(label="Output DepthMap") inp += go.OUTPUT_DEPTH_INVERT, gr.Checkbox(label="Invert (black=near, white=far)") with gr.Row() as options_depend_on_output_depth_1: inp += go.OUTPUT_DEPTH_COMBINE, gr.Checkbox( label="Combine input and depthmap into one image") inp += go.OUTPUT_DEPTH_COMBINE_AXIS, gr.Radio( label="Combine axis", choices=['Vertical', 'Horizontal'], type="value", visible=False) with gr.Box() as cur_option_root: inp -= 'depthmap_gen_row_3', cur_option_root with gr.Row(): inp += go.CLIPDEPTH, gr.Checkbox(label="Clip and renormalize DepthMap") inp += go.CLIPDEPTH_MODE,\ gr.Dropdown(label="Mode", choices=['Range', 'Outliers'], type="value", visible=False) with gr.Row(visible=False) as clip_options_row_1: inp += go.CLIPDEPTH_FAR, gr.Slider(minimum=0, maximum=1, step=0.001, label='Far clip') inp += go.CLIPDEPTH_NEAR, gr.Slider(minimum=0, maximum=1, step=0.001, label='Near clip') with gr.Box(): with gr.Row(): inp += go.GEN_STEREO, gr.Checkbox(label="Generate stereoscopic (3D) image(s)") with gr.Column(visible=False) as stereo_options: with gr.Row(): inp += go.STEREO_MODES, gr.CheckboxGroup( ["left-right", "right-left", "top-bottom", "bottom-top", "red-cyan-anaglyph", "left-only", "only-right", "cyan-red-reverseanaglyph" ][0:8 if backbone.get_opt('depthmap_script_extra_stereomodes', False) else 5], label="Output") with gr.Row(): inp += go.STEREO_DIVERGENCE, gr.Slider(minimum=0.05, maximum=15.005, step=0.01, label='Divergence (3D effect)') inp += go.STEREO_SEPARATION, gr.Slider(minimum=-5.0, maximum=5.0, step=0.01, label='Separation (moves images apart)') with gr.Row(): inp += go.STEREO_FILL_ALGO, gr.Dropdown(label="Gap fill technique", choices=['none', 'naive', 'naive_interpolating', 'polylines_soft', 'polylines_sharp'], type="value") inp += go.STEREO_OFFSET_EXPONENT, gr.Slider(label="Magic exponent", minimum=1, maximum=2, step=1) inp += go.STEREO_BALANCE, gr.Slider(minimum=-1.0, maximum=1.0, step=0.05, label='Balance between eyes') with gr.Box(): with gr.Row(): inp += go.GEN_NORMALMAP, gr.Checkbox(label="Generate NormalMap") with gr.Column(visible=False) as normalmap_options: with gr.Row(): inp += go.NORMALMAP_PRE_BLUR, gr.Checkbox(label="Smooth before calculating normals") inp += go.NORMALMAP_PRE_BLUR_KERNEL, gr.Slider(minimum=1, maximum=31, step=2, label='Pre-smooth kernel size', visible=False) inp.add_rule(go.NORMALMAP_PRE_BLUR_KERNEL, 'visible-if', go.NORMALMAP_PRE_BLUR) with gr.Row(): inp += go.NORMALMAP_SOBEL, gr.Checkbox(label="Sobel gradient") inp += go.NORMALMAP_SOBEL_KERNEL, gr.Slider(minimum=1, maximum=31, step=2, label='Sobel kernel size') inp.add_rule(go.NORMALMAP_SOBEL_KERNEL, 'visible-if', go.NORMALMAP_SOBEL) with gr.Row(): inp += go.NORMALMAP_POST_BLUR, gr.Checkbox(label="Smooth after calculating normals") inp += go.NORMALMAP_POST_BLUR_KERNEL, gr.Slider(minimum=1, maximum=31, step=2, label='Post-smooth kernel size', visible=False) inp.add_rule(go.NORMALMAP_POST_BLUR_KERNEL, 'visible-if', go.NORMALMAP_POST_BLUR) with gr.Row(): inp += go.NORMALMAP_INVERT, gr.Checkbox(label="Invert") if backbone.get_opt('depthmap_script_gen_heatmap_from_ui', False): with gr.Box(): with gr.Row(): inp += go.GEN_HEATMAP, gr.Checkbox(label="Generate HeatMap") with gr.Box(): with gr.Column(): inp += go.GEN_SIMPLE_MESH, gr.Checkbox(label="Generate simple 3D mesh") with gr.Column(visible=False) as mesh_options: with gr.Row(): gr.HTML(value="Generates fast, accurate only with ZoeDepth models and no boost, no custom maps.") with gr.Row(): inp += go.SIMPLE_MESH_OCCLUDE, gr.Checkbox(label="Remove occluded edges") inp += go.SIMPLE_MESH_SPHERICAL, gr.Checkbox(label="Equirectangular projection") if is_depth_tab: with gr.Box(): with gr.Column(): inp += go.GEN_INPAINTED_MESH, gr.Checkbox( label="Generate 3D inpainted mesh") with gr.Column(visible=False) as inpaint_options_row_0: gr.HTML("Generation is sloooow. Required for generating videos from mesh.") inp += go.GEN_INPAINTED_MESH_DEMOS, gr.Checkbox( label="Generate 4 demo videos with 3D inpainted mesh.") gr.HTML("More options for generating video can be found in the Generate video tab.") with gr.Box(): # TODO: it should be clear from the UI that there is an option of the background removal # that does not use the model selected above with gr.Row(): inp += go.GEN_REMBG, gr.Checkbox(label="Remove background") with gr.Column(visible=False) as bgrem_options: with gr.Row(): inp += go.SAVE_BACKGROUND_REMOVAL_MASKS, gr.Checkbox(label="Save the foreground masks") inp += go.PRE_DEPTH_BACKGROUND_REMOVAL, gr.Checkbox(label="Pre-depth background removal") with gr.Row(): inp += go.REMBG_MODEL, gr.Dropdown( label="Rembg Model", type="value", choices=['u2net', 'u2netp', 'u2net_human_seg', 'silueta', "isnet-general-use", "isnet-anime"]) with gr.Box(): gr.HTML(f"{SCRIPT_FULL_NAME}
") gr.HTML("Information, comment and share @ " "https://github.com/thygate/stable-diffusion-webui-depthmap-script") def update_default_net_size(model_type): w, h = ModelHolder.get_default_net_size(model_type) return inp[go.NET_WIDTH].update(value=w), inp[go.NET_HEIGHT].update(value=h) inp[go.MODEL_TYPE].change( fn=update_default_net_size, inputs=inp[go.MODEL_TYPE], outputs=[inp[go.NET_WIDTH], inp[go.NET_HEIGHT]] ) inp[go.BOOST].change( # Go boost! Wroom!.. fn=lambda a, b: (inp[go.NET_SIZE_MATCH].update(visible=not a), options_depend_on_match_size.update(visible=not a and not b)), inputs=[inp[go.BOOST], inp[go.NET_SIZE_MATCH]], outputs=[inp[go.NET_SIZE_MATCH], options_depend_on_match_size] ) inp.add_rule(options_depend_on_match_size, 'visible-if-not', go.NET_SIZE_MATCH) inp[go.TILING_MODE].change( # Go boost! Wroom!.. fn=lambda a: ( inp[go.BOOST].update(value=False), inp[go.NET_SIZE_MATCH].update(value=True) ) if a else (inp[go.BOOST].update(), inp[go.NET_SIZE_MATCH].update()), inputs=[inp[go.TILING_MODE]], outputs=[inp[go.BOOST], inp[go.NET_SIZE_MATCH]] ) inp.add_rule(options_depend_on_output_depth_1, 'visible-if', go.DO_OUTPUT_DEPTH) inp.add_rule(go.OUTPUT_DEPTH_INVERT, 'visible-if', go.DO_OUTPUT_DEPTH) inp.add_rule(go.OUTPUT_DEPTH_COMBINE_AXIS, 'visible-if', go.OUTPUT_DEPTH_COMBINE) inp.add_rule(go.CLIPDEPTH_MODE, 'visible-if', go.CLIPDEPTH) inp.add_rule(clip_options_row_1, 'visible-if', go.CLIPDEPTH) inp[go.CLIPDEPTH_FAR].change( fn=lambda a, b: a if b < a else b, inputs=[inp[go.CLIPDEPTH_FAR], inp[go.CLIPDEPTH_NEAR]], outputs=[inp[go.CLIPDEPTH_NEAR]], show_progress=False ) inp[go.CLIPDEPTH_NEAR].change( fn=lambda a, b: a if b > a else b, inputs=[inp[go.CLIPDEPTH_NEAR], inp[go.CLIPDEPTH_FAR]], outputs=[inp[go.CLIPDEPTH_FAR]], show_progress=False ) inp.add_rule(stereo_options, 'visible-if', go.GEN_STEREO) inp.add_rule(normalmap_options, 'visible-if', go.GEN_NORMALMAP) inp.add_rule(mesh_options, 'visible-if', go.GEN_SIMPLE_MESH) if is_depth_tab: inp.add_rule(inpaint_options_row_0, 'visible-if', go.GEN_INPAINTED_MESH) inp.add_rule(bgrem_options, 'visible-if', go.GEN_REMBG) return inp def open_folder_action(): # Adapted from stable-diffusion-webui f = backbone.get_outpath() if backbone.get_cmd_opt('hide_ui_dir_config', False): return if not os.path.exists(f) or not os.path.isdir(f): raise Exception("Couldn't open output folder") # .isdir is security-related, do not remove! import platform import subprocess as sp path = os.path.normpath(f) if platform.system() == "Windows": os.startfile(path) elif platform.system() == "Darwin": sp.Popen(["open", path]) elif "microsoft-standard-WSL2" in platform.uname().release: sp.Popen(["wsl-open", path]) else: sp.Popen(["xdg-open", path]) def depthmap_mode_video(inp): gr.HTML(value="Single video mode allows generating videos from videos. Please " "keep in mind that all the frames of the video need to be processed - therefore it is important to " "pick settings so that the generation is not too slow. For the best results, " "use a zoedepth model, since they provide the highest level of coherency between frames.") inp += gr.File(elem_id='depthmap_vm_input', label="Video or animated file", file_count="single", interactive=True, type="file") inp += gr.Checkbox(elem_id="depthmap_vm_custom_checkbox", label="Use custom/pregenerated DepthMap video", value=False) inp += gr.Dropdown(elem_id="depthmap_vm_smoothening_mode", label="Smoothening", type="value", choices=['none', 'experimental'], value='experimental') inp += gr.File(elem_id='depthmap_vm_custom', file_count="single", interactive=True, type="file", visible=False) with gr.Row(): inp += gr.Checkbox(elem_id='depthmap_vm_compress_checkbox', label="Compress colorvideos?", value=False) inp += gr.Slider(elem_id='depthmap_vm_compress_bitrate', label="Bitrate (kbit)", visible=False, minimum=1000, value=15000, maximum=50000, step=250) inp.add_rule('depthmap_vm_custom', 'visible-if', 'depthmap_vm_custom_checkbox') inp.add_rule('depthmap_vm_smoothening_mode', 'visible-if-not', 'depthmap_vm_custom_checkbox') inp.add_rule('depthmap_vm_compress_bitrate', 'visible-if', 'depthmap_vm_compress_checkbox') return inp custom_css = """ #depthmap_vm_input {height: 75px} #depthmap_vm_custom {height: 75px} """ def on_ui_tabs(): inp = GradioComponentBundle() with gr.Blocks(analytics_enabled=False, title="DepthMap", css=custom_css) as depthmap_interface: with gr.Row(equal_height=False): with gr.Column(variant='panel'): inp += 'depthmap_mode', gr.HTML(visible=False, value='0') with gr.Tabs(): with gr.TabItem('Single Image') as depthmap_mode_0: with gr.Group(): with gr.Row(): inp += gr.Image(label="Source", source="upload", interactive=True, type="pil", elem_id="depthmap_input_image") # TODO: depthmap generation settings should disappear when using this inp += gr.File(label="Custom DepthMap", file_count="single", interactive=True, type="file", elem_id='custom_depthmap_img', visible=False) inp += gr.Checkbox(elem_id="custom_depthmap", label="Use custom DepthMap", value=False) with gr.TabItem('Batch Process') as depthmap_mode_1: inp += gr.File(elem_id='image_batch', label="Batch Process", file_count="multiple", interactive=True, type="file") with gr.TabItem('Batch from Directory') as depthmap_mode_2: inp += gr.Textbox(elem_id="depthmap_batch_input_dir", label="Input directory", **backbone.get_hide_dirs(), placeholder="A directory on the same machine where the server is running.") inp += gr.Textbox(elem_id="depthmap_batch_output_dir", label="Output directory", **backbone.get_hide_dirs(), placeholder="Leave blank to save images to the default path.") gr.HTML("Files in the output directory may be overwritten.") inp += gr.Checkbox(elem_id="depthmap_batch_reuse", label="Skip generation and use (edited/custom) depthmaps " "in output directory when a file already exists.", value=True) with gr.TabItem('Single Video') as depthmap_mode_3: inp = depthmap_mode_video(inp) submit = gr.Button('Generate', elem_id="depthmap_generate", variant='primary') inp |= main_ui_panel(True) # Main panel is inserted here unloadmodels = gr.Button('Unload models', elem_id="depthmap_unloadmodels") with gr.Column(variant='panel'): with gr.Tabs(elem_id="mode_depthmap_output"): with gr.TabItem('Depth Output'): with gr.Group(): result_images = gr.Gallery(label='Output', show_label=False, elem_id=f"depthmap_gallery", columns=4) with gr.Column(): html_info = gr.HTML() folder_symbol = '\U0001f4c2' # 📂 gr.Button(folder_symbol, visible=not backbone.get_cmd_opt('hide_ui_dir_config', False)).click( fn=lambda: open_folder_action(), inputs=[], outputs=[], ) with gr.TabItem('3D Mesh'): with gr.Group(): result_depthmesh = gr.Model3D(label="3d Mesh", clear_color=[1.0, 1.0, 1.0, 1.0]) with gr.Row(): # loadmesh = gr.Button('Load') clearmesh = gr.Button('Clear') with gr.TabItem('Generate video'): # generate video with gr.Group(): with gr.Row(): gr.Markdown("Generate video from inpainted(!) mesh.") with gr.Row(): depth_vid = gr.Video(interactive=False) with gr.Column(): vid_html_info_x = gr.HTML() vid_html_info = gr.HTML() fn_mesh = gr.Textbox(label="Input Mesh (.ply | .obj)", **backbone.get_hide_dirs(), placeholder="A file on the same machine where " "the server is running.") with gr.Row(): vid_numframes = gr.Textbox(label="Number of frames", value="300") vid_fps = gr.Textbox(label="Framerate", value="40") vid_format = gr.Dropdown(label="Format", choices=['mp4', 'webm'], value='mp4', type="value", elem_id="video_format") vid_ssaa = gr.Dropdown(label="SSAA", choices=['1', '2', '3', '4'], value='3', type="value", elem_id="video_ssaa") with gr.Row(): vid_traj = gr.Dropdown(label="Trajectory", choices=['straight-line', 'double-straight-line', 'circle'], value='double-straight-line', type="index", elem_id="video_trajectory") vid_shift = gr.Textbox(label="Translate: x, y, z", value="-0.015, 0.0, -0.05") vid_border = gr.Textbox(label="Crop: top, left, bottom, right", value="0.03, 0.03, 0.05, 0.03") vid_dolly = gr.Checkbox(label="Dolly", value=False, elem_classes="smalltxt") with gr.Row(): submit_vid = gr.Button('Generate Video', elem_id="depthmap_generatevideo", variant='primary') inp += inp.enkey_tail() depthmap_mode_0.select(lambda: '0', None, inp['depthmap_mode']) depthmap_mode_1.select(lambda: '1', None, inp['depthmap_mode']) depthmap_mode_2.select(lambda: '2', None, inp['depthmap_mode']) depthmap_mode_3.select(lambda: '3', None, inp['depthmap_mode']) def custom_depthmap_change_fn(mode, zero_on, three_on): hide = mode == '0' and zero_on or mode == '3' and three_on return inp['custom_depthmap_img'].update(visible=hide), \ inp['depthmap_gen_row_0'].update(visible=not hide), \ inp['depthmap_gen_row_1'].update(visible=not hide), \ inp['depthmap_gen_row_3'].update(visible=not hide), not hide custom_depthmap_change_els = ['depthmap_mode', 'custom_depthmap', 'depthmap_vm_custom_checkbox'] for el in custom_depthmap_change_els: inp[el].change( fn=custom_depthmap_change_fn, inputs=[inp[el] for el in custom_depthmap_change_els], outputs=[inp[st] for st in [ 'custom_depthmap_img', 'depthmap_gen_row_0', 'depthmap_gen_row_1', 'depthmap_gen_row_3', go.DO_OUTPUT_DEPTH]]) unloadmodels.click( fn=unload_models, inputs=[], outputs=[] ) clearmesh.click( fn=lambda: None, inputs=[], outputs=[result_depthmesh] ) submit.click( fn=backbone.wrap_gradio_gpu_call(run_generate), inputs=inp.enkey_body(), outputs=[ result_images, fn_mesh, result_depthmesh, html_info ] ) submit_vid.click( fn=backbone.wrap_gradio_gpu_call(run_makevideo), inputs=[ fn_mesh, vid_numframes, vid_fps, vid_traj, vid_shift, vid_border, vid_dolly, vid_format, vid_ssaa ], outputs=[ depth_vid, vid_html_info_x, vid_html_info ] ) return depthmap_interface def format_exception(e: Exception): traceback.print_exc() msg = '

' + 'ERROR: ' + str(e) + '

' + '\n' if 'out of GPU memory' in msg: pass elif "torch.hub.load('facebookresearch/dinov2'," in traceback.format_exc(): msg += ('

To use Depth Anything integration in WebUI mode, please add "--disable-safe-unpickle" to the command line flags. ' 'Alternatively, use Standalone mode. This is a known issue.') elif "Error(s) in loading state_dict " in traceback.format_exc(): msg += ('

There was issue during loading the model.' 'Please add "--disable-safe-unpickle" to the command line flags. This is a known issue.') elif 'out of GPU memory' not in msg: msg += \ 'Please report this issue ' \ f'here. ' \ 'Make sure to provide the full stacktrace: \n' msg += '' + traceback.format_exc() + '' return msg def run_generate(*inputs): inputs = GradioComponentBundle.enkey_to_dict(inputs) depthmap_mode = inputs['depthmap_mode'] depthmap_batch_input_dir = inputs['depthmap_batch_input_dir'] image_batch = inputs['image_batch'] depthmap_input_image = inputs['depthmap_input_image'] depthmap_batch_output_dir = inputs['depthmap_batch_output_dir'] depthmap_batch_reuse = inputs['depthmap_batch_reuse'] custom_depthmap = inputs['custom_depthmap'] custom_depthmap_img = inputs['custom_depthmap_img'] inputimages = [] inputdepthmaps = [] # Allow supplying custom depthmaps inputnames = [] # Also keep track of original file names if depthmap_mode == '3': try: custom_depthmap = inputs['depthmap_vm_custom'] \ if inputs['depthmap_vm_custom_checkbox'] else None colorvids_bitrate = inputs['depthmap_vm_compress_bitrate'] \ if inputs['depthmap_vm_compress_checkbox'] else None ret = video_mode.gen_video( inputs['depthmap_vm_input'], backbone.get_outpath(), inputs, custom_depthmap, colorvids_bitrate, inputs['depthmap_vm_smoothening_mode']) return [], None, None, ret except Exception as e: ret = format_exception(e) return [], None, None, ret if depthmap_mode == '2' and depthmap_batch_output_dir != '': outpath = depthmap_batch_output_dir else: outpath = backbone.get_outpath() if depthmap_mode == '0': # Single image if depthmap_input_image is None: return [], None, None, "Please select an input image" inputimages.append(depthmap_input_image) inputnames.append(None) if custom_depthmap: if custom_depthmap_img is None: return [], None, None, \ "Custom depthmap is not specified. Please either supply it or disable this option." inputdepthmaps.append(Image.open(os.path.abspath(custom_depthmap_img.name))) else: inputdepthmaps.append(None) if depthmap_mode == '1': # Batch Process if image_batch is None: return [], None, None, "Please select input images", "" for img in image_batch: image = Image.open(os.path.abspath(img.name)) inputimages.append(image) inputnames.append(os.path.splitext(img.orig_name)[0]) print(f'{len(inputimages)} images will be processed') elif depthmap_mode == '2': # Batch from Directory # TODO: There is a RAM leak when we process batches, I can smell it! Or maybe it is gone. assert not backbone.get_cmd_opt('hide_ui_dir_config', False), '--hide-ui-dir-config option must be disabled' if depthmap_batch_input_dir == '': return [], None, None, "Please select an input directory." if depthmap_batch_input_dir == depthmap_batch_output_dir: return [], None, None, "Please pick different directories for batch processing." image_list = backbone.listfiles(depthmap_batch_input_dir) for path in image_list: try: inputimages.append(Image.open(path)) inputnames.append(path) custom_depthmap = None if depthmap_batch_reuse: basename = Path(path).stem # Custom names are not used in samples directory if outpath != backbone.get_opt('outdir_extras_samples', None): # Possible filenames that the custom depthmaps may have name_candidates = [f'{basename}-0000.{backbone.get_opt("samples_format", "png")}', # current format f'{basename}.png', # human-intuitive format f'{Path(path).name}'] # human-intuitive format (worse) for fn_cand in name_candidates: path_cand = os.path.join(outpath, fn_cand) if os.path.isfile(path_cand): custom_depthmap = Image.open(os.path.abspath(path_cand)) break inputdepthmaps.append(custom_depthmap) except Exception as e: print(f'Failed to load {path}, ignoring. Exception: {str(e)}') inputdepthmaps_n = len([1 for x in inputdepthmaps if x is not None]) print(f'{len(inputimages)} images will be processed, {inputdepthmaps_n} existing depthmaps will be reused') gen_obj = core_generation_funnel(outpath, inputimages, inputdepthmaps, inputnames, inputs, backbone.gather_ops()) # Saving images img_results = [] results_total = 0 inpainted_mesh_fi = mesh_simple_fi = None msg = "" # Empty string is never returned while True: try: input_i, type, result = next(gen_obj) results_total += 1 except StopIteration: # TODO: return more info msg = '

Successfully generated

' if results_total > 0 else \ '

Successfully generated nothing - please check the settings and try again

' break except Exception as e: msg = format_exception(e) break if type == 'simple_mesh': mesh_simple_fi = result continue if type == 'inpainted_mesh': inpainted_mesh_fi = result continue if not isinstance(result, Image.Image): print(f'This is not supposed to happen! Somehow output type {type} is not supported! Input_i: {input_i}.') continue img_results += [(input_i, type, result)] if inputs["save_outputs"]: try: basename = 'depthmap' if depthmap_mode == '2' and inputnames[input_i] is not None: if outpath != backbone.get_opt('outdir_extras_samples', None): basename = Path(inputnames[input_i]).stem suffix = "" if type == "depth" else f"{type}" backbone.save_image(result, path=outpath, basename=basename, seed=None, prompt=None, extension=backbone.get_opt('samples_format', 'png'), short_filename=True, no_prompt=True, grid=False, pnginfo_section_name="extras", suffix=suffix) except Exception as e: if not ('image has wrong mode' in str(e) or 'I;16' in str(e)): raise e print('Catched exception: image has wrong mode!') traceback.print_exc() # Deciding what mesh to display (and if) display_mesh_fi = None if backbone.get_opt('depthmap_script_show_3d', True): display_mesh_fi = mesh_simple_fi if backbone.get_opt('depthmap_script_show_3d_inpaint', True): if inpainted_mesh_fi is not None and len(inpainted_mesh_fi) > 0: display_mesh_fi = inpainted_mesh_fi return map(lambda x: x[2], img_results), inpainted_mesh_fi, display_mesh_fi, msg.replace('\n', '
')