From 9dfa300083eba3b5f059c889f7c55e6468a27271 Mon Sep 17 00:00:00 2001
From: JeLuF <jf@mormo.org>
Date: Thu, 25 May 2023 00:16:14 +0200
Subject: [PATCH] Add seamless tiling support

---
 ui/easydiffusion/types.py | 1 +
 ui/index.html             | 9 +++++++++
 ui/media/js/auto-save.js  | 1 +
 ui/media/js/dnd.js        | 8 ++++++++
 ui/media/js/engine.js     | 3 ++-
 ui/media/js/main.js       | 7 +++++++
 6 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/ui/easydiffusion/types.py b/ui/easydiffusion/types.py
index a76f489a..e4426714 100644
--- a/ui/easydiffusion/types.py
+++ b/ui/easydiffusion/types.py
@@ -23,6 +23,7 @@ class GenerateImageRequest(BaseModel):
     sampler_name: str = None  # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms"
     hypernetwork_strength: float = 0
     lora_alpha: float = 0
+    tiling: str = "none" # "none", "x", "y", "xy"
 
 
 class TaskData(BaseModel):
diff --git a/ui/index.html b/ui/index.html
index dc4eb7f0..4814446b 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -236,6 +236,15 @@
                         <td><label for="hypernetwork_strength_slider">Hypernetwork Strength:</label></td>
                         <td> <input id="hypernetwork_strength_slider" name="hypernetwork_strength_slider" class="editor-slider" value="100" type="range" min="0" max="100"> <input id="hypernetwork_strength" name="hypernetwork_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td>
                     </tr>
+                    <tr class="pl-5"><td><label for="tiling">Seamless tiling:</label></td><td>
+                        <select id="tiling" name="tiling">
+                            <option value="none" selected>None</option>
+                            <option value="x">Horizontal</option>
+                            <option value="y">Vertical</option>
+                            <option value="xy">Both</option>
+                        </select>
+                        <a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/Seamless-Tiling" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about Seamless Tiling</span></i></a>
+                    </td></tr>
                     <tr class="pl-5"><td><label for="output_format">Output Format:</label></td><td>
                         <select id="output_format" name="output_format">
                             <option value="jpeg" selected>jpeg</option>
diff --git a/ui/media/js/auto-save.js b/ui/media/js/auto-save.js
index 49d3c751..1424a301 100644
--- a/ui/media/js/auto-save.js
+++ b/ui/media/js/auto-save.js
@@ -25,6 +25,7 @@ const SETTINGS_IDS_LIST = [
     "prompt_strength",
     "hypernetwork_strength",
     "lora_alpha",
+    "tiling",
     "output_format",
     "output_quality",
     "output_lossless",
diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js
index 8b66a3a4..166228f1 100644
--- a/ui/media/js/dnd.js
+++ b/ui/media/js/dnd.js
@@ -249,6 +249,14 @@ const TASK_MAPPING = {
         readUI: () => clip_skip.checked,
         parse: (val) => Boolean(val),
     },
+    tiling: {
+        name: "Tiling",
+        setUI: (val) => {
+            tilingField.value = val
+        },
+        readUI: () => tilingField.value,
+        parse: (val) => val,
+    },
     use_vae_model: {
         name: "VAE model",
         setUI: (use_vae_model) => {
diff --git a/ui/media/js/engine.js b/ui/media/js/engine.js
index eccae6ac..e60409f1 100644
--- a/ui/media/js/engine.js
+++ b/ui/media/js/engine.js
@@ -789,9 +789,10 @@
         use_hypernetwork_model: "string",
         hypernetwork_strength: "number",
         output_lossless: "boolean",
+        tiling: "string",
     }
 
-    // Higer values will result in...
+    // Higher values will result in...
     // pytorch_lightning/utilities/seed.py:60: UserWarning: X is not in bounds, numpy accepts from 0 to 4294967295
     const MAX_SEED_VALUE = 4294967295
 
diff --git a/ui/media/js/main.js b/ui/media/js/main.js
index ecd8ad73..00e87ec2 100644
--- a/ui/media/js/main.js
+++ b/ui/media/js/main.js
@@ -18,6 +18,11 @@ const taskConfigSetup = {
             visible: ({ reqBody }) => reqBody?.clip_skip,
             value: ({ reqBody }) => "yes",
         },
+        tiling: {
+            label: "Tiling",
+            visible: ({ reqBody }) => reqBody?.tiling != "none",
+            value: ({ reqBody }) => reqBody?.tiling,
+        },
         use_vae_model: {
             label: "VAE",
             visible: ({ reqBody }) => reqBody?.use_vae_model !== undefined && reqBody?.use_vae_model.trim() !== "",
@@ -91,6 +96,7 @@ let latentUpscalerStepsSlider = document.querySelector("#latent_upscaler_steps_s
 let latentUpscalerStepsField = document.querySelector("#latent_upscaler_steps")
 let stableDiffusionModelField = new ModelDropdown(document.querySelector("#stable_diffusion_model"), "stable-diffusion")
 let clipSkipField = document.querySelector("#clip_skip")
+let tilingField = document.querySelector("#tiling")
 let vaeModelField = new ModelDropdown(document.querySelector("#vae_model"), "vae", "None")
 let hypernetworkModelField = new ModelDropdown(document.querySelector("#hypernetwork_model"), "hypernetwork", "None")
 let hypernetworkStrengthSlider = document.querySelector("#hypernetwork_strength_slider")
@@ -1221,6 +1227,7 @@ function getCurrentUserRequest() {
             //render_device: undefined, // Set device affinity. Prefer this device, but wont activate.
             use_stable_diffusion_model: stableDiffusionModelField.value,
             clip_skip: clipSkipField.checked,
+            tiling: tilingField.value,
             use_vae_model: vaeModelField.value,
             stream_progress_updates: true,
             stream_image_progress: numOutputsTotal > 50 ? false : streamImageProgressField.checked,