Commit 31fcc689 authored by Andrey Filippov's avatar Andrey Filippov

Implementing quasi-parallel processing using GUI and MCP

parent 30b9d3f9
......@@ -3407,13 +3407,19 @@ public class CLTParameters {
}
public boolean showJDialog() {
return showJDialog(false);
return showJDialog(false, GenericJTabbedDialogMcp.isDefaultMcpMode());
}
// codex 2026-01-27: optional modeless dialog for MCP/GUI co-use
public boolean showJDialog(boolean nonBlocking) {
return showJDialog(nonBlocking, GenericJTabbedDialogMcp.isDefaultMcpMode());
}
// codex 2026-01-28: allow forcing GUI vs MCP mode per call
public boolean showJDialog(boolean nonBlocking, boolean useMcp) {
// GenericDialog gd = new GenericDialog("Set CLT parameters");
GenericJTabbedDialogMcp gd = new GenericJTabbedDialogMcp("Set CLT parameters",1090,900, !nonBlocking); // codex 2026-01-25
gd.setMcpMode(useMcp);
gd.addTab ("General", "General parameters");
gd.addNumericField("Nominal (rectilinear) disparity between side of square cameras (pix)", this.disparity, 3,7,"pix",
"Used when rendering 4 images");
......
......@@ -1195,17 +1195,26 @@ public class EyesisCorrectionParameters {
}
public boolean showCLTBatchDialog(String title,
CLTParameters clt_parameters) {
return showCLTBatchDialog(title, clt_parameters, false);
}
public boolean showCLTBatchDialog(String title,
CLTParameters clt_parameters) {
return showCLTBatchDialog(title, clt_parameters, false, GenericJTabbedDialogMcp.isDefaultMcpMode());
}
// codex 2026-01-27: optional modeless dialog for MCP/GUI co-use
public boolean showCLTBatchDialog(String title,
CLTParameters clt_parameters,
boolean nonBlocking) {
GenericJTabbedDialogMcp gd = new GenericJTabbedDialogMcp(title,1000,1000, !nonBlocking); // codex 2026-01-25
updateAuxFromMain();
// codex 2026-01-27: optional modeless dialog for MCP/GUI co-use
public boolean showCLTBatchDialog(String title,
CLTParameters clt_parameters,
boolean nonBlocking) {
return showCLTBatchDialog(title, clt_parameters, nonBlocking, GenericJTabbedDialogMcp.isDefaultMcpMode());
}
// codex 2026-01-28: allow forcing GUI vs MCP mode per call
public boolean showCLTBatchDialog(String title,
CLTParameters clt_parameters,
boolean nonBlocking,
boolean useMcp) {
GenericJTabbedDialogMcp gd = new GenericJTabbedDialogMcp(title,1000,1000, !nonBlocking); // codex 2026-01-25
gd.setMcpMode(useMcp);
updateAuxFromMain();
gd.addTab ("File paths", "Select files and directories paths (common to main and optional auxiliary)");
......@@ -1792,7 +1801,8 @@ public class EyesisCorrectionParameters {
base_path=base_path.resolve(Paths.get(dir_map.get("rootDirectory")));
File base_dir = new File(base_path.toString());
if (!base_dir.exists()) {
base_dir.mkdirs(); // codex 2026-01-28: mkdirs side-effect (consider guarding)
System.out.println("Root directory "+base_path.toString()+" does not exist, ignoring "+seq_str);
return null;
}
}
// set sourceDirectory:
......@@ -1808,7 +1818,8 @@ public class EyesisCorrectionParameters {
Path source_path = Paths.get(this.sourceDirectory);
File source_dir = new File(source_path.toString());
if (!source_dir.exists()) {
source_dir.mkdirs(); // codex 2026-01-28: mkdirs side-effect (consider guarding)
System.out.println("Source directory "+source_path.toString()+" does not exist, ignoring "+seq_str);
return null;
}
useCuasSeedDir = false;
......@@ -1821,7 +1832,8 @@ public class EyesisCorrectionParameters {
File dir_file = new File(dir_path.toString());
if ((i != KEY_INDEX_UAS_LOGS) && (i != KEY_INDEX_SKY_MASK)) { // cuasUasLogs, cuasSkyMask are files, not directories
if (!dir_file.exists()) {
dir_file.mkdirs(); // codex 2026-01-28: mkdirs side-effect (consider guarding)
System.out.println(KEY_DIRS[i]+" directory "+dir_path.toString()+" does not exist, ignoring "+seq_str);
return null;
}
}
dir_string = dir_path.toString();
......
......@@ -12,7 +12,9 @@ import ij.IJ;
public class GenericJTabbedDialogMcp extends GenericJTabbedDialog{
// codex 2026-01-25: MCP dialog capture state
private static boolean defaultMcpMode = false;
private static long dialogTimeoutMs = 30000L;
public boolean mcp_mode = false;
private boolean mcpCanceled = false;
private final List<McpDialogField> mcpFields = new ArrayList<McpDialogField>();
private final String dialogTitle;
private String currentTab = "";
......@@ -42,6 +44,14 @@ public class GenericJTabbedDialogMcp extends GenericJTabbedDialog{
public static boolean isDefaultMcpMode() {
return defaultMcpMode;
}
// codex 2026-01-28: configurable MCP dialog submit timeout (0 = wait forever)
public static void setDialogTimeoutMs(long timeoutMs) {
dialogTimeoutMs = timeoutMs;
}
// codex 2026-01-28: override MCP mode per dialog instance
public void setMcpMode(boolean enabled) {
this.mcp_mode = enabled;
}
private void addMcpField(McpDialogField field) {
mcpFields.add(field);
......@@ -121,6 +131,16 @@ public class GenericJTabbedDialogMcp extends GenericJTabbedDialog{
else super.addChoice(label, items, defaultItem, tooltip, count);
}
@Override
public void addChoice(String label, String[] items, String defaultItem) {
addChoice(label, items, defaultItem, null, 0);
}
@Override
public void addChoice(String label, String[] items, String defaultItem, String tooltip) {
addChoice(label, items, defaultItem, tooltip, 0);
}
@Override
public void addDefaultButtons() { // not used
if (mcp_mode) {
......@@ -149,7 +169,10 @@ public class GenericJTabbedDialogMcp extends GenericJTabbedDialog{
if (mcp_mode) {
// codex 2026-01-25: publish dialog schema to MCP registry
readIndex = 0;
McpDialogRegistry.setCurrent(new McpDialogSession(dialogTitle, mcpFields));
boolean applied = McpDialogRegistry.setCurrent(new McpDialogSession(dialogTitle, mcpFields));
if (!applied) {
System.out.println("MCP: dialog already active, ignoring \"" + dialogTitle + "\"");
}
}
else super.buildDialog();
}
......@@ -253,6 +276,17 @@ public class GenericJTabbedDialogMcp extends GenericJTabbedDialog{
public boolean showDialog() {
if (mcp_mode) {
buildDialog();
McpDialogSession session = McpDialogRegistry.getCurrent();
if (session != null) {
long timeout = dialogTimeoutMs;
Boolean ok = (timeout <= 0) ? session.awaitSubmit(Long.MAX_VALUE) : session.awaitSubmit(timeout);
if (ok != null && !ok.booleanValue()) {
mcpCanceled = true;
} else {
mcpCanceled = false;
}
}
McpDialogRegistry.setCurrent(null);
return true;
}
else return super.showDialog();
......@@ -279,7 +313,7 @@ public class GenericJTabbedDialogMcp extends GenericJTabbedDialog{
@Override
public boolean wasCanceled() {
if (mcp_mode) {
return false;
return mcpCanceled;
}
else return super.wasCanceled();
}
......
......@@ -479,6 +479,11 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
public static String DEFAULT_DIRECTORY = null;
// codex 2026-01-28: remember last MCP-selected paths per dialog title
private static final HashMap<String, String> MCP_LAST_PATHS = new HashMap<String, String>();
// codex 2026-01-28: current command origin (MCP vs GUI) for file dialogs
private static volatile boolean MCP_COMMAND_CONTEXT = false;
// codex 2026-01-28: MCP debug output control
public static final int MINIMAL_DEBUG_MCP = -2;
public static int MCP_DEBUG_LEVEL = -1;
public static boolean ADVANCED_MODE = false; // true; // show all buttons
public static boolean DCT_MODE = false; // true; // show all buttons
public static boolean MODE_3D = false; // 3D-related commands
......@@ -489,7 +494,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
public ImagePlus CORRELATE_IMP = null;
public TensorflowInferModel TENSORFLOW_INFER_MODEL = null;
public boolean use_swing = true; // false;
// public boolean use_swing = true; // false;
private PlugInFrame plugInFrame;
private JFrame plugInJFrame;
// static Frame instance;
......@@ -499,6 +504,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
private JPanel jpanel1, jpanel2, jpanel3, jpanel4, jpanel5, jpanel5a, jpanel6, jpanel7, jpanelPostProcessing1,
jpanelPostProcessing2, jpanelPostProcessing3, jpanelDct1, jpanelClt1, jpanelClt2, jpanelClt3, jpanelClt4,
jpanelClt5, jpanelClt5aux, jpanelClt_GPU, jpanelLWIR, jpanelLWIR16, jpanelLWIRWorld, jpanelOrange;
private boolean commandFromMcp = false;
// EyesisTopFrame eyesisTopFrame = new EyesisTopFrame();
// System.out.println("Launched EyesisTopFrame");
......@@ -535,6 +541,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
LogTee.install(); // once, early
// codex 2026-01-25: start MCP server + enable MCP dialog mode by default
GenericJTabbedDialogMcp.setDefaultMcpMode(getMcpMode());
GenericJTabbedDialogMcp.setDialogTimeoutMs(getMcpDialogTimeoutMs());
MCP_DEBUG_LEVEL = DEBUG_LEVEL-2;
// codex 2026-01-27: enable MCP-mode SyncCommand control
SYNC_COMMAND.setMcpMode(getMcpMode());
McpServer.startIfNeeded(this, getMcpPort());
......@@ -550,11 +558,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
if (options != null || headless) {
processFiles();
} else {
if (use_swing) {
initGuiSwing();
} else {
initGuiAWT();
}
initGuiSwing();
}
}
......@@ -954,6 +958,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
if (this.SYNC_COMMAND.stopRequested.get() == 0) {
try {
this.commandFromMcp = this.SYNC_COMMAND.fromMcp;
this.SYNC_COMMAND.fromMcp = false;
runMenuCommand(this.SYNC_COMMAND.buttonLabel);
} catch (Exception e) {
// TODO Auto-generated catch block
......@@ -962,418 +968,13 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
IJ.showMessage("Exception", stack2string(e));
}
}
this.commandFromMcp = false;
this.SYNC_COMMAND.isRunning = false;
this.SYNC_COMMAND.stopRequested.set(0);
}
}
public void initGuiAWT() {
/// EyesisTopFrame eyesisTopFrame = new EyesisTopFrame();
Color color_configure = new Color(200, 200, 160);
Color color_configure_aux = new Color(190, 190, 180);
Color color_process = new Color(180, 180, 240);
Color color_process_aux = new Color(175, 175, 250);
Color color_conf_process = new Color(180, 240, 240);
Color color_conf_process_aux = new Color(175, 235, 250);
Color color_restore = new Color(160, 240, 160);
Color color_stop = new Color(255, 160, 160);
Color color_report = new Color(180, 220, 180);
plugInFrame = new PlugInFrame("Eyesis_Correction") {
private static final long serialVersionUID = -4138832568507690332L;
@Override
public void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
plugInFrame=null; // instance = null;
}
}
};
// Font font = plugInFrame.getFont();
// instance = plugInFrame;
plugInFrame.addKeyListener(IJ.getInstance());
// int menuRows=4 + (ADVANCED_MODE?4:0) + (MODE_3D?3:0) + (DCT_MODE?6:0) + (GPU_MODE?1:0) +(LWIR_MODE?2:0);
int menuRows = 4 + (ADVANCED_MODE ? 4 : 0) + (MODE_3D ? 3 : 0) + (DCT_MODE ? 7 : 0) + (GPU_MODE ? 1 : 0)
+ (LWIR_MODE ? 4 : 0);
plugInFrame.setLayout(new GridLayout(menuRows, 1));
panel6 = new Panel();
panel6.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Save", panel6, color_process); // , "Save configuration");
addButton("Save Clean", panel6, color_process); // , "Save clean configuration");
addButton("Restore", panel6, color_restore); // , "Restore configuration");
addButton("Stop", panel6, color_stop);
addButton("Abort", panel6, color_stop);
plugInFrame.add(panel6);
panel5 = new Panel();
panel5.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Configure spilt", panel5, color_configure);
addButton("Configure demosaic", panel5, color_configure);
plugInFrame.add(panel5);
panel5a = new Panel();
panel5a.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Configure convolution", panel5a, color_configure);
addButton("Configure denoise", panel5a, color_configure);
addButton("Configure color", panel5a, color_configure);
addButton("Configure AUX color", panel5a, color_configure_aux);
// addButton("Channel gains", panel5a, color_configure);
addButton("Configure RGB", panel5a, color_configure);
plugInFrame.add(panel5a);
// Debug/development options
if (ADVANCED_MODE) {
panel1 = new Panel();
panel1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Split Image", panel1, null);
addButton("Debayer Image", panel1, null);
plugInFrame.add(panel1);
panel2 = new Panel();
panel2.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Select kernel stack", panel2, null);
addButton("Convolve with stack", panel2, null);
plugInFrame.add(panel2);
panel3 = new Panel();
panel3.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Select lo-res", panel3, null);
addButton("Combine pair", panel3, null);
addButton("Colors", panel3, null);
addButton("RGB", panel3, null);
plugInFrame.add(panel3);
panel4 = new Panel();
panel4.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Test", panel4, null);
addButton("Test Debayer", panel4, null);
plugInFrame.add(panel4);
}
panel7 = new Panel();
panel7.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Configure correction", panel7, color_configure);
addButton("Channel gains/colors", panel7, color_configure);
addButton("Configure warping", panel7, color_conf_process);
addButton("Select source files", panel7, color_configure);
addButton("Select source sets", panel7, color_configure);
addButton("Process files", panel7, color_process);
if (ADVANCED_MODE) {
addButton("Tiff Writer", panel7, null);
addButton("Tiff Properties", panel7, null);
addButton("Add TIFF resolution", panel7, null);
}
plugInFrame.add(panel7);
if (MODE_3D) {
panelPostProcessing1 = new Panel();
panelPostProcessing1.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Configure PP", panelPostProcessing1, color_configure);
addButton("Source PP", panelPostProcessing1, color_configure);
addButton("ConvertPP", panelPostProcessing1, color_process);
addButton("Linear Features", panelPostProcessing1, null);
addButton("Intercam correlations", panelPostProcessing1, null);
plugInFrame.add(panelPostProcessing1, null);
panelPostProcessing2 = new Panel();
panelPostProcessing2.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Tile correlations", panelPostProcessing2, null);
addButton("Load correlations", panelPostProcessing2, null);
addButton("Section correlations", panelPostProcessing2, null);
addButton("Setup Z-map", panelPostProcessing2, null);
addButton("Fill FG gaps", panelPostProcessing2, null);
addButton("Filter Z-map", panelPostProcessing2, null);
addButton("Occluding FG", panelPostProcessing2, null);
plugInFrame.add(panelPostProcessing2, null);
panelPostProcessing3 = new Panel();
panelPostProcessing3.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Refine Disparities", panelPostProcessing3, null);
addButton("Init Photometry", panelPostProcessing3, null);
addButton("Plane Likely", panelPostProcessing3, null);
plugInFrame.add(panelPostProcessing3, null);
}
if (DCT_MODE) {
panelDct1 = new Panel();
panelDct1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("DCT test 1", panelDct1, color_process);
addButton("select MDCT image", panelDct1, color_configure);
addButton("MDCT scale", panelDct1, color_process);
addButton("MDCT stack", panelDct1, color_process);
addButton("DCT test 3", panelDct1, color_process);
addButton("DCT test 4", panelDct1, color_process);
addButton("Test Kernel Factorization", panelDct1, color_process);
addButton("Min Kernel Factorization", panelDct1, color_process);
addButton("Select kernels image", panelDct1, color_configure);
addButton("Create DCT kernels", panelDct1, color_process);
addButton("Read DCT kernels", panelDct1, color_process);
addButton("Reset DCT kernels", panelDct1, color_stop);
addButton("Setup DCT parameters", panelDct1, color_configure);
addButton("DCT process files", panelDct1, color_process);
plugInFrame.add(panelDct1);
}
if (DCT_MODE) {
panelClt1 = new Panel();
panelClt1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Select CLT image", panelClt1, color_configure);
addButton("CLT stack", panelClt1, color_process);
addButton("Select second CLT image", panelClt1, color_configure);
addButton("CLT correlate", panelClt1, color_process);
addButton("Reset Geometry", panelClt1, color_stop);
addButton("Reset AUX Geometry", panelClt1, color_stop);
addButton("Create CLT kernels", panelClt1, color_process);
addButton("Create AUX CLT kernels", panelClt1, color_process);
addButton("Read CLT kernels", panelClt1, color_process_aux);
addButton("Reset CLT kernels", panelClt1, color_stop);
addButton("CLT process files", panelClt1, color_process);
addButton("CLT process sets", panelClt1, color_process);
plugInFrame.add(panelClt1);
}
if (DCT_MODE) {
panelClt2 = new Panel();
panelClt2.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Setup CLT parameters", panelClt2, color_configure);
addButton("CLT 4 images", panelClt2, color_conf_process);
addButton("CLT disparity scan", panelClt2, color_conf_process);
addButton("CLT reset fine corr", panelClt2, color_stop);
addButton("CLT reset extrinsic corr", panelClt2, color_stop);
addButton("ERS reset", panelClt2, color_stop);
addButton("CLT show geometry", panelClt2, color_configure);
addButton("CLT show fine corr", panelClt2, color_report);
addButton("CLT apply fine corr", panelClt2, color_process);
addButton("CLT test fine corr", panelClt2, color_process);
addButton("CLT process fine corr", panelClt2, color_conf_process);
addButton("CLT infinity corr", panelClt2, color_conf_process);
addButton("CLT ext infinity corr", panelClt2, color_conf_process);
addButton("CLT reset 3D", panelClt2, color_stop);
addButton("MAIN extrinsics", panelClt2, color_process);
addButton("CLT Poly corr", panelClt2, color_process);
addButton("DRY RUN", panelClt2, color_configure);
addButton("CLT 3D", panelClt2, color_process);
addButton("CLT planes", panelClt2, color_conf_process);
addButton("CLT ASSIGN", panelClt2, color_process);
addButton("CLT OUT 3D", panelClt2, color_process);
plugInFrame.add(panelClt2);
}
if (DCT_MODE) {
panelClt3 = new Panel();
panelClt3.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Setup CLT", panelClt3, color_configure);
addButton("Infinity offset", panelClt3, color_configure);
addButton("Setup CLT Batch parameters", panelClt3, color_configure);
addButton("CLT batch process", panelClt3, color_process);
addButton("CM Test", panelClt3, color_stop);
addButton("Show scan", panelClt3, color_report);
addButton("Show all scans", panelClt3, color_report);
addButton("Periodic", panelClt3, color_configure);
plugInFrame.add(panelClt3);
}
if (DCT_MODE) {
panelClt4 = new Panel();
panelClt4.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Import Aux", panelClt4, color_restore);
addButton("Setup CLT Batch parameters", panelClt4, color_configure);
addButton("CLT rig edit", panelClt4, color_configure);
addButton("Rig offset", panelClt4, color_configure);
addButton("Save offset", panelClt4, color_process);
addButton("SHOW extrinsics", panelClt4, color_report);
addButton("RIG DSI", panelClt4, color_conf_process);
addButton("MAIN extrinsics", panelClt4, color_process);
addButton("AUX extrinsics", panelClt4, color_process);
addButton("RIG extrinsics", panelClt4, color_conf_process);
addButton("SAVE extrinsics", panelClt4, color_process); // , "Save configuration");
addButton("Rig8 images", panelClt4, color_conf_process);
addButton("Reset GT", panelClt4, color_stop);
addButton("Ground truth", panelClt4, color_conf_process);
addButton("Show biscan", panelClt4, color_report);
addButton("Poles GT", panelClt4, color_process);
addButton("ML export", panelClt4, color_conf_process);
addButton("JP4 copy", panelClt4, color_conf_process);
addButton("DSI show", panelClt4, color_report);
addButton("Rig batch", panelClt4, color_process);
plugInFrame.add(panelClt4);
}
if (DCT_MODE) {
panelClt5 = new Panel();
panelClt5.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("LIST extrinsics", panelClt5, color_report);
addButton("DSI histogram", panelClt5, color_report);
addButton("ML recalc", panelClt5, color_process);
addButton("Inter Test", panelClt5, color_stop);
addButton("Inter Pairs", panelClt5, color_process);
addButton("Inter LMA", panelClt5, color_stop);
addButton("Inter Series", panelClt5, color_process);
addButton("Inter Accumulate", panelClt5, color_process);
addButton("Inter Noise", panelClt5, color_process);
addButton("Inter Debug Noise", panelClt5, color_report);
addButton("Noise Stats", panelClt5, color_process);
addButton("Test 1D", panelClt5, color_process);
addButton("Colorize Depth", panelClt5, color_process);
addButton("Main LY series", panelClt5, color_process);
plugInFrame.add(panelClt5);
}
if (DCT_MODE) {
panelClt5aux = new Panel();
panelClt5aux.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("LIST extrinsics", panelClt5aux, color_report);
addButton("Aux Build Series", panelClt5aux, color_stop);
addButton("Aux Inter Test", panelClt5aux, color_stop);
addButton("Aux Inter Pairs", panelClt5aux, color_process);
addButton("Aux Inter LMA", panelClt5aux, color_stop);
addButton("Aux Inter Series", panelClt5aux, color_process);
addButton("Aux Inter Accumulate", panelClt5aux, color_process);
addButton("Inter Noise Aux", panelClt5aux, color_process);
addButton("Batch Noise Aux", panelClt5aux, color_report);
addButton("Noise Stats Aux", panelClt5aux, color_process);
addButton("Colorize Depth", panelClt5aux, color_process);
addButton("Inter Intra ML", panelClt5aux, color_report);
addButton("Aux LY series", panelClt5aux, color_process);
plugInFrame.add(panelClt5aux);
}
if (GPU_MODE) {
panelClt_GPU = new Panel();
panelClt_GPU.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("JCUDA TEST", panelClt_GPU, null);
addButton("TF TEST", panelClt_GPU, null);
addButton("GPU simulate", panelClt_GPU, color_conf_process);
addButton("GPU RUN", panelClt_GPU, color_conf_process);
// addButton("ShowGPU", panelClt_GPU, color_conf_process);
addButton("LWIR_TEST", panelClt_GPU, color_conf_process);
addButton("LWIR_ACQUIRE", panelClt_GPU, color_conf_process);
addButton("ERS reset", panelClt2, color_stop);
addButton("IMU main", panelClt_GPU, color_conf_process);
addButton("ERS main", panelClt_GPU, color_process);
addButton("IMU aux", panelClt_GPU, color_conf_process_aux);
addButton("ERS aux", panelClt_GPU, color_process_aux);
addButton("Rotations_test", panelClt_GPU, color_stop);
addButton("GPU simulate", panelClt_GPU, color_conf_process);
plugInFrame.add(panelClt_GPU);
}
if (LWIR_MODE) {
panelLWIR = new Panel();
panelLWIR.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Setup CLT Batch parameters", panelLWIR, color_configure);
addButton("Reset Geometry", panelLWIR, color_stop);
addButton("Reset AUX Geometry", panelLWIR, color_stop);
addButton("Create CLT kernels", panelLWIR, color_process);
addButton("Create AUX CLT kernels", panelLWIR, color_process_aux);
addButton("Select source sets", panelLWIR, color_configure);
addButton("Configure color", panelLWIR, color_configure);
addButton("CORR TEST", panelLWIR, color_conf_process);
addButton("CLT 4 images", panelLWIR, color_conf_process);
addButton("CLT 3D", panelLWIR, color_process);
addButton("CLT planes", panelLWIR, color_conf_process);
addButton("CLT ASSIGN", panelLWIR, color_process);
addButton("CLT OUT 3D", panelLWIR, color_process);
addButton("Configure AUX color", panelLWIR, color_configure_aux);
addButton("AUX 4 images", panelLWIR, color_conf_process_aux);
addButton("AUX 3D", panelLWIR, color_process);
addButton("AUX planes", panelLWIR, color_conf_process_aux);
addButton("AUX ASSIGN", panelLWIR, color_process_aux);
addButton("AUX OUT 3D", panelLWIR, color_process_aux);
addButton("Main img AUX", panelLWIR, color_process_aux);
addButton("Main to AUX", panelLWIR, color_process_aux);
addButton("LWIR batch", panelClt4, color_process);
// addButton("LWIR_TEST", panelLWIR, color_conf_process);
// addButton("LWIR_ACQUIRE", panelLWIR, color_conf_process);
plugInFrame.add(panelLWIR);
panelLWIR16 = new Panel();
panelLWIR16.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("SHOW extrinsics", panelLWIR16, color_report);
addButton("Reset Geometry", panelLWIR16, color_stop);
addButton("Reset AUX Geometry", panelLWIR16, color_stop);
addButton("Generate Sym Vectors", panelLWIR16, color_configure);
addButton("Image Properties", panelLWIR16, color_conf_process);
addButton("Illustrations Configure", panelLWIR16, color_conf_process);
addButton("Footage Organize", panelLWIR16, color_conf_process);
addButton("Super batch", panelLWIR16, color_process);
addButton("Remove source paths", panelLWIR16, color_stop);
plugInFrame.add(panelLWIR16);
panelLWIRWorld = new Panel();
panelLWIRWorld.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Aux Build Series", panelLWIRWorld, color_stop);
addButton("CUAS Combine", panelLWIRWorld, color_stop);
addButton("Build World", panelLWIRWorld, color_process);
addButton("Test IMX5", panelLWIRWorld, color_process);
addButton("Show mice", panelLWIRWorld, color_process);
addButton("Set pair", panelLWIRWorld, color_process);
addButton("Warp pair", panelLWIRWorld, color_process);
addButton("Read Tiff", panelLWIRWorld, color_process);
addButton("Test video", panelLWIRWorld, color_process);
addButton("Ortho", panelLWIRWorld, color_process);
addButton("Ortho Pairs", panelLWIRWorld, color_process);
addButton("Manual pair", panelLWIRWorld, color_process);
addButton("Extract Objects", panelLWIRWorld, color_process);
addButton("Mismatched resolutions", panelLWIRWorld, color_process);
addButton("Generate DATI", panelLWIRWorld, color_process);
addButton("Create mine", panelLWIRWorld, color_process);
addButton("Pattern correlate", panelLWIRWorld, color_process);
addButton("Properties compare", panelLWIRWorld, color_process);
plugInFrame.add(panelLWIRWorld);
panelOrange = new Panel();
panelOrange.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("Test Orange", panelOrange, color_process);
addButton("Process Merged", panelOrange, color_process);
addButton("Vegetation LMA", panelOrange, color_process);
addButton("Combine LMA Segments", panelOrange, color_process);
addButton("Render synthetic", panelOrange, color_process);
addButton("Generate LWIR target", panelOrange, color_process);
// addButton("Test LDLT Cholesky", panelOrange, color_process);
addButton("Test LLT Cholesky", panelOrange, color_process);
addButton("UAS log", panelOrange, color_process);
addButton("DJI SRT", panelOrange, color_process);
addButton("SRT to KML", panelOrange, color_process);
//
plugInFrame.add(panelOrange);
}
plugInFrame.pack(); // Adjusts the window size to fit components
//"LWIR batch"
GUI.center(plugInFrame);
plugInFrame.setVisible(true);
// FHT_INSTANCE = new DoubleFHT();
// main loop
while (true) {
synchronized (this.SYNC_COMMAND) {
try {
this.SYNC_COMMAND.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.SYNC_COMMAND.isRunning = true;
}
if (this.SYNC_COMMAND.stopRequested.get() == 0) {
try {
runMenuCommand(this.SYNC_COMMAND.buttonLabel);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(stack2string(e));
IJ.showMessage("Exception", stack2string(e));
}
}
this.SYNC_COMMAND.isRunning = false;
this.SYNC_COMMAND.stopRequested.set(0);
}
}
private Properties prefsProperties = new Properties();
public void loadPrefs() throws IOException {
......@@ -1535,6 +1136,11 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
// codex 2026-01-25: MCP-visible command trigger
public void triggerCommand(String label) {
triggerCommand(label, false);
}
// codex 2026-01-28: mark MCP-originated commands
public void triggerCommand(String label, boolean fromMcp) {
if (label == null) {
return;
}
......@@ -1553,6 +1159,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
return;
}
synchronized (this.SYNC_COMMAND) {
this.SYNC_COMMAND.fromMcp = fromMcp;
this.SYNC_COMMAND.buttonLabel = label;
this.SYNC_COMMAND.notify();
}
......@@ -1600,6 +1207,19 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
}
private long getMcpDialogTimeoutMs() {
String value = System.getProperty("elphel.mcp.dialogTimeoutMs");
if (value == null || value.isEmpty()) {
return 30000L;
}
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return 30000L;
}
}
private boolean getMcpMode() {
String value = System.getProperty("elphel.mcp.mode");
if (value == null || value.isEmpty()) {
......@@ -1752,6 +1372,8 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
public void runMenuCommand(String label) {
MCP_COMMAND_CONTEXT = this.commandFromMcp;
try {
int i, j; // ,l,iq;
// String label = e.getActionCommand();
Runtime runtime = Runtime.getRuntime();
......@@ -4762,16 +4384,16 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
/* ======================================================================== */
} else if (label.equals("Setup CLT Batch parameters")) {
DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
CORRECTION_PARAMETERS.showCLTBatchDialog("CLT Batch parameters", CLT_PARAMETERS, true); // codex 2026-01-27
CORRECTION_PARAMETERS.showCLTBatchDialog("CLT Batch parameters", CLT_PARAMETERS, true, this.commandFromMcp); // codex 2026-01-27
return;
/* ======================================================================== */
} else if (label.equals("Setup CLT parameters")) {
CLT_PARAMETERS.showJDialog(true); // codex 2026-01-27
CLT_PARAMETERS.showJDialog(true, this.commandFromMcp); // codex 2026-01-27
return;
/* ======================================================================== */
} else if (label.equals("Setup CLT")) {
CLT_PARAMETERS.showJDialog(true); // codex 2026-01-27
CLT_PARAMETERS.showJDialog(true, this.commandFromMcp); // codex 2026-01-27
return;
/* ======================================================================== */
} else if (label.equals("Infinity offset")) {
......@@ -6451,6 +6073,9 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
*/
}
} finally {
MCP_COMMAND_CONTEXT = false;
}
}
public static boolean testUasLog() {
......@@ -10162,7 +9787,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
public static String[] selectDirectoriesOrFiles(boolean save, boolean directory, String title, String button,
FileFilter filter, String[] defaultPaths) {
if (GenericJTabbedDialogMcp.isDefaultMcpMode()) {
if (GenericJTabbedDialogMcp.isDefaultMcpMode() && MCP_COMMAND_CONTEXT) {
String defaultPath = null;
if (defaultPaths != null && defaultPaths.length > 0) {
defaultPath = defaultPaths[0];
......@@ -10255,7 +9880,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
public static String selectDirectoryOrFile(boolean save, boolean directory, String title, String button, FileFilter filter,
String defaultPath) {
if (GenericJTabbedDialogMcp.isDefaultMcpMode()) {
if (GenericJTabbedDialogMcp.isDefaultMcpMode() && MCP_COMMAND_CONTEXT) {
return selectDirectoryOrFileMcp(directory, title, defaultPath);
}
File dir = null;
......@@ -10930,7 +10555,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
QUAD_CLT.getProperties(QuadCLT.PREFIX);
if (QUAD_CLT_AUX != null)
QUAD_CLT_AUX.getProperties(QuadCLT.PREFIX_AUX);
return;
}
/* ======================================================================== */
......
......@@ -12,6 +12,7 @@ public class SyncCommand {
public AtomicInteger stopRequested = new AtomicInteger(0); // 0 - not requested, 1 - ASAP, 2 - gracefully
public String buttonLabel = "";
public boolean confirm = true;
public boolean fromMcp = false;
// codex 2026-01-27: MCP-controlled pause/confirm
private boolean mcpMode = false;
private boolean confirmPending = false;
......
......@@ -8,19 +8,58 @@ public class McpDialogRegistry {
private McpDialogRegistry() {
}
public static void setCurrent(McpDialogSession session) {
public static boolean setCurrent(McpDialogSession session) {
if (session == null) {
CURRENT.set(null);
return true;
}
McpDialogSession existing = CURRENT.get();
if (existing != null) {
return false;
}
CURRENT.set(session);
return true;
}
public static McpDialogSession getCurrent() {
return CURRENT.get();
}
public static void setValue(String label, String value) {
public static boolean setValue(String label, String value) {
McpDialogSession session = CURRENT.get();
if (session == null) {
return;
return false;
}
session.setValue(label, value);
return true;
}
public static boolean setValueForId(String id, String label, String value) {
McpDialogSession session = CURRENT.get();
if (session == null || id == null || !id.equals(session.getId())) {
return false;
}
session.setValue(label, value);
return true;
}
public static boolean submitCurrent(boolean ok) {
McpDialogSession session = CURRENT.get();
if (session == null) {
return false;
}
session.submit(ok);
CURRENT.set(null);
return true;
}
public static boolean submitForId(String id, boolean ok) {
McpDialogSession session = CURRENT.get();
if (session == null || id == null || !id.equals(session.getId())) {
return false;
}
session.submit(ok);
CURRENT.set(null);
return true;
}
}
......@@ -8,10 +8,13 @@ import java.util.Map;
import java.util.UUID;
public class McpDialogSession {
public static final int debugLevel = -1; // name in the same case in most other places. Compares if (debugLevel >-3)
private final String id;
private final String title;
private final List<McpDialogField> fields;
private final Map<String, String> valuesByLabel;
private final Object submitLock = new Object();
private Boolean submittedOk = null;
public McpDialogSession(String title, List<McpDialogField> fields) {
this.id = UUID.randomUUID().toString();
......@@ -37,6 +40,41 @@ public class McpDialogSession {
return;
}
valuesByLabel.put(label, value);
if (debugLevel > -3) {
System.out.println("setValue("+label+","+value+")");
}
}
public void submit(boolean ok) {
synchronized (submitLock) {
submittedOk = Boolean.valueOf(ok);
submitLock.notifyAll();
if (debugLevel > -3) {
System.out.println("submit("+ok+")");
}
}
}
public Boolean awaitSubmit(long timeoutMs) {
synchronized (submitLock) {
if (submittedOk != null) {
return submittedOk;
}
long deadline = System.currentTimeMillis() + timeoutMs;
while (submittedOk == null) {
long remaining = deadline - System.currentTimeMillis();
if (remaining <= 0) {
break;
}
try {
submitLock.wait(remaining);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return submittedOk;
}
}
public String getValue(String label) {
......
......@@ -72,9 +72,9 @@ public class McpFsAccess {
if (configPath != null && !configPath.trim().isEmpty()) {
Path configFile = Paths.get(configPath).toAbsolutePath().normalize();
roots.add(configFile);
Path configDir = configFile.getParent();
if (configDir != null) {
roots.add(configDir);
Path configDirFileParent = configFile.getParent();
if (configDirFileParent != null) {
roots.add(configDirFileParent);
}
addRootsFromConfig(configFile, roots);
}
......
......@@ -51,6 +51,7 @@ public class McpServer {
server.createContext("/mcp/status", new StatusHandler());
server.createContext("/mcp/dialog", new DialogHandler());
server.createContext("/mcp/dialog/values", new DialogValuesHandler());
server.createContext("/mcp/dialog/submit", new DialogSubmitHandler());
server.createContext("/mcp/button", new ButtonHandler());
server.createContext("/mcp/interrupt", new InterruptHandler());
server.createContext("/mcp/interrupt/confirm", new InterruptConfirmHandler());
......@@ -62,7 +63,9 @@ public class McpServer {
server.createContext("/mcp/fs/glob", new FsGlobHandler());
server.setExecutor(null);
server.start();
System.out.println("MCP: server started on http://127.0.0.1:" + port);
if (Eyesis_Correction.MCP_DEBUG_LEVEL >= Eyesis_Correction.MINIMAL_DEBUG_MCP) {
System.out.println("MCP: server started on http://127.0.0.1:" + port);
}
}
private class StatusHandler implements HttpHandler {
......@@ -89,14 +92,40 @@ public class McpServer {
return;
}
Map<String, String> params = parseParams(exchange);
String id = params.get("id");
String label = params.get("label");
String value = params.get("value");
if (label == null) {
sendJson(exchange, 400, "{\"ok\":false,\"error\":\"Missing label\"}");
return;
}
McpDialogRegistry.setValue(label, value);
sendJson(exchange, 200, "{\"ok\":true}");
boolean applied = (id == null) ? McpDialogRegistry.setValue(label, value) : McpDialogRegistry.setValueForId(id, label, value);
if (applied) {
if (Eyesis_Correction.MCP_DEBUG_LEVEL >= Eyesis_Correction.MINIMAL_DEBUG_MCP) {
System.out.println("MCP: dialog value label=\"" + label + "\"");
}
sendJson(exchange, 200, "{\"ok\":true}");
} else {
sendJson(exchange, 409, "{\"ok\":false,\"error\":\"No active dialog or id mismatch\"}");
}
}
}
private class DialogSubmitHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
if (!"POST".equalsIgnoreCase(exchange.getRequestMethod())) {
sendJson(exchange, 405, "{\"ok\":false,\"error\":\"POST required\"}");
return;
}
Map<String, String> params = parseParams(exchange);
String id = params.get("id");
boolean ok = parseBool(params.get("ok"), true);
boolean applied = (id == null) ? McpDialogRegistry.submitCurrent(ok) : McpDialogRegistry.submitForId(id, ok);
if (applied && Eyesis_Correction.MCP_DEBUG_LEVEL >= Eyesis_Correction.MINIMAL_DEBUG_MCP) {
System.out.println("MCP: dialog submit ok=" + ok);
}
sendJson(exchange, 200, applied ? "{\"ok\":true}" : "{\"ok\":false,\"error\":\"No active dialog\"}");
}
}
......@@ -113,7 +142,10 @@ public class McpServer {
sendJson(exchange, 400, "{\"ok\":false,\"error\":\"Missing label\"}");
return;
}
owner.triggerCommand(label);
owner.triggerCommand(label, true);
if (Eyesis_Correction.MCP_DEBUG_LEVEL >= Eyesis_Correction.MINIMAL_DEBUG_MCP) {
System.out.println("MCP: button \"" + label + "\"");
}
sendJson(exchange, 200, "{\"ok\":true}");
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment