const api = require('../api')
const html_manip = require('../html_manip')
const selection = require('../../selection')
const note = require('../notification')
const controlnet_preset = require('../presets/controlnet_preset')
const preset = require('../presets/preset')
const Enum = require('../../enum')
const event = require('../event')
// const g_controlnet_max_supported_models = 3
let g_controlnet_presets
let g_module_detail
class ControlNetUnit {
static {}
static resetUnit(index) {
const controlnet_unit_default = {
module: null,
model: null,
weight: 1.0,
resize_mode: null,
lowvram: null,
processor_res: null,
threshold_a: null,
threshold_b: null,
guidance_start: 0,
guidance_end: 1,
guessmode: null,
}
this.setUnit(index, controlnet_unit_default)
}
static resetUnits() {
for (let i = 0; i < g_controlnet_max_models; ++i) {
this.resetUnit(i)
}
}
static getUnit(index) {
const controlnet_unit = {
module: this.getModule(index),
model: this.getModel(index),
weight: this.getWeight(index),
resize_mode: null,
lowvram: null,
processor_res: null,
threshold_a: null,
threshold_b: null,
guidance_start: this.getGuidanceStrengthStart(index),
guidance_end: this.getGuidanceStrengthEnd(index),
guessmode: null,
}
return controlnet_unit
}
static setUnit(index, unit_settings) {
const controlnet_unit_setters = {
module: this.setModule,
model: this.setModel,
weight: this.setWeight,
resize_mode: null,
lowvram: null,
processor_res: null,
threshold_a: null,
threshold_b: null,
guidance_start: this.setGuidanceStrengthStart,
guidance_end: this.setGuidanceStrengthEnd,
guessmode: null,
}
for (const [name, value] of Object.entries(unit_settings)) {
try {
if (
controlnet_unit_setters.hasOwnProperty(name)
//&& value.toString() // check if it has a value, null return error; undefine return error; 0 pass
) {
// if (value) {
const setter = controlnet_unit_setters[name]
setter(index, value)
// }
}
} catch (e) {
console.warn(e)
}
}
}
static getUnits() {
const controlnet_units = {}
for (let i = 0; i < g_controlnet_max_models; ++i) {
controlnet_units[i] = this.getUnit(i)
}
return controlnet_units
}
static setUnits(controlnet_units) {
for (const [index, unit] of Object.entries(controlnet_units)) {
try {
this.setUnit(index, unit)
} catch (e) {
console.warn(e)
}
}
}
static doesUnitExist(index) {
//TODO: check if controlnet unit exist
if (index >= 0) {
}
}
static getModule(index) {
const module = getSelectedModule(index)
return module
}
static setModule(index, module_item) {
try {
const module_menu_element = controlnetElement(
index,
'.mModulesMenuControlNet_'
)
html_manip.selectMenuItemByElement(module_menu_element, module_item)
// module_menu_element.dispatchEvent(new Event('click'))
// module_menu_element.click()
changeModule(module_item, index)
} catch (e) {
html_manip.unselectMenuItemByElement(module_menu_element)
console.warn(e)
}
}
static getModel(index) {
const model = getSelectedModel(index)
return model
}
static setModel(index, model_item) {
try {
const model_menu_element = controlnetElement(
index,
'.mModelsMenuControlNet_'
)
html_manip.selectMenuItemByElement(model_menu_element, model_item)
} catch (e) {
html_manip.unselectMenuItemByElement(model_menu_element)
console.warn(e)
}
}
static getWeight(index = 0) {
const weight = getWeight(index)
return weight
}
static setWeight(index, weight) {
setWeight(index, weight)
}
static getGuidanceStrengthStart(index) {
const guidance_strength = getControlNetGuidanceStrengthStart(index)
return guidance_strength
}
static setGuidanceStrengthStart(index, sd_value) {
setControlNetGuidanceStrengthStart(index, sd_value)
}
static getGuidanceStrengthEnd(index) {
const guidance_strength = getControlNetGuidanceStrengthEnd(index)
return guidance_strength
}
static setGuidanceStrengthEnd(index, sd_value) {
setControlNetGuidanceStrengthEnd(index, sd_value)
}
static getProcessorRes(index) {
const slider = controlnetElement(index, '.slControlNetProcessorRes_')
return slider.value
}
static setProcessorRes(index, sd_value) {
const slider = controlnetElement(index, '.slControlNetProcessorRes_')
slider.value = sd_value
}
static getThreshold(index, a_or_b) {
let slider
if (a_or_b === 'a') {
slider = controlnetElement(index, '.slControlNetThreshold_A_')
} else if (a_or_b === 'b') {
slider = controlnetElement(index, '.slControlNetThreshold_B_')
}
const sd_value = general.mapRange(
slider.value,
slider.min,
slider.max,
slider.dataset['sd_min'],
slider.dataset['sd_max']
)
return sd_value
}
static setThreshold(index, a_or_b, sd_value) {
let slider
let label
if (a_or_b === 'a') {
slider = controlnetElement(index, '.slControlNetThreshold_A_')
label = controlnetElement(index, '.lControlNetThreshold_A_')
} else if (a_or_b === 'b') {
slider = controlnetElement(index, '.slControlNetThreshold_B_')
label = controlnetElement(index, '.lControlNetThreshold_B_')
}
const slider_value = general.mapRange(
sd_value,
slider.dataset['sd_min'],
slider.dataset['sd_max'],
slider.min,
slider.max
)
slider.value = String(slider_value)
label.innerText = String(sd_value)
}
static getControlNetUnitJson(index = 0) {}
}
async function checkIfControlNetInstalled() {}
async function requestControlNetDetectMap(
controlnet_init_image,
_module,
processor_res,
threshold_a,
threshold_b
) {
try {
const payload = {
controlnet_module: _module,
controlnet_input_images: [controlnet_init_image],
controlnet_processor_res: processor_res,
controlnet_threshold_a: threshold_a,
controlnet_threshold_b: threshold_b,
}
const full_url = `${g_sd_url}/controlnet/detect`
// debugger
const response_data = await api.requestPost(full_url, payload)
// update the mask preview with the new detectMap
if (response_data['images'].length === 0) {
app.showAlert(response_data['info'])
}
return response_data['images'][0]
} catch (e) {
console.warn('requestControlNetDetectMap(): ', _module, e)
}
}
async function requestControlNetModelList() {
const control_net_json = await api.requestGet(
`${g_sd_url}/controlnet/model_list`
)
const model_list = control_net_json?.model_list
// const model_list = [
// 'none',
// 'control_sd15_depth [fef5e48e]',
// 'control_sd15_openpose [fef5e48e]',
// 'control_sd15_scribble [fef5e48e]',
// ]
return model_list
}
async function requestControlNetModuleList() {
// const control_net_json = await api.requestGet(
// `${g_sd_url}/controlnet/model_list`
// )
// const module_list = [
// // 'none',
// 'canny',
// 'depth',
// 'depth_leres',
// 'hed',
// 'mlsd',
// 'normal_map',
// 'openpose',
// // "openpose_hand",
// 'pidinet',
// 'scribble',
// 'fake_scribble',
// 'segmentation',
// ]
// const module_list = g_sd_config_obj.getControlNetPreprocessors()
const result = await api.requestGet(
`${g_sd_url}/controlnet/module_list?alias_names=1`
)
return result?.module_list
}
async function populateModelMenu() {
try {
const models = await requestControlNetModelList()
for (let index = 0; index < g_controlnet_max_models; index++) {
const menu_element = controlnetElement(
index,
'.mModelsMenuControlNet_'
)
html_manip.populateMenuByElement(
menu_element,
'mModelsMenuItemControlNet_',
models,
(item, item_html_element) => {
item_html_element.innerHTML = item
item_html_element.dataset['index'] = index
},
false,
'Select Model'
)
}
} catch (e) {
console.warn(e)
}
}
function changeModule(_module, index) {
// const index = index
const preprocessor_res_element = controlnetElement(
index,
'.slControlNetProcessorRes_'
)
const threshold_a_element = controlnetElement(
index,
'.slControlNetThreshold_A_'
)
const threshold_b_element = controlnetElement(
index,
'.slControlNetThreshold_B_'
)
const detail = g_module_detail[_module]
function remapArray(arr) {
let obj = {
preprocessor_res: arr[0] || null,
threshold_a: arr[1] || null,
threshold_b: arr[2] || null,
}
return obj
}
const params = remapArray(detail['sliders'])
const model_free = detail.model_free
// threshold_a_element.min = prams.
// threshold_a_element.max =
// debugger
if (model_free)
controlnetElement(
index,
'.mModelsMenuControlNet_'
).parentElement.style.display = 'none'
else
controlnetElement(
index,
'.mModelsMenuControlNet_'
).parentElement.style.display = 'block'
if (params?.preprocessor_res) {
const preprocessor_res_label_element = controlnetElement(
index,
'.labelControlNetProcessorRes_'
)
preprocessor_res_element.style.display = 'block'
preprocessor_res_label_element.innerText = params.preprocessor_res.name
} else {
preprocessor_res_element.style.display = 'none'
}
if (params?.threshold_a) {
const threshold_a_label_element = controlnetElement(
index,
'.labelControlNetThreshold_A_'
)
threshold_a_element.dataset['sd_min'] = params.threshold_a.min
threshold_a_element.dataset['sd_max'] = params.threshold_a.max
ControlNetUnit.setThreshold(index, 'a', params.threshold_a.value)
threshold_a_element.style.display = 'block'
threshold_a_label_element.innerText = params.threshold_a.name + ":"
} else {
ControlNetUnit.setThreshold(index, 'a', 32)
threshold_a_element.style.display = 'none'
}
if (params?.threshold_b) {
const threshold_b_label_element = controlnetElement(
index,
'.labelControlNetThreshold_B_'
)
threshold_b_element.dataset['sd_min'] = params.threshold_b.min
threshold_b_element.dataset['sd_max'] = params.threshold_b.max
ControlNetUnit.setThreshold(index, 'b', params.threshold_b.value)
threshold_b_element.style.display = 'block'
threshold_b_label_element.innerText = params.threshold_b.name + ":"
} else {
ControlNetUnit.setThreshold(index, 'b', 32)
threshold_b_element.style.display = 'none'
}
}
async function populatePreprocessorMenu() {
try {
// debugger
const modules = await requestControlNetModuleList()
for (let index = 0; index < g_controlnet_max_models; index++) {
const menu_element = controlnetElement(
index,
'.mModulesMenuControlNet_'
)
menu_element.dataset['index'] = String(index)
html_manip.populateMenuByElement(
menu_element,
'mModuleMenuItemControlNet_',
modules,
(item, item_html_element) => {
item_html_element.innerHTML = item
item_html_element.dataset['index'] = index
},
false,
'Select Module'
)
menu_element.addEventListener('click', (event) => {
changeModule(
event.target.innerText,
event.target.dataset['index']
)
})
}
} catch (e) {
console.warn(e)
}
}
function controlnetElement(index, class_) {
const element = document.querySelector(
`#controlnet_settings_${index} ${class_}`
)
return element
}
function getControlNetGuidanceStrengthStart(index) {
const slider_element = document.querySelector(
`#controlnet_settings_${index} .slControlNetGuidanceStrengthStart_`
)
const sd_value = html_manip.getSliderSdValueByElement(
slider_element,
0,
100,
0,
1
)
return sd_value
}
function setControlNetGuidanceStrengthStart(index, sd_value) {
const slider_element = controlnetElement(
index,
'.slControlNetGuidanceStrengthStart_'
)
const label_element = controlnetElement(
index,
'.lControlNetGuidanceStrengthStart_'
)
html_manip.setSliderSdValueByElements(
slider_element,
label_element,
sd_value,
0,
100,
0,
1
)
}
function getControlNetGuidanceStrengthEnd(index) {
const slider_element = controlnetElement(
index,
'.slControlNetGuidanceStrengthEnd_'
)
const sd_value = html_manip.getSliderSdValueByElement(
slider_element,
0,
100,
0,
1
)
return sd_value
}
function setControlNetGuidanceStrengthEnd(index, sd_value) {
const slider_element = controlnetElement(
index,
'.slControlNetGuidanceStrengthEnd_'
)
const label_element = controlnetElement(
index,
'.lControlNetGuidanceStrengthEnd_'
)
html_manip.setSliderSdValueByElements(
slider_element,
label_element,
sd_value,
0,
100,
0,
1
)
}
// controlnet settings getters
function getControlNetWeightGuidanceStrengthStart(index = 0) {
const slider_element = controlnetElement(
index,
'.slControlNetGuidanceStrengthStart_'
)
const slider_value = slider_element.value
const sd_value = general.mapRange(slider_value, 0, 100, 0, 1) // convert slider value to SD ready value
return sd_value
}
function getControlNetWeightGuidanceStrengthEnd(index = 0) {
const slider_value = controlnetElement(
index,
'.slControlNetGuidanceStrengthEnd_'
).value
const sd_value = general.mapRange(slider_value, 0, 100, 0, 1) // convert slider value to SD ready value
return sd_value
}
function getWeight(index = 0) {
const slider_value = document.querySelector(
`#controlnet_settings_${index} .slControlNetWeight_`
).value
const sd_value = general.mapRange(slider_value, 0, 100, 0, 2) // convert slider value to SD ready value
return sd_value
}
function setWeight(index = 0, sd_weight) {
const slider_element = document.querySelector(
`#controlnet_settings_${index} .slControlNetWeight_`
)
const label_element = document.querySelector(
`#controlnet_settings_${index} .lControlNetWeight_`
)
html_manip.setSliderSdValueByElements(
slider_element,
label_element,
sd_weight,
0,
100,
0,
2
)
}
function getUseLowVram(index = 0) {
const b_result = document.querySelector(
`#controlnet_settings_${index} .chlowVram_`
).checked
return b_result
}
function getEnableControlNet(index = 0) {
const is_enable = document.querySelector(
`#controlnet_settings_${index} .chEnableControlNet_`
).checked
return is_enable
}
function setEnable(index) {
document.querySelector(
`#controlnet_settings_${index} .chEnableControlNet_`
).checked = b_live_update
}
function getSelectedModule(index = 0) {
const menu_element = controlnetElement(index, '.mModulesMenuControlNet_')
// debugger
const module_name =
html_manip.getSelectedMenuItemTextContentByElement(menu_element)
return module_name
}
function getSelectedModel(index = 0) {
const menu_element = controlnetElement(index, '.mModelsMenuControlNet_')
const model_name =
html_manip.getSelectedMenuItemTextContentByElement(menu_element)
return model_name
}
function getUseGuessMode(index = 0) {
const is_guess_mode = document.querySelector(
`#controlnet_settings_${index} .chGuessMode_`
).checked
return is_guess_mode
}
function isControlNetModeEnable() {
let is_tab_enabled = !document.getElementById('chDisableControlNetTab')
.checked
let numOfEnabled = 0
if (g_controlnet_max_models <= 0) {
return false
}
if (is_tab_enabled) {
for (let index = 0; index < g_controlnet_max_models; index++) {
if (getEnableControlNet(index)) {
numOfEnabled += 1
}
}
}
let is_mode_enabled = is_tab_enabled // could be true
if (is_tab_enabled === false || numOfEnabled === 0) {
is_mode_enabled = false
}
return is_mode_enabled
}
// function getControlNetMaxModelsNumber() {
// return g_controlnet_max_supported_models
// }
function preprocessorData(
processor_res = 512,
threshold_a = 64,
threshold_b = 64,
a_min = 64,
a_max = 1024,
b_min = 64,
b_max = 1024,
processor_res_label = 'Annotator resolution',
threshold_a_label = 'threshold a',
threshold_b_label = 'threshold b'
) {
return {
processor_res,
threshold_a,
threshold_b,
a_min,
a_max,
b_min,
b_max,
processor_res_label,
threshold_a_label,
threshold_b_label,
}
}
function mapPluginSettingsToControlNet(plugin_settings) {
const ps = plugin_settings // for shortness
let controlnet_units = []
// debugger
let active_index = 0
for (let index = 0; index < g_controlnet_max_models; index++) {
const preprocessor_name = getSelectedModule(index)
controlnet_units[active_index] = {
enabled: getEnableControlNet(index),
input_image: g_generation_session.controlNetImage[index],
mask: '',
module: getSelectedModule(index),
model: getSelectedModel(index),
weight: getWeight(index),
resize_mode: 'Scale to Fit (Inner Fit)',
lowvram: getUseLowVram(index),
processor_res: ControlNetUnit.getProcessorRes(index),
threshold_a: ControlNetUnit.getThreshold(index, 'a'),
threshold_b: ControlNetUnit.getThreshold(index, 'b'),
// guidance: ,
guidance_start: getControlNetWeightGuidanceStrengthStart(index),
guidance_end: getControlNetWeightGuidanceStrengthEnd(index),
guessmode: false,
}
active_index++
}
if (
plugin_settings['mode'] === Enum.generationModeEnum['Img2Img'] ||
plugin_settings['mode'] === Enum.generationModeEnum['Inpaint'] ||
plugin_settings['mode'] === Enum.generationModeEnum['Outpaint']
) {
const b_use_guess_mode = getUseGuessMode()
controlnet_units[0]['guessmode'] = b_use_guess_mode
}
const controlnet_payload = {
...ps,
controlnet_units, //keep for backward compatibility for now
subseed: -1,
override_settings: {},
override_settings_restore_afterwards: true,
alwayson_scripts: {
controlnet: {
args: controlnet_units,
},
},
}
return controlnet_payload
}
function refreshControlNetTab() {}
async function populateControlNetPresetMenu() {
// const default_preset_name = 'Select CtrlNet Preset'
// const default_preset_settings = {} // empty preset
const custom_presets = await preset.getAllCustomPresetsSettings(
Enum.PresetTypeEnum['ControlNetPreset']
)
g_controlnet_presets = {
'Select CtrlNet Preset': {},
...controlnet_preset.ControlNetNativePresets,
...custom_presets,
}
const presets_names = Object.keys(g_controlnet_presets)
html_manip.populateMenu(
'mControlNetPresetMenu',
'mControlNetPresetMenuItem',
presets_names,
(preset_name, item_html_element) => {
item_html_element.innerHTML = preset_name
}
)
html_manip.selectMenuItem('mControlNetPresetMenu', 'Select CtrlNet Preset')
}
document
.getElementById('mControlNetPresetMenu')
.addEventListener('change', async (evt) => {
try {
ControlNetUnit.resetUnits()
const preset_index = evt.target.selectedIndex
const preset_name = evt.target.options[preset_index].textContent
units_settings = g_controlnet_presets[preset_name]
ControlNetUnit.setUnits(units_settings)
} catch (e) {
console.warn(e)
}
})
document
.getElementById('bSetAllControlImage')
.addEventListener('click', async () => {
const selectionInfo = await selection.Selection.getSelectionInfoExe()
if (selectionInfo) {
const base64_image =
await g_generation_session.setControlNetImageHelper()
for (index = 0; index < g_controlnet_max_models; index++) {
await g_generation_session.setControlNetImage(
index,
base64_image
)
}
} else {
await note.Notification.inactiveSelectionArea()
}
})
function initControlNetUnitsEventListeners(controlnet_max_models) {
for (let index = 0; index < controlnet_max_models; index++) {
//event listeners
controlnetElement(
index,
'.slControlNetGuidanceStrengthStart_'
).addEventListener('input', (evt) => {
// debugger
const sd_value = general.mapRange(evt.target.value, 0, 100, 0, 1) // convert slider value to SD ready value
controlnetElement(
index,
'.lControlNetGuidanceStrengthStart_'
).textContent = Number(sd_value).toFixed(2)
})
controlnetElement(
index,
'.slControlNetGuidanceStrengthEnd_'
).addEventListener('input', (evt) => {
// debugger
const sd_value = general.mapRange(evt.target.value, 0, 100, 0, 1) // convert slider value to SD ready value
controlnetElement(
index,
'.lControlNetGuidanceStrengthEnd_'
).textContent = Number(sd_value).toFixed(2)
})
document
.querySelector(`#controlnet_settings_${index} .slControlNetWeight_`)
.addEventListener('input', (evt) => {
// debugger
const sd_value = general.mapRange(
evt.target.value,
0,
100,
0,
2
) // convert slider value to SD ready value
document.querySelector(
`#controlnet_settings_${index} .lControlNetWeight_`
).textContent = Number(sd_value).toFixed(2)
})
// controlnetElement(index, '.slControlNetProcessorRes_').addEventListener(
// 'input',
// (evt) => {
// // debugger
// const sd_value = general.mapRange(
// evt.target.value,
// 64,
// 2048,
// 64,
// 2048
// ) // convert slider value to SD ready value
// controlnetElement(index, '.lControlNetProcessorRes_').textContent =
// Number(sd_value).toFixed(2)
// }
// )
controlnetElement(index, '.slControlNetThreshold_A_').addEventListener(
'input',
(event) => {
const slider = event.target
const sd_value = Number(
general
.mapRange(
slider.value,
slider.min,
slider.max,
slider.dataset['sd_min'],
slider.dataset['sd_max']
)
.toFixed(2)
)
controlnetElement(index, '.lControlNetThreshold_A_').innerText =
String(sd_value)
// ControlNetUnit.setThreshold(index, 'a', sd_value)
// controlnetElement(index, '.lControlNetThreshold_A_').value =
// sd_value
}
)
controlnetElement(index, '.slControlNetThreshold_B_').addEventListener(
'input',
(event) => {
const slider = event.target
const sd_value = Number(
general
.mapRange(
slider.value,
slider.min,
slider.max,
slider.dataset['sd_min'],
slider.dataset['sd_max']
)
.toFixed(2)
)
controlnetElement(index, '.lControlNetThreshold_B_').innerText =
String(sd_value)
// ControlNetUnit.setThreshold(index, 'a', sd_value)
// controlnetElement(index, '.lControlNetThreshold_A_').value =
// sd_value
}
)
document
.querySelector(`#controlnet_settings_${index} .bSetControlImage_`)
.addEventListener('click', async () => {
const selectionInfo =
await selection.Selection.getSelectionInfoExe()
if (selectionInfo) {
// debugger
const base64_image =
await g_generation_session.setControlNetImageHelper()
await g_generation_session.setControlNetImage(
index,
base64_image
)
} else {
await note.Notification.inactiveSelectionArea()
}
})
document
.querySelector(`#controlnet_settings_${index} .bControlMask_`)
.addEventListener('click', async () => {
await previewAnnotator(index)
})
}
}
document
.getElementById('mControlNetPresetMenu')
.addEventListener('updatePresetMenuEvent', async (event) => {
// console.log("I'm listening on a custom event")
await populateControlNetPresetMenu()
})
async function previewAnnotator(index) {
try {
const controlnet_init_image =
g_generation_session.controlNetImage[index]
const _module = ControlNetUnit.getModule(index)
const processor_res = ControlNetUnit.getProcessorRes(index)
const threshold_a = ControlNetUnit.getThreshold(index, 'a')
const threshold_b = ControlNetUnit.getThreshold(index, 'b')
if (!controlnet_init_image) {
const error = 'ControlNet initial image is empty'
app.showAlert(error)
throw error
}
if (!_module || _module === 'none') {
const error = 'select a valid controlnet module (preprocessor)'
app.showAlert(error)
throw error
}
const detect_map = await requestControlNetDetectMap(
controlnet_init_image,
_module,
processor_res,
threshold_a,
threshold_b
)
const rgb_detect_map_url =
await io.convertBlackAndWhiteImageToRGBChannels3(detect_map)
const rgb_detect_map = general.base64UrlToBase64(rgb_detect_map_url)
g_generation_session.controlNetMask[index] = rgb_detect_map
html_manip.setControlMaskSrc(rgb_detect_map_url, index)
} catch (e) {
console.warn('PreviewAnnotator click(): index: ', index, e)
}
}
async function previewAnnotatorFromCanvas(index) {
try {
const _module = ControlNetUnit.getModule(index)
const width = html_manip.getWidth()
const height = html_manip.getHeight()
const selectionInfo = await psapi.getSelectionInfoExe()
g_generation_session.control_net_preview_selection_info = selectionInfo
const base64 = await io.IO.getSelectionFromCanvasAsBase64Interface_New(
width,
height,
selectionInfo,
true
)
if (!_module || _module === 'none') {
const error = 'select a valid controlnet module (preprocessor)'
app.showAlert(error)
throw error
}
const processor_res = ControlNetUnit.getProcessorRes(index)
const threshold_a = ControlNetUnit.getThreshold(index, 'a')
const threshold_b = ControlNetUnit.getThreshold(index, 'b')
const detect_map = await requestControlNetDetectMap(
base64,
_module,
processor_res,
threshold_a,
threshold_b
)
const rgb_detect_map_url =
await io.convertBlackAndWhiteImageToRGBChannels3(detect_map)
g_generation_session.controlNetMask[index] = detect_map
html_manip.setControlMaskSrc(rgb_detect_map_url, index)
} catch (e) {
console.warn('PreviewAnnotator click(): index: ', index, e)
}
}
// document
// .getElementById('bPreviewAnnotator_0')
// .addEventListener('click', async (event) => {
// const index = parseInt(event.target.dataset['controlnet-index'])
// await previewAnnotator(index)
// })
function initPreviewElement(index) {
//make init mask image use the thumbnail class with buttons
// const mask_image_html = document.getElementById(
// 'control_net_preview_image_0'
// )
const mask_image_html = controlnetElement(index, '.control_net_mask_')
const mask_parent_element = mask_image_html.parentElement
this.thumbnail_container = thumbnail.Thumbnail.wrapImgInContainer(
mask_image_html,
'viewer-image-container'
)
mask_parent_element.appendChild(thumbnail_container)
async function toCanvas(index) {
// debugger
if (
g_generation_session.control_net_preview_selection_info &&
g_generation_session.controlNetMask[index]
) {
const selection_info =
g_generation_session.control_net_preview_selection_info
const layer = await io.IO.base64ToLayer(
g_generation_session.controlNetMask[index],
'ControlNet Mask.png',
selection_info.left,
selection_info.top,
selection_info.width,
selection_info.height
)
} else {
// await note.Notification.inactiveSelectionArea()
app.showAlert('Mask Image is not available')
}
}
async function toControlNetInitImage(index) {
const preview_result_base64 = g_generation_session.controlNetMask[index]
g_generation_session.controlNetImage[index] = preview_result_base64
g_generation_session.control_net_selection_info =
g_generation_session.control_net_preview_selection_info
const rgb_detect_map_url =
await io.convertBlackAndWhiteImageToRGBChannels3(
preview_result_base64
)
// g_generation_session.controlNetMask[index] = rgb_detect_map
html_manip.setControlImageSrc(rgb_detect_map_url, index)
}
thumbnail.Thumbnail.addSPButtonToContainer(
this.thumbnail_container,
'svg_sp_btn',
'use as ControlNet init image',
toControlNetInitImage,
index
)
thumbnail.Thumbnail.addSPButtonToContainer(
this.thumbnail_container,
'svg_sp_btn_canvas',
'move to the canvas',
toCanvas,
index
)
thumbnail.Thumbnail.addSPButtonToContainer(
this.thumbnail_container,
'svg_sp_btn_preview',
'preview selection from canvas',
previewAnnotatorFromCanvas,
index
)
}
function initControlNetUnit(index) {
document.querySelector(
`#controlnet_settings_${index} .controlnet_unit_label_`
).textContent = `Control Net Settings Slot ${index}`
}
async function initializeControlNetTab(controlnet_max_models) {
try {
if (controlnet_max_models <= 0) {
document.getElementById('controlnetMissingError').style.display =
'block'
return
}
document.getElementById('controlnetMissingError').style.display = 'none'
// if (controlnet_max_models > g_controlnet_max_models)
// controlnet_max_models = g_controlnet_max_models
await populateControlNetPresetMenu()
const parent_container = document.getElementById(
'controlnet_parent_container'
)
parent_container.innerHTML = ''
const controlnet_unit_template = document.getElementById(
'controlnet_settings_template'
)
for (let index = 0; index < controlnet_max_models; index++) {
const controlnet_unit = controlnet_unit_template.cloneNode(true)
controlnet_unit.id = 'controlnet_settings_' + index
controlnet_unit.dataset['index'] = String(index)
parent_container.appendChild(controlnet_unit)
}
const full_url = `${g_sd_url}/controlnet/module_list?alias_names=1`
let result_json = await api.requestGet(full_url)
g_module_detail = result_json['module_detail']
initControlNetUnitsEventListeners(controlnet_max_models) // add event listener to all units after cloning
for (let index = 0; index < controlnet_max_models; index++) {
await populateModelMenu(index)
await populatePreprocessorMenu(index)
document.getElementById(
'controlnet_settings_' + index
).style.display = 'block'
initPreviewElement(index)
initControlNetUnit(index)
}
} catch (e) {
console.warn(e)
}
}
module.exports = {
requestControlNetModelList,
populateModelMenu,
initializeControlNetTab,
getWeight,
mapPluginSettingsToControlNet,
getEnableControlNet,
getSelectedModule,
getSelectedModel,
// getControlNetMaxModelsNumber,
getControlNetGuidanceStrengthStart,
setControlNetGuidanceStrengthStart,
getControlNetGuidanceStrengthEnd,
setControlNetGuidanceStrengthEnd,
ControlNetUnit,
populateControlNetPresetMenu,
isControlNetModeEnable,
getModuleDetail() {
return g_module_detail
}
}