Added high-res pass
This commit is contained in:
@ -9,10 +9,12 @@ class ImagePipeline:
|
|||||||
self.id_counter = 0
|
self.id_counter = 0
|
||||||
self.stages = {}
|
self.stages = {}
|
||||||
self.stagedata = {}
|
self.stagedata = {}
|
||||||
|
self.stagedata_full = {}
|
||||||
|
|
||||||
def register_stage(self, name: str):
|
def register_stage(self, name: str):
|
||||||
self.stages[self.id_counter] = name
|
self.stages[self.id_counter] = name
|
||||||
self.stagedata[self.id_counter] = None
|
self.stagedata[self.id_counter] = None
|
||||||
|
self.stagedata_full[self.id_counter] = None
|
||||||
self.bus.publish_deferred("pipeline_stages", self.stages)
|
self.bus.publish_deferred("pipeline_stages", self.stages)
|
||||||
self.id_counter += 1
|
self.id_counter += 1
|
||||||
return self.id_counter-1
|
return self.id_counter-1
|
||||||
@ -22,9 +24,17 @@ class ImagePipeline:
|
|||||||
self.stages[id] = name
|
self.stages[id] = name
|
||||||
self.bus.publish_deferred("pipeline_stages", self.stages)
|
self.bus.publish_deferred("pipeline_stages", self.stages)
|
||||||
|
|
||||||
def publish(self, id: int, img: np.ndarray):
|
def publish(self, id: int, img: np.ndarray, full_res=False):
|
||||||
|
if img is None:
|
||||||
|
return
|
||||||
|
if full_res:
|
||||||
|
self.stagedata_full[id] = img.astype(np.float32)
|
||||||
|
self.bus.publish_deferred(
|
||||||
|
"pipeline_stage_full", (id, self.stagedata_full[id]))
|
||||||
|
else:
|
||||||
self.stagedata[id] = img.astype(np.float32)
|
self.stagedata[id] = img.astype(np.float32)
|
||||||
self.bus.publish_deferred("pipeline_stage", (id, self.stagedata[id]))
|
self.bus.publish_deferred(
|
||||||
|
"pipeline_stage", (id, self.stagedata[id]))
|
||||||
|
|
||||||
def get_stage_data(self, id: int):
|
def get_stage_data(self, id: int):
|
||||||
if id >= 0 and id < len(self.stages):
|
if id >= 0 and id < len(self.stages):
|
||||||
|
@ -95,6 +95,9 @@ class EditorManager:
|
|||||||
dpg.add_menu_item(
|
dpg.add_menu_item(
|
||||||
label="Save Layout", callback=self.layout_manager.save_layout
|
label="Save Layout", callback=self.layout_manager.save_layout
|
||||||
)
|
)
|
||||||
|
dpg.add_menu_item(
|
||||||
|
label="Run full-res pipeline", callback=lambda: self.bus.publish_deferred("process_full_res", None)
|
||||||
|
)
|
||||||
dpg.add_menu_item(
|
dpg.add_menu_item(
|
||||||
label="Quit", callback=lambda: dpg.stop_dearpygui()
|
label="Quit", callback=lambda: dpg.stop_dearpygui()
|
||||||
)
|
)
|
||||||
|
33
negstation/widgets/export_widget.py
Normal file
33
negstation/widgets/export_widget.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import dearpygui.dearpygui as dpg
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from .pipeline_stage_widget import PipelineStageWidget
|
||||||
|
|
||||||
|
|
||||||
|
class ExportStage(PipelineStageWidget):
|
||||||
|
name = "Export Image"
|
||||||
|
register = True
|
||||||
|
has_pipeline_in = True
|
||||||
|
has_pipeline_out = False
|
||||||
|
|
||||||
|
def __init__(self, manager, logger):
|
||||||
|
super().__init__(manager, logger, default_stage_out="opened_image")
|
||||||
|
self.manager.bus.subscribe(
|
||||||
|
"process_full_res", self._on_process_full_res, True)
|
||||||
|
|
||||||
|
def create_pipeline_stage_content(self):
|
||||||
|
dpg.add_text("Some export fields")
|
||||||
|
|
||||||
|
def _on_process_full_res(self, data):
|
||||||
|
self.logger.info("Starting full res pipeline export")
|
||||||
|
|
||||||
|
def on_pipeline_data(self, img):
|
||||||
|
if img is None:
|
||||||
|
return
|
||||||
|
self.logger.info("low res image received, ignore")
|
||||||
|
|
||||||
|
def on_full_res_pipeline_data(self, img):
|
||||||
|
if img is None:
|
||||||
|
return
|
||||||
|
h, w, _ = img.shape
|
||||||
|
self.logger.info(f"Full res image received: {w}x{h}")
|
@ -15,6 +15,11 @@ class OpenImageWidget(PipelineStageWidget):
|
|||||||
super().__init__(manager, logger, default_stage_out="opened_image")
|
super().__init__(manager, logger, default_stage_out="opened_image")
|
||||||
self.dialog_tag = dpg.generate_uuid()
|
self.dialog_tag = dpg.generate_uuid()
|
||||||
self.output_tag = dpg.generate_uuid()
|
self.output_tag = dpg.generate_uuid()
|
||||||
|
self.img = None
|
||||||
|
self.img_full = None
|
||||||
|
|
||||||
|
self.manager.bus.subscribe(
|
||||||
|
"process_full_res", self._on_process_full_res, True)
|
||||||
|
|
||||||
def create_pipeline_stage_content(self):
|
def create_pipeline_stage_content(self):
|
||||||
with dpg.file_dialog(
|
with dpg.file_dialog(
|
||||||
@ -46,9 +51,30 @@ class OpenImageWidget(PipelineStageWidget):
|
|||||||
self.logger.info(f"Selected file '{selection}'")
|
self.logger.info(f"Selected file '{selection}'")
|
||||||
try:
|
try:
|
||||||
img = Image.open(selection).convert("RGBA")
|
img = Image.open(selection).convert("RGBA")
|
||||||
arr = np.asarray(img).astype(np.float32) / \
|
rgba = np.asarray(img).astype(np.float32) / \
|
||||||
255.0 # normalize to [0,1]
|
255.0 # normalize to [0,1]
|
||||||
# Publish into pipeline
|
h, w, _ = rgba.shape
|
||||||
self.manager.pipeline.publish(self.pipeline_stage_out_id, arr)
|
|
||||||
|
# scale for small version
|
||||||
|
max_dim = 500
|
||||||
|
scale = min(1.0, max_dim / w, max_dim / h)
|
||||||
|
if scale < 1.0:
|
||||||
|
# convert to 0–255 uint8, resize with PIL, back to float32 [0–1]
|
||||||
|
pil = Image.fromarray(
|
||||||
|
(rgba * 255).astype(np.uint8), mode="RGBA")
|
||||||
|
new_w, new_h = int(w * scale), int(h * scale)
|
||||||
|
pil = pil.resize((new_w, new_h), Image.LANCZOS)
|
||||||
|
rgba_small = np.asarray(pil).astype(np.float32) / 255.0
|
||||||
|
w_small, h_small = new_w, new_h
|
||||||
|
|
||||||
|
self.img_full = rgba
|
||||||
|
self.img = rgba_small
|
||||||
|
|
||||||
|
self.manager.pipeline.publish(
|
||||||
|
self.pipeline_stage_out_id, rgba_small)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Failed to load image {selection}: {e}")
|
self.logger.error(f"Failed to load image {selection}: {e}")
|
||||||
|
|
||||||
|
def _on_process_full_res(self, data):
|
||||||
|
self.manager.pipeline.publish(
|
||||||
|
self.pipeline_stage_out_id, self.img_full, True)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import dearpygui.dearpygui as dpg
|
import dearpygui.dearpygui as dpg
|
||||||
import rawpy
|
import rawpy
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from .pipeline_stage_widget import PipelineStageWidget
|
from .pipeline_stage_widget import PipelineStageWidget
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ class OpenRawWidget(PipelineStageWidget):
|
|||||||
self.config_group = dpg.generate_uuid()
|
self.config_group = dpg.generate_uuid()
|
||||||
self.busy_group = dpg.generate_uuid()
|
self.busy_group = dpg.generate_uuid()
|
||||||
self.raw_path = None
|
self.raw_path = None
|
||||||
|
self.img = None
|
||||||
|
self.img_full = None
|
||||||
self.config = {
|
self.config = {
|
||||||
# Demosaic algorithm
|
# Demosaic algorithm
|
||||||
"demosaic_algorithm": rawpy.DemosaicAlgorithm.AHD,
|
"demosaic_algorithm": rawpy.DemosaicAlgorithm.AHD,
|
||||||
@ -39,6 +42,9 @@ class OpenRawWidget(PipelineStageWidget):
|
|||||||
"four_color_rgb": False,
|
"four_color_rgb": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.manager.bus.subscribe(
|
||||||
|
"process_full_res", self._on_process_full_res, True)
|
||||||
|
|
||||||
def get_config(self):
|
def get_config(self):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@ -203,6 +209,26 @@ class OpenRawWidget(PipelineStageWidget):
|
|||||||
|
|
||||||
rgba = np.concatenate([rgb_float, alpha], axis=2)
|
rgba = np.concatenate([rgb_float, alpha], axis=2)
|
||||||
|
|
||||||
self.manager.pipeline.publish(self.pipeline_stage_out_id, rgba)
|
# scale for small version
|
||||||
|
max_dim = 500
|
||||||
|
scale = min(1.0, max_dim / w, max_dim / h)
|
||||||
|
if scale < 1.0:
|
||||||
|
# convert to 0–255 uint8, resize with PIL, back to float32 [0–1]
|
||||||
|
pil = Image.fromarray((rgba * 255).astype(np.uint8), mode="RGBA")
|
||||||
|
new_w, new_h = int(w * scale), int(h * scale)
|
||||||
|
pil = pil.resize((new_w, new_h), Image.LANCZOS)
|
||||||
|
rgba_small = np.asarray(pil).astype(np.float32) / 255.0
|
||||||
|
w_small, h_small = new_w, new_h
|
||||||
|
|
||||||
|
self.img_full = rgba
|
||||||
|
self.img = rgba_small
|
||||||
|
|
||||||
|
self.manager.pipeline.publish(self.pipeline_stage_out_id, rgba_small)
|
||||||
dpg.configure_item(self.config_group, show=True)
|
dpg.configure_item(self.config_group, show=True)
|
||||||
dpg.configure_item(self.busy_group, show=False)
|
dpg.configure_item(self.busy_group, show=False)
|
||||||
|
|
||||||
|
def _on_process_full_res(self, data):
|
||||||
|
if self.img_full is None:
|
||||||
|
return
|
||||||
|
self.manager.pipeline.publish(
|
||||||
|
self.pipeline_stage_out_id, self.img_full, True)
|
||||||
|
@ -23,16 +23,21 @@ class PipelineStageWidget(BaseWidget):
|
|||||||
self.pipeline_stage_out_id = None
|
self.pipeline_stage_out_id = None
|
||||||
self.pipeline_config_group_tag = dpg.generate_uuid()
|
self.pipeline_config_group_tag = dpg.generate_uuid()
|
||||||
self.stage_in_combo = dpg.generate_uuid()
|
self.stage_in_combo = dpg.generate_uuid()
|
||||||
|
self._last_full = False
|
||||||
|
|
||||||
if self.has_pipeline_out:
|
if self.has_pipeline_out:
|
||||||
self.pipeline_stage_out_id = self.manager.pipeline.register_stage(
|
self.pipeline_stage_out_id = self.manager.pipeline.register_stage(
|
||||||
default_stage_out
|
default_stage_out
|
||||||
)
|
)
|
||||||
|
|
||||||
self.manager.bus.subscribe("pipeline_stages", self._on_stage_list, True)
|
self.manager.bus.subscribe(
|
||||||
|
"pipeline_stages", self._on_stage_list, True)
|
||||||
if self.has_pipeline_in:
|
if self.has_pipeline_in:
|
||||||
self.pipeline_stage_in_id = 0
|
self.pipeline_stage_in_id = 0
|
||||||
self.manager.bus.subscribe("pipeline_stage", self._on_stage_data, True)
|
self.manager.bus.subscribe(
|
||||||
|
"pipeline_stage", self._on_stage_data, True)
|
||||||
|
self.manager.bus.subscribe(
|
||||||
|
"pipeline_stage_full", self._on_stage_data_full, True)
|
||||||
# force getting all available pipeline stages
|
# force getting all available pipeline stages
|
||||||
self.manager.pipeline.republish_stages()
|
self.manager.pipeline.republish_stages()
|
||||||
|
|
||||||
@ -43,7 +48,8 @@ class PipelineStageWidget(BaseWidget):
|
|||||||
label="Stage In",
|
label="Stage In",
|
||||||
items=[],
|
items=[],
|
||||||
callback=self._on_stage_in_select,
|
callback=self._on_stage_in_select,
|
||||||
default_value=f"{self.manager.pipeline.get_stage_name(0)} : 0",
|
default_value=f"{
|
||||||
|
self.manager.pipeline.get_stage_name(0)} : 0",
|
||||||
tag=self.stage_in_combo
|
tag=self.stage_in_combo
|
||||||
)
|
)
|
||||||
if self.has_pipeline_out:
|
if self.has_pipeline_out:
|
||||||
@ -59,11 +65,6 @@ class PipelineStageWidget(BaseWidget):
|
|||||||
dpg.add_separator()
|
dpg.add_separator()
|
||||||
self.create_pipeline_stage_content()
|
self.create_pipeline_stage_content()
|
||||||
|
|
||||||
def publish_stage(self, img: np.ndarray):
|
|
||||||
"""Publishes an image to output stage"""
|
|
||||||
if self.has_pipeline_out:
|
|
||||||
self.manager.pipeline.publish(self.pipeline_stage_out_id, img)
|
|
||||||
|
|
||||||
def create_pipeline_stage_content(self):
|
def create_pipeline_stage_content(self):
|
||||||
"""Must be implemented by the widget, creates the content of the window"""
|
"""Must be implemented by the widget, creates the content of the window"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -72,6 +73,12 @@ class PipelineStageWidget(BaseWidget):
|
|||||||
"""Must be implemented by the widget, is called when there is a new image published on the in stage"""
|
"""Must be implemented by the widget, is called when there is a new image published on the in stage"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def publish_stage(self, img):
|
||||||
|
"""Publishes an image to output stage"""
|
||||||
|
if self.has_pipeline_out:
|
||||||
|
self.manager.pipeline.publish(
|
||||||
|
self.pipeline_stage_out_id, img, full_res=self._last_full)
|
||||||
|
|
||||||
# Callbacks
|
# Callbacks
|
||||||
|
|
||||||
def _on_window_close(self):
|
def _on_window_close(self):
|
||||||
@ -97,12 +104,25 @@ class PipelineStageWidget(BaseWidget):
|
|||||||
pipeline_id = data[0]
|
pipeline_id = data[0]
|
||||||
img = data[1]
|
img = data[1]
|
||||||
if self.has_pipeline_in and pipeline_id == self.pipeline_stage_in_id:
|
if self.has_pipeline_in and pipeline_id == self.pipeline_stage_in_id:
|
||||||
|
self._last_full = False
|
||||||
|
self.on_pipeline_data(img)
|
||||||
|
|
||||||
|
def _on_stage_data_full(self, data):
|
||||||
|
pipeline_id = data[0]
|
||||||
|
img = data[1]
|
||||||
|
if self.has_pipeline_in and pipeline_id == self.pipeline_stage_in_id:
|
||||||
|
self._last_full = True
|
||||||
|
if hasattr(self, "on_full_res_pipeline_data"):
|
||||||
|
self.on_full_res_pipeline_data(img)
|
||||||
|
else:
|
||||||
self.on_pipeline_data(img)
|
self.on_pipeline_data(img)
|
||||||
|
|
||||||
# Override the window resize callback
|
# Override the window resize callback
|
||||||
|
|
||||||
def _on_window_resize(self, data):
|
def _on_window_resize(self, data):
|
||||||
win_w, win_h = dpg.get_item_rect_size(self.window_tag)
|
win_w, win_h = dpg.get_item_rect_size(self.window_tag)
|
||||||
group_w, group_h = dpg.get_item_rect_size(self.pipeline_config_group_tag)
|
group_w, group_h = dpg.get_item_rect_size(
|
||||||
|
self.pipeline_config_group_tag)
|
||||||
group_x, group_y = dpg.get_item_pos(self.pipeline_config_group_tag)
|
group_x, group_y = dpg.get_item_pos(self.pipeline_config_group_tag)
|
||||||
self.window_height = win_h - group_h - group_y - 12
|
self.window_height = win_h - group_h - group_y - 12
|
||||||
self.window_width = win_w - 7
|
self.window_width = win_w - 7
|
||||||
|
@ -31,19 +31,13 @@ class PipelineStageViewer(PipelineStageWidget):
|
|||||||
if img is None:
|
if img is None:
|
||||||
return
|
return
|
||||||
h, w, _ = img.shape
|
h, w, _ = img.shape
|
||||||
max_dim = 500
|
|
||||||
scale = min(1.0, max_dim / w, max_dim / h)
|
|
||||||
if scale < 1.0:
|
|
||||||
# convert to 0–255 uint8, resize with PIL, back to float32 [0–1]
|
|
||||||
pil = Image.fromarray((img * 255).astype(np.uint8), mode="RGBA")
|
|
||||||
new_w, new_h = int(w * scale), int(h * scale)
|
|
||||||
pil = pil.resize((new_w, new_h), Image.LANCZOS)
|
|
||||||
img = np.asarray(pil).astype(np.float32) / 255.0
|
|
||||||
w, h = new_w, new_h
|
|
||||||
|
|
||||||
self.img = img
|
self.img = img
|
||||||
self.needs_update = True
|
self.needs_update = True
|
||||||
|
|
||||||
|
def on_full_res_pipeline_data(self, img):
|
||||||
|
pass
|
||||||
|
|
||||||
def update_texture(self, img: np.ndarray):
|
def update_texture(self, img: np.ndarray):
|
||||||
"""Only call from update function"""
|
"""Only call from update function"""
|
||||||
# TODO show a smaller version of the image to speed things up
|
# TODO show a smaller version of the image to speed things up
|
||||||
|
@ -60,7 +60,7 @@ DockId=0x00000012,0
|
|||||||
Pos=198,19
|
Pos=198,19
|
||||||
Size=602,425
|
Size=602,425
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000011,0
|
DockId=0x0000000F,0
|
||||||
|
|
||||||
[Window][###49]
|
[Window][###49]
|
||||||
Pos=0,495
|
Pos=0,495
|
||||||
@ -72,7 +72,7 @@ DockId=0x0000000C,0
|
|||||||
Pos=246,19
|
Pos=246,19
|
||||||
Size=554,379
|
Size=554,379
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000011,0
|
DockId=0x0000000F,0
|
||||||
|
|
||||||
[Window][###60]
|
[Window][###60]
|
||||||
Pos=0,19
|
Pos=0,19
|
||||||
@ -81,16 +81,16 @@ Collapsed=0
|
|||||||
DockId=0x00000012,1
|
DockId=0x00000012,1
|
||||||
|
|
||||||
[Window][###107]
|
[Window][###107]
|
||||||
Pos=246,400
|
Pos=939,19
|
||||||
Size=554,200
|
Size=261,534
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000016,0
|
DockId=0x00000011,0
|
||||||
|
|
||||||
[Window][###35]
|
[Window][###35]
|
||||||
Pos=272,19
|
Pos=272,19
|
||||||
Size=710,625
|
Size=710,625
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000011,0
|
DockId=0x0000000F,0
|
||||||
|
|
||||||
[Window][###43]
|
[Window][###43]
|
||||||
Pos=0,490
|
Pos=0,490
|
||||||
@ -117,16 +117,16 @@ Collapsed=0
|
|||||||
DockId=0x00000015,0
|
DockId=0x00000015,0
|
||||||
|
|
||||||
[Window][###111]
|
[Window][###111]
|
||||||
Pos=900,19
|
Pos=984,412
|
||||||
Size=300,781
|
Size=216,388
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000001A,0
|
DockId=0x0000001A,0
|
||||||
|
|
||||||
[Window][###96]
|
[Window][###96]
|
||||||
Pos=984,19
|
Pos=984,19
|
||||||
Size=216,781
|
Size=216,391
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000001D,0
|
DockId=0x00000019,0
|
||||||
|
|
||||||
[Window][###127]
|
[Window][###127]
|
||||||
Pos=984,365
|
Pos=984,365
|
||||||
@ -134,11 +134,49 @@ Size=216,435
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000001E,0
|
DockId=0x0000001E,0
|
||||||
|
|
||||||
|
[Window][###125]
|
||||||
|
Pos=984,600
|
||||||
|
Size=216,200
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000022,0
|
||||||
|
|
||||||
|
[Window][###103]
|
||||||
|
Pos=984,19
|
||||||
|
Size=216,579
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000025,0
|
||||||
|
|
||||||
|
[Window][###139]
|
||||||
|
Pos=984,600
|
||||||
|
Size=216,200
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000026,0
|
||||||
|
|
||||||
|
[Window][###101]
|
||||||
|
Pos=984,19
|
||||||
|
Size=216,609
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000029,0
|
||||||
|
|
||||||
|
[Window][###121]
|
||||||
|
Pos=984,630
|
||||||
|
Size=216,170
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x0000002A,0
|
||||||
|
|
||||||
|
[Window][###129]
|
||||||
|
Pos=939,555
|
||||||
|
Size=261,245
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000016,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,781 Split=X
|
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,781 Split=X
|
||||||
DockNode ID=0x0000001B Parent=0x7C6B3D9B SizeRef=982,781 Split=X
|
DockNode ID=0x0000002B Parent=0x7C6B3D9B SizeRef=937,781 Split=X
|
||||||
DockNode ID=0x00000019 Parent=0x0000001B SizeRef=898,781 Split=X
|
DockNode ID=0x00000027 Parent=0x0000002B SizeRef=982,781 Split=X
|
||||||
DockNode ID=0x00000017 Parent=0x00000019 SizeRef=898,781 Split=X
|
DockNode ID=0x00000023 Parent=0x00000027 SizeRef=982,781 Split=X
|
||||||
|
DockNode ID=0x0000001B Parent=0x00000023 SizeRef=982,781 Split=X
|
||||||
|
DockNode ID=0x00000017 Parent=0x0000001B SizeRef=898,781 Split=X
|
||||||
DockNode ID=0x00000009 Parent=0x00000017 SizeRef=270,581 Split=Y Selected=0x3BEDC6B0
|
DockNode ID=0x00000009 Parent=0x00000017 SizeRef=270,581 Split=Y Selected=0x3BEDC6B0
|
||||||
DockNode ID=0x0000000B Parent=0x00000009 SizeRef=196,474 Split=Y Selected=0x3BEDC6B0
|
DockNode ID=0x0000000B Parent=0x00000009 SizeRef=196,474 Split=Y Selected=0x3BEDC6B0
|
||||||
DockNode ID=0x0000000D Parent=0x0000000B SizeRef=196,99 Split=Y Selected=0x99D84869
|
DockNode ID=0x0000000D Parent=0x0000000B SizeRef=196,99 Split=Y Selected=0x99D84869
|
||||||
@ -150,7 +188,7 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,7
|
|||||||
DockNode ID=0x00000015 Parent=0x00000013 SizeRef=244,154 Selected=0x8773D56E
|
DockNode ID=0x00000015 Parent=0x00000013 SizeRef=244,154 Selected=0x8773D56E
|
||||||
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=196,373 Selected=0x3BEDC6B0
|
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=196,373 Selected=0x3BEDC6B0
|
||||||
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=196,105 Selected=0x4F81AB74
|
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=196,105 Selected=0x4F81AB74
|
||||||
DockNode ID=0x0000000A Parent=0x00000017 SizeRef=710,581 Split=X
|
DockNode ID=0x0000000A Parent=0x00000017 SizeRef=665,581 Split=X
|
||||||
DockNode ID=0x00000003 Parent=0x0000000A SizeRef=299,581 Split=Y Selected=0x52849BCC
|
DockNode ID=0x00000003 Parent=0x0000000A SizeRef=299,581 Split=Y Selected=0x52849BCC
|
||||||
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=299,473 Split=Y Selected=0x52849BCC
|
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=299,473 Split=Y Selected=0x52849BCC
|
||||||
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=299,86 Selected=0x52849BCC
|
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=299,86 Selected=0x52849BCC
|
||||||
@ -158,14 +196,24 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,7
|
|||||||
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=299,106 Selected=0x84DD78D1
|
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=299,106 Selected=0x84DD78D1
|
||||||
DockNode ID=0x00000004 Parent=0x0000000A SizeRef=499,581 Split=Y
|
DockNode ID=0x00000004 Parent=0x0000000A SizeRef=499,581 Split=Y
|
||||||
DockNode ID=0x00000001 Parent=0x00000004 SizeRef=800,379 Split=Y Selected=0x7FF1E0B5
|
DockNode ID=0x00000001 Parent=0x00000004 SizeRef=800,379 Split=Y Selected=0x7FF1E0B5
|
||||||
DockNode ID=0x0000000F Parent=0x00000001 SizeRef=602,425 Split=Y Selected=0x38519A65
|
DockNode ID=0x0000000F Parent=0x00000001 SizeRef=602,425 CentralNode=1 Selected=0x977476CD
|
||||||
DockNode ID=0x00000011 Parent=0x0000000F SizeRef=554,379 CentralNode=1 Selected=0x977476CD
|
|
||||||
DockNode ID=0x00000016 Parent=0x0000000F SizeRef=554,200 Selected=0x3A881EEF
|
|
||||||
DockNode ID=0x00000010 Parent=0x00000001 SizeRef=602,154 Selected=0x083320CE
|
DockNode ID=0x00000010 Parent=0x00000001 SizeRef=602,154 Selected=0x083320CE
|
||||||
DockNode ID=0x00000002 Parent=0x00000004 SizeRef=800,200 Selected=0x1834836D
|
DockNode ID=0x00000002 Parent=0x00000004 SizeRef=800,200 Selected=0x1834836D
|
||||||
DockNode ID=0x00000018 Parent=0x00000019 SizeRef=300,781 Selected=0x7E9438EA
|
DockNode ID=0x00000018 Parent=0x0000001B SizeRef=300,781 Selected=0x7E9438EA
|
||||||
DockNode ID=0x0000001A Parent=0x0000001B SizeRef=300,781 Selected=0x7E9438EA
|
DockNode ID=0x0000001C Parent=0x00000023 SizeRef=216,781 Split=Y Selected=0x714F2F7B
|
||||||
DockNode ID=0x0000001C Parent=0x7C6B3D9B SizeRef=216,781 Split=Y Selected=0x714F2F7B
|
DockNode ID=0x0000001D Parent=0x0000001C SizeRef=216,344 Split=Y Selected=0x714F2F7B
|
||||||
DockNode ID=0x0000001D Parent=0x0000001C SizeRef=216,344 Selected=0x714F2F7B
|
DockNode ID=0x00000021 Parent=0x0000001D SizeRef=216,579 Split=Y Selected=0x714F2F7B
|
||||||
|
DockNode ID=0x00000019 Parent=0x00000021 SizeRef=216,391 Selected=0x714F2F7B
|
||||||
|
DockNode ID=0x0000001A Parent=0x00000021 SizeRef=216,388 Selected=0x7E9438EA
|
||||||
|
DockNode ID=0x00000022 Parent=0x0000001D SizeRef=216,200 Selected=0x0D80EC84
|
||||||
DockNode ID=0x0000001E Parent=0x0000001C SizeRef=216,435 Selected=0x7740BFE4
|
DockNode ID=0x0000001E Parent=0x0000001C SizeRef=216,435 Selected=0x7740BFE4
|
||||||
|
DockNode ID=0x00000024 Parent=0x00000027 SizeRef=216,781 Split=Y Selected=0xCF08B82F
|
||||||
|
DockNode ID=0x00000025 Parent=0x00000024 SizeRef=216,579 Selected=0xCF08B82F
|
||||||
|
DockNode ID=0x00000026 Parent=0x00000024 SizeRef=216,200 Selected=0x032CD220
|
||||||
|
DockNode ID=0x00000028 Parent=0x0000002B SizeRef=216,781 Split=Y Selected=0xB5C8EB4F
|
||||||
|
DockNode ID=0x00000029 Parent=0x00000028 SizeRef=216,609 Selected=0xB5C8EB4F
|
||||||
|
DockNode ID=0x0000002A Parent=0x00000028 SizeRef=216,170 Selected=0xF8004A44
|
||||||
|
DockNode ID=0x0000002C Parent=0x7C6B3D9B SizeRef=261,781 Split=Y Selected=0xC8700185
|
||||||
|
DockNode ID=0x00000011 Parent=0x0000002C SizeRef=142,534 Selected=0x3A881EEF
|
||||||
|
DockNode ID=0x00000016 Parent=0x0000002C SizeRef=142,245 Selected=0xC8700185
|
||||||
|
|
||||||
|
@ -26,5 +26,9 @@
|
|||||||
{
|
{
|
||||||
"widget_type": "HistogramWidget",
|
"widget_type": "HistogramWidget",
|
||||||
"config": {}
|
"config": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widget_type": "ExportStage",
|
||||||
|
"config": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
Reference in New Issue
Block a user