22#define IMGUI_DEFINE_MATH_OPERATORS  
   24#include <imgui_internal.h> 
   37#include <glm/gtc/matrix_transform.hpp>  
   38#include <glm/gtx/euler_angles.hpp> 
   49  if (winsize::get().width == 0)
 
   52    int w = 1920, 
h = 1080;  
 
   56      std::vector<std::string> 
const tok = 
jevois::split(ws, 
"\\s*[,;x]\\s*");
 
   57      if (tok.size() == 2) { w = std::stoi(tok[0]); 
h = std::stoi(tok[1]) / 2; } 
 
   58      LINFO(
"Detected framebuffer size: " << w << 
'x' << 
h);
 
   62    winsize::set(cv::Size(w, 
h));
 
   68  std::vector<EditorItem> fixedcfg
 
   70     { 
JEVOIS_ROOT_PATH "/config/videomappings.cfg", 
"JeVois videomappings.cfg", EditorSaveAction::RefreshMappings },
 
   71     { 
JEVOIS_ROOT_PATH "/config/initscript.cfg", 
"JeVois initscript.cfg", EditorSaveAction::Reboot },
 
   72     { 
"params.cfg", 
"Module's params.cfg", EditorSaveAction::Reload },
 
   73     { 
"script.cfg", 
"Module's script.cfg", EditorSaveAction::Reload },
 
   75       "JeVois models.yml DNN Zoo Root", EditorSaveAction::Reload },
 
   77       "JeVois opencv.yml DNN Zoo for OpenCV models", EditorSaveAction::Reload },
 
   79       "JeVois npu.yml DNN Zoo for A311D NPU models", EditorSaveAction::Reload },
 
   81       "JeVois spu.yml DNN Zoo for Hailo SPU models", EditorSaveAction::Reload },
 
   83       "JeVois tpu.yml DNN Zoo for Coral TPU models", EditorSaveAction::Reload },
 
   85       "JeVois vpu.yml DNN Zoo for Myriad-X VPU models", EditorSaveAction::Reload },
 
   87       "JeVois ort.yml DNN Zoo for ONNX-Runtime CPU models", EditorSaveAction::Reload },
 
   92                                           { 
".yaml", 
".yml" }));
 
   95  std::vector<EditorItem> fixedcode
 
   97     { 
"*", 
"Module's source code", EditorSaveAction::Reload },
 
  103                                            { 
".py", 
".C", 
".H", 
".cpp", 
".hpp", 
".c", 
".h", 
".txt" }));
 
 
  116  itsEndFrameCalled = 
true;
 
  119  itsLastDrawnImage = 
nullptr;
 
  120  itsLastDrawnTextLine = -1;
 
  131    itsCfgEditor->refresh();
 
  132    itsCodeEditor->refresh();
 
  137    std::lock_guard<std::mutex> _(itsErrorMtx);
 
  143  itsBackend.getWindowSize(w, 
h);
 
  145  if (w == 0) 
LFATAL(
"Need to call startFrame() at least once first");
 
  147  float const fov_y = 45.0f;
 
  149  proj = glm::perspective(glm::radians(fov_y), 
float(w) / 
float(
h), 1.0f, 
h * 2.0f);
 
  150  const_cast<float &
>(pixel_perfect_z) = -
float(
h) / (2.0 * tan(fov_y * M_PI / 360.0));
 
  151#ifdef JEVOIS_PLATFORM 
  153  proj = glm::translate(proj, glm::vec3(0.375f, 0.375f, 0.0f));
 
  155  view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, pixel_perfect_z));
 
  158  style::set(style::get());
 
  165  if (std::filesystem::exists(m.
cmakepath())) itsNewMapping = m;
 
 
  171  if (itsEndFrameCalled == 
false) 
LFATAL(
"You need to call endFrame() at the end of your process() function");
 
  174  itsBackend.getWindowSize(w, 
h);
 
  179    cv::Size 
const siz = winsize::get();
 
  180    bool const fs = fullscreen::get();
 
  181    LINFO(
"OpenGL init " << siz.width << 
'x' << siz.height << (fs ? 
" fullscreen" : 
""));
 
  182    itsBackend.init(siz.width, siz.height, fs, scale::get(), itsConsLock);
 
  183    rounding::set(
int(rounding::get() * scale::get() + 0.499F));
 
  186    unsigned short winw, winh; itsBackend.getWindowSize(winw, winh); winsize::set(cv::Size(winw, winh));
 
  187    winsize::freeze(
true);
 
  188    fullscreen::freeze(
true);
 
  195  bool shouldclose = 
false; 
auto const now = std::chrono::steady_clock::now();
 
  196  if (itsBackend.pollEvents(shouldclose)) itsLastEventTime = now;
 
  198  if (shouldclose && allowquit::get())
 
  200    LINFO(
"Closing down on user request...");
 
  205  itsBackend.newFrame();
 
  212    float const hs = hidesecs::get();
 
  215      std::chrono::duration<float> elapsed = now - itsLastEventTime;
 
  216      itsIdle = (elapsed.count() >= hs);
 
  218    else itsIdle = 
false;
 
  221  itsEndFrameCalled = 
false;
 
 
  233  float oldval = param.get();
 
  234  if (newval == oldval) 
return;
 
  236  ImGui::GetStyle().ScaleAllSizes(newval / oldval);
 
  237  ImGui::GetIO().FontGlobalScale = newval;
 
  238  ImGui::GetStyle().MouseCursorScale = 2.0f; 
 
  241  if (oldval) rounding::set(std::min(24, 
int(rounding::get() * newval / oldval + 0.499F)));
 
  249  case jevois::gui::GuiStyle::Dark:
 
  250    ImGui::StyleColorsDark();
 
  251    itsCfgEditor->SetPalette(TextEditor::GetDarkPalette());
 
  252    itsCodeEditor->SetPalette(TextEditor::GetDarkPalette());
 
  255  case jevois::gui::GuiStyle::Light:
 
  256    ImGui::StyleColorsLight();
 
  257    ImGui::GetStyle().Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 0.92f); 
 
  258    itsCfgEditor->SetPalette(TextEditor::GetLightPalette());
 
  259    itsCodeEditor->SetPalette(TextEditor::GetLightPalette());
 
  262  case jevois::gui::GuiStyle::Classic:
 
  263    ImGui::StyleColorsClassic();
 
  264    itsCfgEditor->SetPalette(TextEditor::GetRetroBluePalette());
 
  265    itsCodeEditor->SetPalette(TextEditor::GetRetroBluePalette());
 
  273  auto & s = ImGui::GetStyle();
 
  274  s.WindowRounding = newval;
 
  275  s.ChildRounding = newval;
 
  276  s.FrameRounding = newval;
 
  277  s.PopupRounding = newval;
 
  278  s.ScrollbarRounding = newval;
 
  279  s.GrabRounding = newval;
 
  284{ 
return (itsEndFrameCalled == 
false); }
 
 
  288                                  unsigned short & w, 
unsigned short & 
h, 
bool noalias, 
bool isoverlay)
 
  291  std::string 
const imgname = name + std::to_string(img.
bufindex);
 
  294  auto & im = itsImages[imgname];
 
  300  im.draw(x, y, w, 
h, noalias, proj * view);
 
  303  if (isoverlay == 
false)
 
  305    itsLastDrawnImage = & im;
 
  306    itsUsingScaledImage = 
false;
 
  307    itsLastDrawnTextLine = -1;
 
 
  313                                  unsigned short & w, 
unsigned short & 
h, 
bool noalias, 
bool isoverlay)
 
  316  auto & im = itsImages[name];
 
  322  im.draw(x, y, w, 
h, noalias, proj * view);
 
  325  if (isoverlay == 
false)
 
  327    itsLastDrawnImage = & im;
 
  328    itsUsingScaledImage = 
false;
 
  329    itsLastDrawnTextLine = -1;
 
 
  335                                       unsigned short & w, 
unsigned short & 
h, 
bool noalias, 
bool casync)
 
  337  itsInputFrame = &frame; 
 
  341  std::string 
const imgname = name + std::to_string(img.
bufindex);
 
  344  auto & im = itsImages[imgname];
 
  348  im.set(frame, itsBackend.getDisplay());
 
  351  im.draw(x, y, w, 
h, noalias, proj * view);
 
  354  itsLastDrawnImage = & im;
 
  356  itsLastDrawnTextLine = -1;
 
  357  if (itsUsingScaledImage)
 
  360    itsScaledImageFacX = float(img.
width) / float(img2.
width);
 
  361    itsScaledImageFacY = float(img.
height) / float(img2.
height);
 
 
  367                                       unsigned short & w, 
unsigned short & 
h, 
bool noalias, 
bool casync)
 
  371  std::string 
const imgname = name + std::to_string(img.
bufindex);
 
  374  auto & im = itsImages2[imgname];
 
  378  im.set2(frame, itsBackend.getDisplay());
 
  381  im.draw(x, y, w, 
h, noalias, proj * view);
 
  384  itsLastDrawnImage = & im;
 
  385  itsUsingScaledImage = 
false;
 
  386  itsLastDrawnTextLine = -1;
 
 
  392  if (itsInputFrame == 
nullptr)
 
  393    LFATAL(
"Input frame not available -- only accessible between drawInputFrame() and endFrame()");
 
  394  return itsInputFrame;
 
 
  403  itsGlobalAlpha = std::abs(1.0F - newval / 15.0F);  
 
  406  for (
auto & ip : itsImages) ip.second.twirl(newval);
 
 
  417    if (itsLastDrawnImage == 
nullptr) 
throw std::range_error(
"You need to call drawImage() or drawInputFrame() first");
 
  418    img = itsLastDrawnImage;
 
  422    std::string nstr = name;
 
  423    auto itr = itsImages.find(nstr);
 
  424    if (itr == itsImages.end())
 
  428      itr = itsImages.find(nstr + 
'0');
 
  429      if (itr == itsImages.end()) 
throw std::range_error(
"No previously drawn image with name [" + nstr + 
"] found");
 
  435  if (itsUsingScaledImage) { p.x *= itsScaledImageFacX; p.y *= itsScaledImageFacY; }
 
 
  443{ 
return i2d(ImVec2(x, y), name); }
 
 
  453    if (itsLastDrawnImage == 
nullptr) 
throw std::range_error(
"You need to call drawImage() or drawInputFrame() first");
 
  454    img = itsLastDrawnImage;
 
  458    std::string nstr = name;
 
  459    auto itr = itsImages.find(nstr);
 
  460    if (itr == itsImages.end())
 
  464      itr = itsImages.find(nstr + 
'0');
 
  465      if (itr == itsImages.end()) 
throw std::range_error(
"No previously drawn image with name [" + nstr + 
"] found");
 
  471  if (itsUsingScaledImage) { p.x *= itsScaledImageFacX; p.y *= itsScaledImageFacY; }
 
 
  479{ 
return i2ds(ImVec2(x, y), name); }
 
 
  484  ImGui::GetBackgroundDrawList()->AddLine(i2d(x1, y1), i2d(x2, y2), col, linethick::get());
 
 
  490  auto dlb = ImGui::GetBackgroundDrawList();
 
  491  ImVec2 
const tl = i2d(x1, y1);
 
  492  ImVec2 
const br = i2d(x2, y2);
 
  494  if (filled) dlb->AddRectFilled(tl, br, applyFillAlpha(col));
 
  495  ImDrawFlags 
constexpr flags = ImDrawFlags_None; 
 
  496  float constexpr rounding = 0.0F;
 
  498  dlb->AddRect(tl, br, col, rounding, flags, linethick::get());
 
 
  504  auto dlb = ImGui::GetBackgroundDrawList();
 
  505  float const thick = linethick::get();
 
  507  if (filled) dlb->AddConvexPolyFilled(pts, npts, applyFillAlpha(col));
 
  511    for (
size_t i = 0; i < npts - 1; ++i)
 
  513      ImVec2 
const & p1 = pts[i];
 
  514      ImVec2 
const & p2 = pts[i + 1];
 
  517      if (p1.x != p2.x || p1.y != p2.y) dlb->AddLine(p1, p2, col, thick);
 
  519    dlb->AddLine(pts[npts - 1], pts[0], col, thick); 
 
 
  526  size_t const npts = pts.size();
 
  527  if (npts < 3) 
return;
 
  530  for (
int i = 0; 
auto const & p : pts) iv[i++] = i2d(p.x, p.y);
 
  532  drawPolyInternal(iv, npts, col, filled);
 
 
  538  size_t const npts = pts.size();
 
  539  if (npts < 3) 
return;
 
  542  for (
int i = 0; 
auto const & p : pts) iv[i++] = i2d(p.x, p.y);
 
  544  drawPolyInternal(iv, npts, col, filled);
 
 
  550  float const * ptr = pts.ptr<
float>(0);
 
  556    if (pts.rows == 1 || pts.cols == 1)
 
  559      int n = std::max(pts.rows, pts.cols);
 
  561      if (std::min(pts.rows, pts.cols) < 3) 
return;
 
  562      n /= 2; ImVec2 p[n]; 
for (
int i = 0; i < n; ++i) { p[i] = i2d(ptr[0], ptr[1]); ptr += 2; }
 
  563      drawPolyInternal(p, n, col, filled);
 
  565    else if (pts.rows == 2)
 
  568      if (pts.cols < 3) 
return;
 
  569      ImVec2 p[pts.cols]; 
for (
int i = 0; i < pts.cols; ++i) { p[i] = i2d(ptr[0], ptr[pts.cols]); ++ptr; }
 
  570      drawPolyInternal(p, pts.cols, col, filled);
 
  572    else if (pts.cols == 2)
 
  575      if (pts.rows < 3) 
return;
 
  576      ImVec2 p[pts.rows]; 
for (
int i = 0; i < pts.rows; ++i) { p[i] = i2d(ptr[0], ptr[1]); ptr += 2; }
 
  577      drawPolyInternal(p, pts.rows, col, filled);
 
  588      if (pts.cols < 3) 
return;
 
  589      ImVec2 p[pts.cols]; 
for (
int i = 0; i < pts.cols; ++i) { p[i] = i2d(ptr[0], ptr[1]); ptr += 2; }
 
  590      drawPolyInternal(p, pts.cols, col, filled);
 
  592    else if (pts.cols == 1)
 
  595      if (pts.rows < 3) 
return;
 
  596      ImVec2 p[pts.rows]; 
for (
int i = 0; i < pts.rows; ++i) { p[i] = i2d(ptr[0], ptr[1]); ptr += 2; }
 
  597      drawPolyInternal(p, pts.rows, col, filled);
 
 
  610  auto dlb = ImGui::GetBackgroundDrawList();
 
  612  ImVec2 
const center = i2d(x, y);
 
  613  float const rad = i2ds(r, 0).x;
 
  615  if (filled) dlb->AddCircleFilled(center, rad, applyFillAlpha(col), 0);
 
  617  dlb->AddCircle(center, rad, col, 0, linethick::get());
 
 
  623  auto dlb = ImGui::GetBackgroundDrawList();
 
  625  ImVec2 
const center = i2d(x, y);
 
  626  ImVec2 
const rad = i2ds(rx, ry);
 
  628  if (filled) dlb->AddEllipseFilled(center, rad, applyFillAlpha(col), rot, 0 );
 
  630  dlb->AddEllipse(center, rad, col, rot, 0 , linethick::get());
 
 
  636  ImGui::GetBackgroundDrawList()->AddText(i2d(x, y), col, txt);
 
 
  642  drawText(x, y, txt.c_str(), col);
 
 
  648  unsigned char alpha = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
 
  649  alpha = (
unsigned char)(fillalpha::get() * alpha);
 
  650  return (col & ~IM_COL32_A_MASK) | (alpha << IM_COL32_A_SHIFT);
 
 
  656  if (line == -1) line = ++itsLastDrawnTextLine; 
else itsLastDrawnTextLine = line;
 
  657  ImVec2 p = i2d(0, 0, name);
 
  659  p.y += 5.0F + (ImGui::GetFontSize() + 5.0F) * line;
 
 
  666  ImU32 
const c = (col == IM_COL32_BLACK_TRANS) ? ImU32(overlaycolor::get()) : col;
 
  667  ImGui::GetBackgroundDrawList()->AddText(iline(line), c, txt);
 
 
  673  itext(txt.c_str(), col, line);
 
 
  678                              unsigned short winw, 
unsigned short winh)
 
  680  unsigned short ww, wh;
 
  681  if (winw == 0 || winh == 0) itsBackend.getWindowSize(ww, wh); 
else { ww = winw; wh = winh; }
 
  690  std::string 
const msg = 
jevois::sformat(
"%s, Camera: %s:%dx%d%s, Display: RGBA:%dx%d", fpscpu.c_str(),
 
  692                                          cam2str.c_str(), ww, wh);
 
  694  ImGui::GetBackgroundDrawList()->AddText(ImVec2(10, wh-10-ImGui::GetFontSize()), overlaycolor::get(), msg.c_str());
 
 
  700  auto itr = itsImages.find(name);
 
  701  if (itr != itsImages.end()) itsImages.erase(itr);
 
 
  707  auto itr = itsImages2.find(name);
 
  708  if (itr != itsImages2.end()) itsImages2.erase(itr);
 
 
  716  float fx = 1.0F, fy = 1.0F;
 
  720    if (itsLastDrawnImage == 
nullptr) 
throw std::range_error(
"You need to call drawImage() or drawInputFrame() first");
 
  721    img = itsLastDrawnImage;
 
  722    if (itsUsingScaledImage) { fx = 1.0F / itsScaledImageFacX; fy = 1.0F / itsScaledImageFacY; }
 
  726    std::string nstr = name;
 
  727    auto itr = itsImages.find(nstr);
 
  728    if (itr == itsImages.end())
 
  732      itr = itsImages.find(nstr + 
'0');
 
  733      if (itr == itsImages.end()) 
throw std::range_error(
"No previously drawn image with name [" + nstr + 
"] found");
 
  739  ImVec2 ret = img->
d2i(p);
 
  740  ret.x *= fx; ret.y *= fy;
 
 
  746{ 
return d2i(ImVec2(x, y), name); }
 
 
  753  float fx = 1.0F, fy = 1.0F;
 
  757    if (itsLastDrawnImage == 
nullptr) 
throw std::range_error(
"You need to call drawImage() or drawInputFrame() first");
 
  758    img = itsLastDrawnImage;
 
  759    if (itsUsingScaledImage) { fx = 1.0F / itsScaledImageFacX; fy = 1.0F / itsScaledImageFacY; }
 
  763    std::string nstr = name;
 
  764    auto itr = itsImages.find(nstr);
 
  765    if (itr == itsImages.end())
 
  769      itr = itsImages.find(nstr + 
'0');
 
  770      if (itr == itsImages.end()) 
throw std::range_error(
"No previously drawn image with name [" + nstr + 
"] found");
 
  776  ImVec2 ret = img->
d2is(p);
 
  777  ret.x *= fx; ret.y *= fy;
 
 
  783{ 
return d2is(ImVec2(x, y), name); }
 
 
  789  ImGui::GetIO().MouseDrawCursor = ! itsIdle;
 
  792  if (itsIdle == 
false) drawJeVoisGUI();
 
  795  if (itsCompileState != CompilationState::Idle) compileModule();
 
  798  if (itsGlobalAlpha != 1.0F)
 
  800    if (itsGlobalAlpha < 0.0F || itsGlobalAlpha > 1.0F)
 
  802      LERROR(
"Invalid global alpha " << itsGlobalAlpha << 
" -- RESET TO 1.0");
 
  803      itsGlobalAlpha = 1.0F;
 
  807      auto dlb = ImGui::GetBackgroundDrawList();
 
  808      cv::Size 
const ws = winsize::get();
 
  809      dlb->AddRectFilled(ImVec2(0, 0), ImVec2(ws.width, ws.height), ImColor(0.0F, 0.0F, 0.0F, 1.0F - itsGlobalAlpha));
 
  814  if (itsBannerTitle.empty() == 
false)
 
  816    ImGui::SetNextWindowPos(ImVec2(800, 500));
 
  817    ImGui::SetNextWindowSize(ImVec2(1000, 400));
 
  818    ImGui::PushStyleColor(ImGuiCol_WindowBg, 0xf0e0ffe0); 
 
  819    ImGui::Begin(
"JeVois-Pro Demo Mode", 
nullptr, ImGuiWindowFlags_NoResize |
 
  820                 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse |
 
  821                 ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings);
 
  822    ImGui::SetWindowFontScale(1.5F);
 
  823    ImGui::TextUnformatted(
" ");
 
  824    ImGui::TextUnformatted(itsBannerTitle.c_str());
 
  825    ImGui::TextUnformatted(
" ");
 
  826    ImGui::SetWindowFontScale(1.0F);
 
  828    int wrap = ImGui::GetWindowSize().x - ImGui::GetFontSize() * 2.0f;
 
  829    ImGui::PushTextWrapPos(wrap);
 
  830    ImGui::TextUnformatted(itsBannerMsg.c_str());
 
  831    ImGui::PopTextWrapPos();
 
  833    ImGui::SetCursorPosY(ImGui::GetWindowSize().y - ImGui::CalcTextSize(
"X").y * 2.3F);
 
  836    if (ImGui::Button(
"Skip to Next Demo")) engine()->
nextDemo();
 
  837    ImGui::SetItemDefaultFocus();
 
  838    ImGui::SameLine(600);
 
  839    if (ImGui::Button(
"Abort Demo Mode")) engine()->
abortDemo();
 
  841    ImGui::PopStyleColor();
 
  847  itsInputFrame = 
nullptr; 
 
  848  itsEndFrameCalled = 
true;
 
 
  855  ImGui::SetNextWindowPos(ImVec2(920, 358), ImGuiCond_FirstUseEver);
 
  856  ImGui::SetNextWindowSize(ImVec2(941, 639), ImGuiCond_FirstUseEver);
 
  858  if (ImGui::Begin(itsWindowTitle.c_str(), 
nullptr ))
 
  866    if (ImGui::BeginTabBar(
"##tabs", ImGuiTabBarFlags_None))
 
  869      if (ImGui::BeginTabItem(
"Info"))
 
  875      if (ImGui::BeginTabItem(
"Parameters"))
 
  881      if (ImGui::BeginTabItem(
"Console"))
 
  887      if (ImGui::BeginTabItem(
"Camera"))
 
  893      if (ImGui::BeginTabItem(
"Config"))
 
  895        itsCfgEditor->draw();
 
  899      if (ImGui::BeginTabItem(
"Code"))
 
  901        itsCodeEditor->draw();
 
  905      if (ImGui::BeginTabItem(
"System"))
 
  911      if (ImGui::BeginTabItem(
"Tweaks"))
 
  923  if (itsShowStyleEditor)
 
  925    ImGui::Begin(
"GUI Style Editor", &itsShowStyleEditor);
 
  926    ImGui::ShowStyleEditor();
 
  929  if (itsShowAppMetrics) ImGui::ShowMetricsWindow(&itsShowAppMetrics);
 
  930  if (itsShowImGuiDemo) ImGui::ShowDemoWindow(&itsShowImGuiDemo);
 
  933  if (itsShowHardSerialWin)
 
  936    ImGui::SetNextWindowSize(ImVec2(700, 500), ImGuiCond_FirstUseEver);
 
  939    ImGui::Begin(
"Hardware 4-pin Serial Monitor", &itsShowHardSerialWin);
 
  943      ImGui::TextUnformatted(
"No Hardware serial port found!");
 
  945      ImGui::TextUnformatted(
"Check engine:serialdev parameter, and");
 
  946      ImGui::TextUnformatted(
"that engine:serialmonitors is true.");
 
  952  if (itsShowUsbSerialWin)
 
  955    ImGui::SetNextWindowSize(ImVec2(700, 500), ImGuiCond_FirstUseEver);
 
  958    ImGui::Begin(
"USB Serial Monitor", &itsShowUsbSerialWin);
 
  962      ImGui::TextUnformatted(
"No USB serial port found!");
 
  964      ImGui::TextUnformatted(
"Check engine:usbserialdev parameter, and");
 
  965      ImGui::TextUnformatted(
"that engine:serialmonitors is true.");
 
 
  977  if (ImGui::BeginMenuBar())
 
  979    if (ImGui::BeginMenu(
"File"))
 
  981      if (ImGui::MenuItem(
"Quit")) engine()->
quit();
 
 1017    if (ImGui::BeginMenu(
"Tools"))
 
 1019      ImGui::MenuItem(
"ImGui Style Editor", NULL, &itsShowStyleEditor);
 
 1020      ImGui::MenuItem(
"ImGui Metrics/Debugger", NULL, &itsShowAppMetrics);
 
 1021      ImGui::MenuItem(
"ImGui Demo/Doc", NULL, &itsShowImGuiDemo);
 
 1026    ImGui::EndMenuBar();
 
 
 1033  static std::map<std::string, size_t> mods;
 
 1035  static std::string currstr;
 
 1038  ImGui::AlignTextToFramePadding();
 
 1039  ImGui::TextUnformatted(
"Module:");
 
 1041  ImGui::SetNextItemWidth(6 * ImGui::GetFontSize() + 5);
 
 1042  if (ImGui::Combo(
"##typemachinevisionmodule", &itsVideoMappingListType, 
"Pro/GUI\0Legacy\0Headless\0\0")
 
 1043      || currstr.empty() || itsRefreshVideoMappings)
 
 1046    itsRefreshVideoMappings = 
false;
 
 1049    switch (itsVideoMappingListType)
 
 1084    default: 
LFATAL(
"Internal error, itsVideoMappingListType=" << itsVideoMappingListType);
 
 1088    currstr = e->getCurrentVideoMapping().menustr().c_str();
 
 1094  if (ImGui::BeginCombo(
"##machinevisionmodule", currstr.c_str()))
 
 1096    for (
auto const & m : mods)
 
 1098      bool is_selected = 
false;
 
 1099      if (ImGui::Selectable(m.first.c_str(), is_selected))
 
 1101        e->requestSetFormat(m.second);
 
 
 1113  std::shared_ptr<jevois::Module> m = engine()->
module();
 
 1117    if (itsIcon.loaded() == 
false)
 
 1118      try { itsIcon.load(m->absolutePath(
"icon.png")); }
 
 1122        LERROR(
"This module has no icon -- USING DEFAULT");
 
 1125          if (engine()->getCurrentVideoMapping().ispython) itsIcon.load(
JEVOIS_SHARE_PATH "/icons/py.png");
 
 1131          cv::Mat blank(32, 32, CV_8UC4, 0);
 
 1132          itsIcon.load(blank);
 
 1136    if (itsIcon.loaded())
 
 1138      int const siz = ImGui::CalcTextSize(
"      ").x;
 
 1139      itsIcon.draw(ImGui::GetCursorScreenPos(), ImVec2(siz, siz));
 
 1143    if (itsModName.empty())
 
 1145      std::filesystem::path fname = m->absolutePath(
"modinfo.html");
 
 1146      std::ifstream ifs(fname);
 
 1147      if (ifs.is_open() == 
false)
 
 1150        LINFO(
"Recomputing module's modinfo.html ...");
 
 1154          std::string 
const cmdout =
 
 1156                           "JEVOIS_SRC_ROOT=none jevoispro-modinfo " + vm.
modulename, 
true);
 
 1158          if (! std::filesystem::exists(fname))
 
 1159            throw std::runtime_error(
"Failed to create " + vm.
modinfopath() + 
": " + cmdout);
 
 1161        catch (...) { itsModName = vm.
modulename; itsModAuth = 
"Cannot read file: " + fname.string(); }
 
 1167        for (std::string s; std::getline(ifs, s); )
 
 1173            if (str.empty() == 
false) { itsModName = str; ++state; }
 
 1180            if (str.empty() == 
false) { itsModDesc = str; ++state; }
 
 1186            std::string 
const str = 
jevois::extractString(s, 
"<table class=modinfoauth width=100%>", 
"</table>");
 
 1187            if (str.empty() == 
false)
 
 1198            if (str.empty() == 
false)
 
 1202              if (tok.size() >= 3)
 
 1205                else itsModLang = 
"Language: Python"; 
 
 1207              else itsModLang = 
"Language: Unknown";
 
 1216            if (str.empty() == 
false)
 
 1220              size_t idx = str2.find_first_not_of(
" "); 
if (idx != str2.npos) str2 = str2.substr(idx);
 
 1221              itsModDoc.emplace_back(str2);
 
 1229            if (s == 
"</div></td></tr>") ++state;
 
 1235              if (s.find(
"/h1>") != s.npos || s.find(
"/h2>") != s.npos || s.find(
"/h3>") != s.npos) prefix = 
"* ";
 
 1236              if (s.find(
"<li>") != s.npos) prefix = 
"- ";
 
 1241              std::string::iterator new_end =
 
 1242                std::unique(ss.begin(), ss.end(), [](
char lhs, 
char rhs) { return (lhs == rhs) && (lhs == 
' '); });
 
 1243              ss.erase(new_end, ss.end());
 
 1244              size_t idx = ss.find_first_not_of(
" "); 
if (idx != ss.npos) ss = ss.substr(idx);
 
 1245              itsModDoc.push_back(ss);
 
 1256    ImGui::TextUnformatted((
"        " + itsModName).c_str());
 
 1257    ImGui::TextUnformatted((
"        " + itsModDesc).c_str());
 
 1258    ImGui::TextUnformatted((
"        " + itsModAuth + 
" " + itsModLang).c_str());
 
 1259    ImGui::TextUnformatted(
"   ");
 
 1261    int wrap = ImGui::GetCursorPos().x + ImGui::GetWindowSize().x - ImGui::GetFontSize() * 2.0f;
 
 1262    if (wrap < 200) wrap = 200;
 
 1263    ImGui::PushTextWrapPos(wrap);
 
 1266    for (std::string 
const & s : itsModDoc)
 
 1270        show = ImGui::CollapsingHeader(s.c_str() + 2, ImGuiTreeNodeFlags_DefaultOpen);
 
 1275        else ImGui::TextUnformatted(s.c_str());
 
 1278    ImGui::PopTextWrapPos();
 
 1281    ImGui::TextUnformatted(
"No JeVois Module currently loaded.");
 
 
 1295  static bool show_frozen = 
true; 
static bool show_system = 
false;
 
 1297  toggleButton(
"Show Frozen Parameters", &show_frozen);
 
 1298  ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::CalcTextSize(
"Show System Parameters").x - 30.0f);
 
 1299  toggleButton(
"Show System Parameters", &show_system);
 
 1305  if (c == 
nullptr) { ImGui::TextUnformatted(
"No module loaded."); 
return; }
 
 1308  std::set<std::string> pnames, ambig;
 
 1311  std::map<std::string , std::vector<jevois::ParameterSummary>> psm;
 
 1315    if (pnames.insert(psum.
name).second == 
false) ambig.insert(psum.
name);
 
 1316    psm[psum.
category].emplace_back(psum); } );
 
 1319  if (psm.empty()) { ImGui::TextUnformatted(
"This module has no parameters."); 
return; }
 
 1323  float maxlen = 0.0f;
 
 1324  for (
auto const & pp : psm)
 
 1327    if (show_frozen == 
false)
 
 1329      bool all_frozen = 
true;
 
 1330      for (
auto const & ps : pp.second) 
if (ps.frozen == 
false) { all_frozen = 
false; 
break; }
 
 1331      if (all_frozen) 
continue;
 
 1335    if (ImGui::CollapsingHeader(pp.first.c_str()))
 
 1337      ImGui::Columns(3, 
"parameters");
 
 1340      for (
auto const & ps : pp.second)
 
 1343        if (ps.frozen && show_frozen == 
false) 
continue;
 
 1346        static char wname[16]; snprintf(wname, 16, 
"##p%d", widgetnum);
 
 1350        ImGui::AlignTextToFramePadding();
 
 1351        std::string nam = ps.name;
 
 1352        if (ambig.contains(nam))
 
 1356          if (tok.size() >= 2) nam = tok[tok.size()-2] + 
':' + nam;
 
 1359        ImGui::TextUnformatted(nam.c_str());
 
 1360        if (ImGui::IsItemHovered()) ImGui::SetTooltip(
"%s", ps.descriptor.c_str());
 
 1361        maxlen = std::max(maxlen, ImGui::CalcTextSize(nam.c_str()).x);
 
 1364        ImGui::NextColumn();
 
 1365        ImGui::AlignTextToFramePadding();
 
 1366        std::string 
const & vtype = ps.valuetype;
 
 1368          helpMarker(ps.description.c_str(), (
"Parameter type: " + vtype).c_str());
 
 1370          helpMarker(ps.description.c_str(), (
"Parameter type: " + vtype).c_str(),
 
 1371                     (
"Allowed values: " + ps.validvalues).c_str());
 
 1374        ImGui::NextColumn();
 
 1375        bool const is_uchar = (vtype == 
"unsigned char");
 
 1376        bool const is_int = (vtype == 
"short" || vtype == 
"int" || vtype == 
"long int" || vtype == 
"long long int");
 
 1377        bool const is_uint = (is_uchar || vtype == 
"unsigned short" || vtype == 
"unsigned int" || 
 
 1378                              vtype == 
"unsigned long int" || vtype == 
"unsigned long long int" || vtype == 
"size_t");
 
 1379        bool const is_real = (vtype == 
"float" || vtype == 
"double" || vtype == 
"long double");
 
 1382        int textflags = ImGuiInputTextFlags_EnterReturnsTrue;
 
 1385          ImGui::PushItemFlag(ImGuiItemFlags_Disabled, 
true);
 
 1386          ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
 
 1387          textflags |= ImGuiInputTextFlags_ReadOnly;
 
 1393          std::string vals = ps.validvalues.substr(6, ps.validvalues.size() - 7);
 
 1396          if (vv.empty() == 
false)
 
 1399            int index = 0; 
for (
auto const & v : vv) 
if (v == ps.value) 
break; 
else ++index;
 
 1402            if (combo(wname, vv, index)) setparstr(ps.descriptor, vv[index]);
 
 1412            std::string rng = ps.validvalues.substr(7, ps.validvalues.size() - 8);
 
 1417              long mi = 0, ma = 255;
 
 1418              if (ImGui::SliderScalar(wname, ImGuiDataType_U64, &val, &mi, &ma))
 
 1419                setparstr(ps.descriptor, std::to_string(val));
 
 1424              if (ImGui::SliderScalar(wname, ImGuiDataType_U64, &val, &r.
min(), &r.
max()))
 
 1425                setparstr(ps.descriptor, std::to_string(val));
 
 1431            std::string rng = ps.validvalues.substr(7, ps.validvalues.size() - 8);
 
 1434            if (ImGui::SliderScalar(wname, ImGuiDataType_U64, &val, &r.
min(), &r.
max()))
 
 1435              setparstr(ps.descriptor, std::to_string(val));
 
 1440            std::string rng = ps.validvalues.substr(7, ps.validvalues.size() - 8);
 
 1443            if (ImGui::SliderScalar(wname, ImGuiDataType_S64, &val, &r.
min(), &r.
max()))
 
 1444              setparstr(ps.descriptor, std::to_string(val));
 
 1449            std::string rng = ps.validvalues.substr(7, ps.validvalues.size() - 8);
 
 1452            if (ImGui::SliderScalar(wname, ImGuiDataType_Double, &val, &r.
min(), &r.
max()))
 
 1453              setparstr(ps.descriptor, std::to_string(val));
 
 1458            char buf[256]; strncpy(buf, ps.value.c_str(), 
sizeof(buf)-1);
 
 1459            if (ImGui::InputText(wname, buf, 
sizeof(buf), textflags))
 
 1460              setparstr(ps.descriptor, buf);
 
 1464        else if (vtype == 
"jevois::Range<unsigned char>")
 
 1468          int mi = val.
min(), ma = val.
max();
 
 1469          if (ImGui::DragIntRange2(wname, &mi, &ma, 0, 0, 255, 
"Min: %d", 
"Max: %d"))
 
 1473        else if (vtype == 
"bool")
 
 1476          if (ImGui::Checkbox(wname, &val)) setparval(ps.descriptor, val);
 
 1479        else if (vtype == 
"ImColor")
 
 1482          if (ImGui::ColorEdit4(wname, (
float *)&val, ImGuiColorEditFlags_AlphaPreview)) setparval(ps.descriptor, val);
 
 1488          char buf[256]; strncpy(buf, ps.value.c_str(), 
sizeof(buf)-1);
 
 1489          if (ImGui::InputText(wname, buf, 
sizeof(buf), textflags))
 
 1490            setparstr(ps.descriptor, buf);
 
 1496          static char rname[24]; snprintf(rname, 24, 
"Reset##%d", widgetnum);
 
 1498          if (ImGui::Button(rname)) setparstr(ps.descriptor, ps.defaultvalue);
 
 1504          ImGui::PopItemFlag();
 
 1505          ImGui::PopStyleVar();
 
 1509        ImGui::NextColumn(); ++widgetnum;
 
 1513      ImGui::EndColumns();
 
 1519    ImGui::Columns(3, 
"parameters");
 
 1520    ImGui::SetColumnWidth(0, maxlen + ImGui::CalcTextSize(
"XX").x);
 
 1521    ImGui::SetColumnWidth(1, ImGui::CalcTextSize(
" (?) ").x);
 
 1522    ImGui::SetColumnWidth(2, 2000);
 
 1523    ImGui::EndColumns();
 
 
 1533  bool slusb = 
false, slhard = 
false, schanged = 
false;
 
 1537  case jevois::engine::SerPort::None: slusb = 
false; slhard = 
false; 
break;
 
 1538  case jevois::engine::SerPort::All: slusb = 
true; slhard = 
true; 
break;
 
 1539  case jevois::engine::SerPort::Hard: slusb = 
false; slhard = 
true; 
break;
 
 1540  case jevois::engine::SerPort::USB: slusb = 
true; slhard = 
false; 
break;
 
 1542  ImGui::AlignTextToFramePadding();
 
 1543  ImGui::TextUnformatted(
"Log messages:"); ImGui::SameLine();
 
 1544  if (itsUSBserial == 
false) 
 
 1546    ImGui::PushItemFlag(ImGuiItemFlags_Disabled, 
true);
 
 1547    ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
 
 1548    if (toggleButton(
"USB##serlogu", &slusb)) schanged = 
true;
 
 1549    ImGui::PopItemFlag();
 
 1550    ImGui::PopStyleVar();
 
 1551#ifdef JEVOIS_PLATFORM 
 1552    if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
 
 1554      ImGui::BeginTooltip();
 
 1555      ImGui::TextUnformatted(
"Disabled - enable USB serial in the System tab");
 
 1556      ImGui::EndTooltip();
 
 1559    if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
 
 1561      ImGui::BeginTooltip();
 
 1562      ImGui::TextUnformatted(
"Disabled - not available on host");
 
 1563      ImGui::EndTooltip();
 
 1567  else if (toggleButton(
"USB##serlogu", &slusb)) schanged = 
true;
 
 1569  ImGui::SameLine(); 
if (toggleButton(
"Hard##serlogh", &slhard)) schanged = 
true;
 
 1570  ImGui::SameLine(); toggleButton(
"Cons##serlogc", &itsSerLogEnabled);
 
 1571  ImGui::SameLine(0, 50);
 
 1573  bool sousb = 
false, sohard = 
false;
 
 1577  case jevois::engine::SerPort::None: sousb = 
false; sohard = 
false; 
break;
 
 1578  case jevois::engine::SerPort::All: sousb = 
true; sohard = 
true; 
break;
 
 1579  case jevois::engine::SerPort::Hard: sousb = 
false; sohard = 
true; 
break;
 
 1580  case jevois::engine::SerPort::USB: sousb = 
true; sohard = 
false; 
break;
 
 1582  ImGui::TextUnformatted(
"Module output:"); ImGui::SameLine();
 
 1583  if (itsUSBserial == 
false) 
 
 1585    ImGui::PushItemFlag(ImGuiItemFlags_Disabled, 
true);
 
 1586    ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
 
 1587    if (toggleButton(
"USB##seroutu", &sousb)) schanged = 
true;
 
 1588    ImGui::PopItemFlag();
 
 1589    ImGui::PopStyleVar();
 
 1590#ifdef JEVOIS_PLATFORM 
 1591    if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
 
 1593      ImGui::BeginTooltip();
 
 1594      ImGui::TextUnformatted(
"Disabled - enable USB serial in the System tab");
 
 1595      ImGui::EndTooltip();
 
 1598    if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
 
 1600      ImGui::BeginTooltip();
 
 1601      ImGui::Text(
"Disabled - not available on host");
 
 1602      ImGui::EndTooltip();
 
 1606  else if (toggleButton(
"USB##seroutu", &sousb)) schanged = 
true;
 
 1607  ImGui::SameLine(); 
if (toggleButton(
"Hard##serouth", &sohard)) schanged = 
true;
 
 1608  ImGui::SameLine(); toggleButton(
"Cons##seroutc", &itsSerOutEnabled);
 
 1614      if (slhard) e->
setParamValUnique(
"engine:serlog", jevois::engine::SerPort::All);
 
 1619      if (slhard) e->
setParamValUnique(
"engine:serlog", jevois::engine::SerPort::Hard);
 
 1625      if (sohard) e->
setParamValUnique(
"engine:serout", jevois::engine::SerPort::All);
 
 1630      if (sohard) e->
setParamValUnique(
"engine:serout", jevois::engine::SerPort::Hard);
 
 1640    int idx = 0; 
for (
auto const & v : jevois::modul::SerStyle_Values) 
if (v == sp) 
break; 
else ++idx;
 
 1643    if (combo(
"serstyle", jevois::modul::SerStyle_Strings, idx))
 
 
 1656{ 
return itsSerLogEnabled; }
 
 
 1660{ 
return itsSerOutEnabled; }
 
 
 1670                             char const * b1txt, 
char const * b2txt)
 
 1673  int ret = 0; 
int * retptr = default_val ? default_val : &ret;
 
 1676  if (*retptr == 1 || *retptr == 2) 
return *retptr;
 
 1679  if (itsOpenModals.find(title) == itsOpenModals.end())
 
 1681    ImGui::OpenPopup(title.c_str());
 
 1682    itsOpenModals.insert(title);
 
 1686  bool dont_ask_me_next_time = (*retptr == 3);
 
 1688  if (ImGui::BeginPopupModal(title.c_str(), NULL, ImGuiWindowFlags_AlwaysAutoResize))
 
 1690    ImGui::TextUnformatted(text); ImGui::TextUnformatted(
" ");
 
 1694      ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
 
 1695      ImGui::PushStyleColor(ImGuiCol_FrameBg, 0xf0ffe0e0); 
 
 1696      ImGui::Checkbox(
"Don't ask me next time", &dont_ask_me_next_time);
 
 1697      ImGui::PopStyleColor();
 
 1698      ImGui::PopStyleVar();
 
 1700    float const b1w = std::max(120.0F, ImGui::CalcTextSize(b1txt).x + 20.0F);
 
 1701    if (ImGui::Button(b1txt, ImVec2(b1w, 0))) ret = 1;
 
 1702    ImGui::SetItemDefaultFocus();
 
 1704    float const b2w = std::max(120.0F, ImGui::CalcTextSize(b2txt).x + 20.0F);
 
 1705    if (ImGui::Button(b2txt, ImVec2(b2w, 0))) ret = 2; 
 
 1710  if (ret == 1 || ret == 2)
 
 1712    ImGui::CloseCurrentPopup();
 
 1713    itsOpenModals.erase(title);
 
 1714    if (dont_ask_me_next_time) *retptr = ret; 
 
 1716  else *retptr = dont_ask_me_next_time ? 3 : 0; 
 
 
 1724  return ImGui::Combo(name.c_str(), &selected_index,
 
 1725                      [](
void * vec, 
int idx, 
const char ** out_text)
 
 1727                        auto & ve = *static_cast<std::vector<std::string>*>(vec);
 
 1728                        if (idx < 0 || idx >= static_cast<int>(ve.size())) return false;
 
 1729                        *out_text = ve.at(idx).c_str();
 
 1732                      const_cast<void *
>(
static_cast<void const *
>(&items)), items.size());
 
 
 1738  if (ImGui::GetMouseCursor() != ImGuiMouseCursor_ResizeAll) ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
 
 1743    if (ImGui::IsMouseClicked(0))
 
 1745      tl = ImGui::GetMousePos();
 
 1752    br = ImGui::GetMousePos();
 
 1753    auto dlb = ImGui::GetBackgroundDrawList();
 
 1754    dlb->AddRectFilled(tl, br, applyFillAlpha(col));
 
 1755    ImDrawFlags 
constexpr flags = ImDrawFlags_None; 
 
 1756    float constexpr rounding = 0.0F;
 
 1757    dlb->AddRect(tl, br, col, rounding, flags, linethick::get());
 
 1759    if (ImGui::IsMouseReleased(0))
 
 1762      int xmin = std::min(tl.x, br.x), xmax = std::max(tl.x, br.x);
 
 1763      int ymin = std::min(tl.y, br.y), ymax = std::max(tl.y, br.y);
 
 1765      if (xmax - xmin < 10 || ymax - ymin < 10)
 
 1769        tl.x = xmin; tl.y = ymin; br.x = xmax; br.y = ymax;
 
 1771        ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
 
 1778  default: 
LFATAL(
"Unknown state reached -- make sure you initialize state to 0 when starting a selection");
 
 
 1785                                    char const * hint, 
char const * hlp)
 
 1787  static char buf[256];
 
 1788  ImGui::AlignTextToFramePadding();
 
 1789  ImGui::TextUnformatted(desc);
 
 1790  ImGui::NextColumn();
 
 1791  helpMarker(desc, hlp);
 
 1792  ImGui::NextColumn();
 
 1793  strncpy(buf, str.c_str(), 
sizeof(buf)-1);
 
 1794  if (ImGui::InputTextWithHint(wname, hint, buf, 
sizeof(buf))) str = buf;
 
 1795  ImGui::NextColumn();
 
 
 1801  float const fontw = ImGui::GetFontSize();
 
 1803  static int refresh = 1;
 
 1804  static std::string cpu, mem, ver;
 
 1805  static size_t npu, tpu, vpu, spu; 
static int fan;
 
 1819  ImGui::TextUnformatted(cpu.c_str());
 
 1820  ImGui::TextUnformatted(mem.c_str());
 
 1821  ImGui::Text(
"NPU: %zu, TPU: %zu, VPU: %zu, SPU: %zu. Fan: %d%%", npu, tpu, vpu, spu, fan);
 
 1825  drawNewModuleForm();
 
 1829  if (ImGui::Button(
"Open Hardware serial monitor...")) itsShowHardSerialWin = 
true;
 
 1831  if (ImGui::Button(
"Open USB serial monitor...")) itsShowUsbSerialWin = 
true;
 
 1835  static std::string pingstr;
 
 1836  static int showping = 0;
 
 1837  if (ImGui::Button(
"Ping jevois.usc.edu"))
 
 1839    std::string ret = 
jevois::system(
"/usr/bin/ping -c 1 -w 2 jevois.usc.edu");
 
 1841    if (rvec.size() < 2) reportError(
"Unable to ping jevois.usc.edu");
 
 1842    else { pingstr = rvec[1]; showping = 60; }
 
 1847    ImGui::TextUnformatted(pingstr.c_str());
 
 1854  static std::string zip;
 
 1855  static std::string donestr;
 
 1856  static int state = 0;
 
 1858  ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue;
 
 1859  if (state) flags |= ImGuiInputTextFlags_ReadOnly;
 
 1860  ImGui::SetNextItemWidth(fontw * 6.0F);
 
 1862  if (ImGui::InputText(
"Load Custom DNN", buf, 
sizeof(buf), flags)) state = 1;
 
 1868    ImGui::TextUnformatted(
" ");
 
 1873    ImGui::TextUnformatted(
"-- Downloading...");
 
 1874    zip = std::string(buf) + 
".zip";
 
 1887    if (itsDnnGetFut.valid() == 
false) { reportError(
"Unknown error while loading custom DNN"); state = 0; 
break; }
 
 1888    ImGui::TextUnformatted(
"-- Downloading...");
 
 1889    if (itsDnnGetFut.wait_for(std::chrono::microseconds(100)) == std::future_status::ready)
 
 1895      if (ifs.is_open() == 
false)
 
 1897        reportError(
"Failed to download. Check network connectivity and available disk space.");
 
 1914    if (itsDnnGetFut.valid() == 
false) { reportError(
"Unknown error while unpacking custom DNN"); state = 0; 
break; }
 
 1915    ImGui::TextUnformatted(
"-- Installing...");
 
 1916    if (itsDnnGetFut.wait_for(std::chrono::microseconds(100)) == std::future_status::ready)
 
 1918      std::string ret = itsDnnGetFut.get();
 
 1921        donestr = 
"-- Invalid file, check DNN download key.";
 
 1923        donestr = 
"-- Done. Reload model zoo to take effect.";
 
 1931    ImGui::TextUnformatted(
" ");
 
 1936    ImGui::TextUnformatted(donestr.c_str());
 
 1941#ifdef JEVOIS_PLATFORM 
 1943  static int bootmode = 0;
 
 1944  ImGui::AlignTextToFramePadding();
 
 1945  ImGui::TextUnformatted(
"On boot, start:");
 
 1947  if (ImGui::Combo(
"##onboot", &bootmode, 
"(no change)\0JeVois-Pro\0Ubuntu Console\0Ubuntu Graphical\0\0"))
 
 1952    case 2: 
jevois::system(
"systemctl --no-reload set-default multi-user.target"); 
break;
 
 1953    case 3: 
jevois::system(
"systemctl --no-reload set-default graphical.target"); 
break;
 
 1954    default: 
jevois::system(
"systemctl --no-reload set-default jevoispro.target"); 
break;
 
 1961  static bool gserial = 
false;
 
 1963  if (ImGui::Checkbox(
"Enable serial outputs/logs over mini-USB (on next reboot)", &gserial))
 
 1966    ofs << (gserial ? 1 : 0) << std::endl;
 
 1973  static bool show_fan_modal = 
false;
 
 1974  if (ImGui::Button(
"Edit fan settings"))
 
 1976    itsCfgEditor->loadFile(
"/lib/systemd/system/jevoispro-fan.service");
 
 1977    show_fan_modal = 
true;
 
 1982    static int doit_default = 0;
 
 1983    int ret = modal(
"Ready to edit", 
"File will now be loaded in the Config tab of the main window and " 
 1984                    "ready to edit.\nPlease switch to the Config tab in the main window.\n\n" 
 1985                    "When you save it, we will reboot the camera.",
 
 1986                    &doit_default, 
"Ok", 
"Thanks");
 
 1989    case 1: show_fan_modal = 
false; 
break;
 
 1990    case 2: show_fan_modal = 
false; 
break;
 
 
 2004  unsigned int get_v4l2_fmt(
int idx)
 
 2008    case 0: 
return V4L2_PIX_FMT_YUYV;
 
 2009    case 1: 
return V4L2_PIX_FMT_RGB24;
 
 2010    case 2: 
return V4L2_PIX_FMT_RGB32;
 
 2011    case 3: 
return V4L2_PIX_FMT_GREY;
 
 2012    case 4: 
return V4L2_PIX_FMT_SBGGR16;
 
 2017  unsigned int get_v4l2_idx(
int fcc)
 
 2021    case V4L2_PIX_FMT_YUYV: 
return 0;
 
 2022    case V4L2_PIX_FMT_RGB24: 
return 1;
 
 2023    case V4L2_PIX_FMT_RGB32: 
return 2;
 
 2024    case V4L2_PIX_FMT_GREY: 
return 3;
 
 2025    case V4L2_PIX_FMT_SBGGR16: 
return 4;
 
 2031  void cookedCopy(std::filesystem::path 
const & src, std::filesystem::path 
const & dst,
 
 2032                  std::string 
const & name, std::string 
const & vendor, std::string 
const & synopsis,
 
 2033                  std::string 
const & author, std::string 
const & email, std::string 
const & website,
 
 2034                  std::string 
const & license, std::string 
const & videomapping)
 
 2036    std::ifstream f(src);
 
 2037    if (f.is_open() == 
false) 
LFATAL(
"Cannot read " << src);
 
 2038    std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
 
 2052    std::ofstream ofs(dst);
 
 2053    if (ofs.is_open() == 
false) 
LFATAL(
"Cannot write " << dst << 
" -- check that you are running as root.");
 
 2054    ofs << str << std::endl;
 
 2055    LINFO(
"Translated copy " << src << 
" => " << dst);             
 
 2059  void cookedCmakeClone(std::filesystem::path 
const & src, std::filesystem::path 
const & dst,
 
 2060                        std::string 
const & oldname, std::string 
const & newname,
 
 2061                        std::string 
const & oldvendor, std::string 
const & newvendor, std::string 
const & synopsis,
 
 2062                        std::string 
const & author, std::string 
const & email, std::string 
const & website,
 
 2063                        std::string 
const & license, std::string 
const & videomapping)
 
 2065    std::ifstream f(src);
 
 2066    if (f.is_open() == 
false) 
LFATAL(
"Cannot read " << src);
 
 2067    std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
 
 2082    std::ofstream ofs(dst);
 
 2083    if (ofs.is_open() == 
false) 
LFATAL(
"Cannot write " << dst << 
" -- check that you are running as root.");
 
 2084    ofs << str << std::endl;
 
 2085    LINFO(
"Translated copy " << src << 
" => " << dst);             
 
 2089  void cookedCodeClone(std::filesystem::path 
const & src, std::filesystem::path 
const & dst,
 
 2090                       std::string 
const & oldname, std::string 
const & newname)
 
 2092    std::ifstream f(src);
 
 2093    if (f.is_open() == 
false) 
LFATAL(
"Cannot read " << src);
 
 2094    std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
 
 2112    std::ofstream ofs(dst);
 
 2113    if (ofs.is_open() == 
false) 
LFATAL(
"Cannot write " << dst << 
" -- check that you are running as root.");
 
 2114    ofs << str << std::endl;
 
 2115    LINFO(
"Translated copy " << src << 
" => " << dst);             
 
 2122  float const fontw = ImGui::GetFontSize();
 
 2124  static int templ = 0; 
 
 2126  ImGui::PushStyleColor(ImGuiCol_PopupBg, 0xf0e0ffe0);
 
 2128  if (ImGui::Button(
"Create new machine vision module..."))
 
 2130    ImGui::OpenPopup(
"Create new machine vision module");
 
 2131    itsIdleBlocked = 
true; 
 
 2135  ImVec2 
const center = ImGui::GetMainViewport()->GetCenter();
 
 2136  ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
 
 2137  ImGui::SetNextWindowContentSize(ImVec2(940, 750));
 
 2139  if (ImGui::BeginPopupModal(
"Create new machine vision module", NULL, ImGuiWindowFlags_AlwaysAutoResize))
 
 2143      static std::string name, vendor, synopsis, author, email, website, license, srcvendor, srcname;
 
 2144      static int language = 0;
 
 2145      static int ofmt = 0; 
static int ow = 320, oh = 240; 
static float ofps = 30.0F;
 
 2146      static int cmode = 0;
 
 2147      static int wdrmode = 0;
 
 2148      static int cfmt = 0; 
static int cw = 1920, ch = 1080; 
static float cfps = 30.0F;
 
 2149      static int c2fmt = 1; 
static int c2w = 512, c2h = 288;
 
 2152      ImGui::AlignTextToFramePadding();
 
 2153      ImGui::TextUnformatted(
"Fill out the details below, or clone from");
 
 2156      static std::map<std::string, size_t> mods;
 
 2157      static std::string currstr = 
"...";
 
 2163      if (ImGui::BeginCombo(
"##clonemodule", currstr.c_str()))
 
 2165        for (
auto const & mod : mods)
 
 2167          bool is_selected = 
false;
 
 2168          if (ImGui::Selectable(mod.first.c_str(), is_selected))
 
 2170            m = e->getVideoMapping(mod.second);
 
 2171            currstr = mod.first;
 
 2177            { name = 
"My" + m.
modulename + std::to_string(i++); }
 
 2184            case jevois::CropType::CropScale: cmode = 0; 
break;
 
 2185            case jevois::CropType::Crop: cmode = 1; 
break;
 
 2186            case jevois::CropType::Scale: cmode = 2; 
break;
 
 2190            case jevois::WDRtype::Linear: wdrmode = 0; 
break;
 
 2191            case jevois::WDRtype::DOL: wdrmode = 1; 
break;
 
 2193            cfmt = get_v4l2_idx(m.
cfmt); cw = m.
cw; ch = m.
ch; cfps = m.
cfps;
 
 2194            c2fmt = get_v4l2_idx(m.
c2fmt); c2w = m.
c2w; c2h = m.
c2h;
 
 2204      ImGui::Columns(3, 
"new module");
 
 2206      newModEntry(
"##NewModname", name, 
"Module Name", 
"MyModule",
 
 2207                  "Required, even when cloning. Must start with an uppercase letter. " 
 2208                  "Will be a folder name under /jevoispro/modules/VendorName");
 
 2210      newModEntry(
"##NewModvendor", vendor, 
"Vendor Name", 
"MyVendor",
 
 2211                  "Required, even when cloning. Must start with an uppercase letter. " 
 2212                  "Will be a folder name under /jevoispro/modules/");
 
 2217        ImGui::PushItemFlag(ImGuiItemFlags_Disabled, 
true);
 
 2218        ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
 
 2221      newModEntry(
"##NewModsynopsis", synopsis, 
"Synopsis", 
"Detect Object of type X",
 
 2222                  "Optional. Brief description of what the module does.");
 
 2224      newModEntry(
"##NewModauthor", author, 
"Author Name", 
"John Smith", 
"Optional");
 
 2226      newModEntry(
"##NewModemail", email, 
"Author Email", 
"you@yourcompany.com", 
"Optional");
 
 2228      newModEntry(
"##NewModwebsite", website, 
"Author Website", 
"http://yourcompany.com", 
"Optional");
 
 2230      newModEntry(
"##NewModlicense", license, 
"License", 
"GPL v3", 
"Optional");
 
 2233      ImGui::AlignTextToFramePadding();
 
 2234      ImGui::TextUnformatted(
"Module Language");
 
 2235      ImGui::NextColumn();
 
 2236      helpMarker(
"Module Language", 
"Machine language to use for your module.");
 
 2237      ImGui::NextColumn();
 
 2238      ImGui::Combo(
"##NewModlanguage", &language, 
"Python\0C++\0\0");
 
 2239      ImGui::NextColumn();
 
 2242      ImGui::AlignTextToFramePadding();
 
 2243      ImGui::TextUnformatted(
"Module Template");
 
 2244      ImGui::NextColumn();
 
 2245      helpMarker(
"Module Template", 
"Type of placeholder code that will be provided to get your module started.");
 
 2246      ImGui::NextColumn();
 
 2247      if (templ < 3) ImGui::Combo(
"##NewModtemplate", &templ, 
"Pro/GUI\0Legacy\0Headless\0\0");
 
 2248      else ImGui::Combo(
"##NewModtemplate", &templ, 
"Pro/GUI\0Legacy\0Headless\0Clone\0\0");
 
 2249      ImGui::NextColumn();
 
 2252      int oflags = ImGuiInputTextFlags_None;
 
 2255        oflags |= ImGuiInputTextFlags_ReadOnly;
 
 2256        ImGui::PushItemFlag(ImGuiItemFlags_Disabled, 
true);
 
 2257        ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
 
 2260      ImGui::AlignTextToFramePadding();
 
 2261      ImGui::TextUnformatted(
"Module Output");
 
 2262      ImGui::NextColumn();
 
 2263      helpMarker(
"Module Output", 
"Output video format for legacy module.");
 
 2264      ImGui::NextColumn();
 
 2265      ImGui::SetNextItemWidth(fontw * 5.0F);
 
 2266      ImGui::Combo(
"##NewModofmt", &ofmt, 
"YUYV\0RGB\0RGBA\0GREY\0BAYER\0\0");
 
 2268      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2269      ImGui::InputInt(
"##NewModow", &ow, 0, 0, ImGuiInputTextFlags_CharsDecimal | oflags);
 
 2271      ImGui::TextUnformatted(
"x");
 
 2273      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2274      ImGui::InputInt(
"##NewModoh", &oh, 0, 0, ImGuiInputTextFlags_CharsDecimal | oflags);
 
 2276      ImGui::TextUnformatted(
"@");
 
 2278      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2279      ImGui::InputFloat(
"##NewModofps", &ofps, 0.0F, 0.0F, 
"%.1f", ImGuiInputTextFlags_CharsDecimal | oflags);
 
 2281      ImGui::TextUnformatted(
"fps");
 
 2282      ImGui::NextColumn();
 
 2286        ImGui::PopItemFlag();
 
 2287        ImGui::PopStyleVar();
 
 2291      ImGui::AlignTextToFramePadding();
 
 2292      ImGui::TextUnformatted(
"Camera Mode");
 
 2293      ImGui::NextColumn();
 
 2294      helpMarker(
"Camera Mode", 
"Camera sensor configuration for your module.");
 
 2295      ImGui::NextColumn();
 
 2296      ImGui::SetNextItemWidth(fontw * 18.0F);
 
 2297      ImGui::Combo(
"##NewModcmode", &cmode, 
"Dual-resolution (Crop+Scale)\0Single-resolution Crop\0" 
 2298                   "Single-resolution Scale\0\0");
 
 2299      ImGui::NextColumn();
 
 2302      ImGui::AlignTextToFramePadding();
 
 2303      ImGui::TextUnformatted(
"Camera WDR");
 
 2304      ImGui::NextColumn();
 
 2305      helpMarker(
"Camera WDR", 
"Camera sensor wide-dynamic-range (WDR) setting for your module. Linear is for no WDR, " 
 2306                 "DOL is for digital overlap (merging short and long exposure frames).");
 
 2307      ImGui::NextColumn();
 
 2308      ImGui::Combo(
"##NewModwdrmode", &wdrmode, 
"Linear\0\0"); 
 
 2310      ImGui::NextColumn();
 
 2313      ImGui::AlignTextToFramePadding();
 
 2314      ImGui::TextUnformatted(
"Camera Format");
 
 2315      ImGui::NextColumn();
 
 2316      helpMarker(
"Camera Format", 
"Camera video format to use for input to module and for GUI display.");
 
 2317      ImGui::NextColumn();
 
 2318      ImGui::SetNextItemWidth(fontw * 5.0F);
 
 2319      ImGui::Combo(
"##NewModcfmt", &cfmt, 
"YUYV\0RGB\0RGBA\0GREY\0BAYER\0\0");
 
 2321      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2322      ImGui::InputInt(
"##NewModcw", &cw, 0, 0, ImGuiInputTextFlags_CharsDecimal);
 
 2324      ImGui::TextUnformatted(
"x");
 
 2326      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2327      ImGui::InputInt(
"##NewModch", &ch, 0, 0, ImGuiInputTextFlags_CharsDecimal);
 
 2329      ImGui::TextUnformatted(
"@");
 
 2331      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2332      ImGui::InputFloat(
"##NewModcfps", &cfps, 0.0F, 0.0F, 
"%.1f", ImGuiInputTextFlags_CharsDecimal);
 
 2334      ImGui::TextUnformatted(
"fps");
 
 2335      ImGui::NextColumn();
 
 2338      int c2flags = ImGuiInputTextFlags_None;
 
 2341        oflags |= ImGuiInputTextFlags_ReadOnly;
 
 2342        ImGui::PushItemFlag(ImGuiItemFlags_Disabled, 
true);
 
 2343        ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
 
 2346      ImGui::AlignTextToFramePadding();
 
 2347      ImGui::TextUnformatted(
"Camera Format 2");
 
 2348      ImGui::NextColumn();
 
 2349      helpMarker(
"Camera Format 2", 
"Camera video format for the second stream (for processing).");
 
 2350      ImGui::NextColumn();
 
 2351      ImGui::SetNextItemWidth(fontw * 5.0F);
 
 2352      ImGui::Combo(
"##NewModc2fmt", &c2fmt, 
"YUYV\0RGB\0RGBA\0GREY\0BAYER\0\0");
 
 2354      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2355      ImGui::InputInt(
"##NewModc2w", &c2w, 0, 0, ImGuiInputTextFlags_CharsDecimal | c2flags);
 
 2357      ImGui::TextUnformatted(
"x");
 
 2359      ImGui::SetNextItemWidth(fontw * 4.0F);
 
 2360      ImGui::InputInt(
"##NewModc2h", &c2h, 0, 0, ImGuiInputTextFlags_CharsDecimal | c2flags);
 
 2361      ImGui::NextColumn();
 
 2365        ImGui::PopItemFlag();
 
 2366        ImGui::PopStyleVar();
 
 2371        ImGui::PopItemFlag();
 
 2372        ImGui::PopStyleVar();
 
 2376      ImGui::SetColumnWidth(0, fontw * 10.0F);
 
 2377      ImGui::SetColumnWidth(1, ImGui::CalcTextSize(
"(?)").x + 30.0F);
 
 2385      ImVec2 
const button_size(ImGui::GetFontSize() * 7.0f, 0.0f);
 
 2386      if (ImGui::Button(
"Cancel", button_size))
 
 2388        ImGui::CloseCurrentPopup();
 
 2390        ImGui::PopStyleColor();
 
 2391        itsIdleBlocked = 
false;
 
 2396      ImGui::SameLine(0, 540);
 
 2399      if (ImGui::Button(
"Create", button_size))
 
 2402        if (name.empty()) 
LFATAL(
"New Module cannot have an empty name.");
 
 2403        if (name[0]<
'A' || name[0]>
'Z') 
LFATAL(
"New Module name must start with an uppercase letter.");
 
 2404        if (vendor.empty()) 
LFATAL(
"New Module cannot have empty vendor name.");
 
 2405        LINFO(
"New Module data valid...");
 
 2409        if (std::filesystem::exists(newvdir) == 
false && std::filesystem::create_directory(newvdir) == 
false)
 
 2410          PLFATAL(
"Error creating dir " << newvdir << 
" -- check that you are running as root");
 
 2411        std::filesystem::path 
const newmdir = newvdir / name;
 
 2419          std::filesystem::path srcpath = m.
srcpath();
 
 2420          std::filesystem::path cmakepath = m.
cmakepath();
 
 2428                                                      srcname.c_str(), newmdir.c_str());
 
 2430          LINFO(
"Cloned module using: " << copycmd);
 
 2433          unlink((m.
path() + 
'/' + srcname + 
".C").c_str());
 
 2434          unlink((m.
path() + 
'/' + srcname + 
".py").c_str());
 
 2435          unlink((m.
path() + 
'/' + srcname + 
".so").c_str());
 
 2436          std::filesystem::remove_all(m.
path() + 
"/__pycache__");
 
 2437          std::filesystem::remove_all(m.
path() + 
"/build");
 
 2440          std::ostringstream oss; oss << m; vmstr = oss.
str();
 
 2441          cookedCodeClone(srcpath, m.srcpath(), srcname, name);
 
 2446            if (std::filesystem::exists(cmakepath))
 
 2447              cookedCmakeClone(cmakepath, m.cmakepath(), srcname, name, srcvendor, vendor, synopsis, author,
 
 2448                               email, website, license, vmstr);
 
 2451                         name, vendor, synopsis, author, email, website, license, vmstr);
 
 2459          if (std::filesystem::exists(newmdir))
 
 2460            LFATAL(
"Directory [" << newmdir << 
"] already exists -- Choose another name");
 
 2461          if (std::filesystem::create_directory(newmdir) == 
false)
 
 2462            PLFATAL(
"Error creating directory [" << newmdir << 
"] for new module. Maybe not running as root?");
 
 2463          LINFO(
"Created new Module directory: " << newmdir);
 
 2470          case 1: m.
ofmt = get_v4l2_fmt(ofmt); m.
ow = ow; m.
oh = oh; m.
ofps = ofps; 
break;
 
 2471          case 2: m.
ofmt = 0; 
break;
 
 2475          m.
cfmt = get_v4l2_fmt(cfmt);
 
 2476          m.
cw = cw; m.
ch = ch; m.
cfps = cfps;
 
 2483          case 0: m.
wdr = jevois::WDRtype::Linear; 
break;
 
 2484          case 1: m.
wdr = jevois::WDRtype::DOL; 
break;
 
 2490          case 0: m.
crop = jevois::CropType::CropScale;
 
 2491            m.
c2fmt = get_v4l2_fmt(c2fmt);
 
 2492            m.
c2w = c2w; m.
c2h = c2h;
 
 2494          case 1: m.
crop = jevois::CropType::Crop; 
break;
 
 2495          case 2: m.
crop = jevois::CropType::Scale; 
break;
 
 2500          std::ostringstream oss; oss << m; vmstr = oss.
str();
 
 2503          std::string code; std::string tname;
 
 2507            tname = 
"PyModule.py";
 
 2516            std::filesystem::path dstcmak = m.cmakepath();
 
 2517            cookedCopy(srccmak, dstcmak, name, vendor, synopsis, author, email, website, license, vmstr);
 
 2521          default: 
LFATAL(
"Invalid language " << language);
 
 2525          std::filesystem::path dstmod = m.srcpath();
 
 2526          cookedCopy(srcmod, dstmod, name, vendor, synopsis, author, email, website, license, vmstr);
 
 2531        LINFO(
"Added videomapping: " << vmstr);
 
 2538        if (language == 0) runNewModule();
 
 2539        else itsCompileState = CompilationState::Start;
 
 2542        name.clear(); vendor.clear(); synopsis.clear(); currstr = 
"...";
 
 2544        ImGui::CloseCurrentPopup();
 
 2545        itsIdleBlocked = 
false;
 
 2548    catch (...) { reportAndIgnoreException(); }
 
 2554  ImGui::PopStyleColor();
 
 
 2561  size_t idx = 0; 
size_t foundidx = 12345678;
 
 2563                                { 
if (itsNewMapping.isSameAs(mm)) foundidx = idx; ++idx; });
 
 2566  else LFATAL(
"Internal error, could not find the module we just created -- CHECK LOGS");
 
 2568  itsRefreshVideoMappings = 
true; 
 
 2573  else if (itsNewMapping.ofmt != 0 && itsNewMapping.ofmt != 
JEVOISPRO_FMT_GUI) itsVideoMappingListType = 1;
 
 2574  else if (itsNewMapping.ofmt == 0) itsVideoMappingListType = 2;
 
 2575  else LERROR(
"Internal error: cannot determine video mapping list type -- IGNORED"); 
 
 
 2581#define L(i,x,y,z)for(F i=x;i<y;i+=z) 
 2582#define Q(y)sin((y+t)*.03)*(1-sin(t*3)*cos(y/99+t))*9 
 2583#define H(p,w)L(k,0,5,1)d->AddCircleFilled(p+V(1,-1)*w*k/8,w*(1-k/5),k<4?0xff000000+k*0x554400:-1); 
 2584#define J(b)L(i,0,h,1){TinyImGUIdemo&o=G[int(i)];if(b*o.z>0)H(o.p,(o.z*.3+4)*o.w)} 
 2585#define O(b)i=t+1.6+j/99;if(b*sin(i)>0)H(c+v*j+u*(cos(i)*40+Q(j)),30) 
 2587F w=0;
L(z,4,20,1){w+=z;
L(yy,-l,l,z*2){
F y=yy+fmod(t*z*10,z*2);
L(i,-1,2,2)d->AddCircle(c+v*y+u*i*(w+sin((y+t)/25)*w/30),z,0xff000000+0x110e00*
int(z*z*z/384),12,z/2);}}
 
 2588h=0;
L(y,-l,l,15)
L(b,0,16,1){i=t+b*.2+y/99;
G[
h++]={c+v*y+u*(cos(i)*60+
Q(y)),sinf(i),(b<1||b>14)?2.f:1.5f};}std::sort(
G,
G+
h);
 
 2589 F j=(-2+fmod(t*3,5))*99;
J(-1)
O(-1)a=c+v*-l;
L(y,-l,l,15){b=c+v*y+u*((15-rand())&31)*.1;
L(k,0,9,1)d->AddLine(a-v,b,k<8?0x11222200*k:-1,(9-k)*4);a=b;}
O(1)
J(1)}
 
 
 2594  if (ImGui::Button(
"Open Style Editor")) itsShowStyleEditor = 
true;
 
 2596  if (ImGui::Button(
"Open App Metrics")) itsShowAppMetrics = 
true;
 
 2598  if (ImGui::Button(
"Open ImGui Demo")) itsShowImGuiDemo = 
true;
 
 2602  float camz = pixel_perfect_z;
 
 2606  static float fudgex = 0.375f;
 
 2607  static float fudgey = 0.375f;
 
 2608  static float fudgez = 0.0f;
 
 2609  unsigned short winw, winh; itsBackend.getWindowSize(winw, winh);
 
 2611  ImGui::SliderFloat(
"OpenGL Camera z", &camz, -2.0f * winh, -1.0f);
 
 2612  ImGui::SliderAngle(
"OpenGL yaw", &yaw, -179.0f, 180.0f);
 
 2613  ImGui::SliderAngle(
"OpenGL pitch", &pitch, -179.0f, 180.0f);
 
 2614  ImGui::SliderAngle(
"OpenGL roll", &roll, -179.0f, 180.0f);
 
 2616  ImGui::SliderFloat(
"fudge x", &fudgex, -1.0f, 1.0f);
 
 2617  ImGui::SliderFloat(
"fudge y", &fudgey, -1.0f, 1.0f);
 
 2618  ImGui::SliderFloat(
"fudge z", &fudgez, -1.0f, 1.0f);
 
 2621  proj = glm::perspective(glm::radians(45.0f), 
float(winw) / 
float(winh), 1.0f, winh * 2.0f);
 
 2622  proj = glm::translate(proj, glm::vec3(fudgex, fudgey, fudgez));
 
 2625  view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, camz));
 
 2626  view *= glm::yawPitchRoll(yaw, pitch, roll);
 
 2642    ImGuiIO& io = ImGui::GetIO();
 
 2643    ImGui::Begin(
"Tiny OpenGL demo", NULL, ImGuiWindowFlags_AlwaysAutoResize);
 
 2644    ImVec2 size(320.0f, 180.0f);
 
 2645    ImGui::InvisibleButton(
"canvas", size);
 
 2646    ImVec2 p0 = ImGui::GetItemRectMin();
 
 2647    ImVec2 p1 = ImGui::GetItemRectMax();
 
 2648    ImDrawList* draw_list = ImGui::GetWindowDrawList();
 
 2649    draw_list->PushClipRect(p0, p1);
 
 2652    mouse_data.x = (io.MousePos.x - p0.x) / size.x;
 
 2653    mouse_data.y = (io.MousePos.y - p0.y) / size.y;
 
 2654    mouse_data.z = io.MouseDownDuration[0];
 
 2655    mouse_data.w = io.MouseDownDuration[1];
 
 2657    drawTinyImGUIdemo(draw_list, p0, p1, size, mouse_data, (
float)ImGui::GetTime());
 
 2658    draw_list->PopClipRect();
 
 
 2666{ reportErrorOrInfo(err, 
false); }
 
 
 2670{ reportErrorOrInfo(err, 
true); }
 
 
 2677  auto now = std::chrono::steady_clock::now();
 
 2679  std::lock_guard<std::mutex> _(itsErrorMtx);
 
 2682  for (
auto & e : itsErrors) 
if (e.err == err) { e.lasttime = now; 
return; }
 
 2685  if (itsErrors.size() > 10) 
return;
 
 2686  else if (itsErrors.size() == 10)
 
 2688    ErrorData d { 
"Too many errors -- TRUNCATING", now, now, 
false };
 
 2689    itsErrors.emplace(itsErrors.end(), std::move(d));
 
 2695  itsErrors.emplace(itsErrors.end(), std::move(d));
 
 
 2703  std::lock_guard<std::mutex> _(itsErrorMtx);
 
 
 2713    catch (std::exception 
const & e)
 
 2714    { reportError(e.what()); }
 
 2715    catch (boost::python::error_already_set & e)
 
 2718    { reportError(
"Unknown error"); }
 
 2723    catch (std::exception 
const & e)
 
 2724    { reportError(prefix + 
": " + e.what()); }
 
 2725    catch (boost::python::error_already_set & e)
 
 2728    { reportError(prefix + 
": Unknown error"); }
 
 
 2735  reportAndIgnoreException(prefix);
 
 
 2742  std::lock_guard<std::mutex> _(itsErrorMtx);
 
 2743  if (itsErrors.empty()) 
return;
 
 2745  bool err_hovered = 
false, inf_hovered = 
false;
 
 2748  std::vector<char const *> errors, infos;
 
 2749  for (
auto const & e : itsErrors)
 
 2750    if (e.is_info) infos.push_back(e.err.c_str());
 
 2751    else errors.push_back(e.err.c_str());
 
 2753  ImGuiWindowFlags 
constexpr window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings |
 
 2754    ImGuiWindowFlags_NoNav | ImGuiWindowFlags_AlwaysAutoResize;
 
 2755  ImGui::SetNextWindowPos(ImVec2(10.0f, 10.0f), ImGuiCond_Always);
 
 2757  float const wrappos = ImGui::GetFontSize() * 35.0f;
 
 2760  if (errors.empty() == 
false)
 
 2762    ImGui::PushStyleColor(ImGuiCol_WindowBg, 0xc0e0e0ff);
 
 2763    if (ImGui::Begin(
"Error popup", &show, window_flags))
 
 2765      ImGui::PushTextWrapPos(wrappos);
 
 2766      ImGui::TextUnformatted(
"Error detected!                                             ");
 
 2767      for (
char const * e : errors) { ImGui::Separator(); ImGui::TextUnformatted(e); }
 
 2768      ImGui::PopTextWrapPos();
 
 2770    err_hovered = ImGui::IsWindowHovered();
 
 2771    ImGui::SetNextWindowPos(ImVec2(10.0f, 15.0f + ImGui::GetWindowSize().y), ImGuiCond_Always);
 
 2773    ImGui::PopStyleColor();
 
 2777  if (infos.empty() == 
false)
 
 2779    ImGui::PushStyleColor(ImGuiCol_WindowBg, 0xc0d0ffe0);
 
 2780    if (ImGui::Begin(
"Info popup", &show, window_flags))
 
 2782      ImGui::PushTextWrapPos(wrappos);
 
 2783      ImGui::TextUnformatted(
"Info message                                                ");
 
 2784      for (
char const * e : infos) { ImGui::Separator(); ImGui::TextUnformatted(e); }
 
 2785      ImGui::PopTextWrapPos();
 
 2787    inf_hovered = ImGui::IsWindowHovered();
 
 2789    ImGui::PopStyleColor();
 
 2793  auto itr = itsErrors.begin();
 
 2794  while (itr != itsErrors.end())
 
 2797    std::chrono::duration<float> d = std::chrono::steady_clock::now() - itr->lasttime;
 
 2798    std::chrono::duration<float> d2 = std::chrono::steady_clock::now() - itr->firsttime;
 
 2802      if (d.count() >= 1.0f && d2.count() >= 3.0F && inf_hovered == 
false) itr = itsErrors.erase(itr);
 
 2807      if (d.count() >= 1.0f && d2.count() >= 10.0F && err_hovered == 
false) itr = itsErrors.erase(itr);
 
 
 2817  ImGui::TextUnformatted(
"(?)");
 
 2818  if (ImGui::IsItemHovered())
 
 2820    ImGui::BeginTooltip();
 
 2821    ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
 
 2822    ImGui::TextUnformatted(msg);
 
 2823    if (msg2) { ImGui::Separator(); ImGui::TextUnformatted(msg2); }
 
 2824    if (msg3) { ImGui::Separator(); ImGui::TextUnformatted(msg3); }
 
 2825    ImGui::PopTextWrapPos();
 
 2826    ImGui::EndTooltip();
 
 
 2833  bool changed = 
false;
 
 2836    ImGui::PushID(name);
 
 2837    ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(4.0f/7.0f, 1.0f, 1.0f));
 
 2838    ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(4.0f/7.0f, 1.0f, 1.0f));
 
 2839    ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(4.0f/7.0f, 0.5f, 0.5f));
 
 2840    if (ImGui::Button(name)) { *val = 
false; changed = 
true; }
 
 2841    ImGui::PopStyleColor(3);
 
 2844  else if (ImGui::Button(name)) { *val = 
true; changed = 
true; }
 
 
 2852  unsigned short winw, winh;
 
 2853  startFrame(winw, winh);
 
 2855  if (itsHeadless.loaded() == 
false)
 
 2860      cv::Mat blank(winh, winw, CV_8UC4, 0);
 
 2861      itsHeadless.load(blank);
 
 2864  if (itsHeadless.loaded()) itsHeadless.draw(ImVec2(0, 0), ImVec2(winw, winh), ImGui::GetBackgroundDrawList());
 
 
 2872  ImGui::PushStyleColor(ImGuiCol_Text, 0xff0000ff);
 
 2873  ImGui::TextUnformatted(str.c_str());
 
 2874  ImGui::PopStyleColor();  
 
 
 2881  itsBannerTitle = title;
 
 
 2888  if (itsCompileState == CompilationState::Cmake || itsCompileState == CompilationState::Make ||
 
 2889      itsCompileState == CompilationState::Install || itsCompileState == CompilationState::CPack)
 
 2890    reportError(
"Still compiling... Try again later...");
 
 2891  else if (std::filesystem::exists(itsNewMapping.srcpath()) && std::filesystem::exists(itsNewMapping.cmakepath()))
 
 2892    itsCompileState = CompilationState::Start;
 
 2897    std::filesystem::path 
const & fpath = itsCodeEditor->getLoadedFilePath();
 
 2898    std::filesystem::path 
const fn = fpath.filename();
 
 2900    if (fn == 
"CMakeLists.txt" || fn.extension() == 
".C")
 
 2902      itsNewMapping = { };
 
 2903      std::filesystem::path p = fpath.parent_path();
 
 2904      itsNewMapping.modulename = p.filename();
 
 2905      itsNewMapping.vendor = p.parent_path().filename();
 
 2906      itsNewMapping.ispython = 
false;
 
 2909      if (std::filesystem::exists(itsNewMapping.srcpath()) && std::filesystem::exists(itsNewMapping.cmakepath()))
 
 2910        itsCompileState = CompilationState::Start;
 
 2911      else reportError(
"Cannot find " + itsNewMapping.srcpath() + 
" or " + itsNewMapping.cmakepath() + 
" -- IGNORED");
 
 2913    else reportError(
"Cannot compile " + fpath.string() + 
" -- IGNORED");
 
 
 2920  ImGui::PushStyleColor(ImGuiCol_WindowBg, 0xf0e0ffe0);
 
 2922  ImGui::SetNextWindowSize(ImVec2(800, 680), ImGuiCond_FirstUseEver);
 
 2925  int constexpr flags = ImGuiWindowFlags_HorizontalScrollbar;
 
 2926  bool keep_window_open = 
true;
 
 2927  if (itsCompileState == CompilationState::Error) ImGui::Begin(
"C++ Module Compilation", &keep_window_open, flags);
 
 2928  else ImGui::Begin(
"C++ Module Compilation", 
nullptr, flags);
 
 2930  ImGui::TextUnformatted((
"Compiling " + itsNewMapping.srcpath()).c_str());
 
 2931  ImGui::TextUnformatted((
"Using " +  itsNewMapping.cmakepath()).c_str());
 
 2933  std::string 
const modpath = itsNewMapping.path();
 
 2934  std::string 
const buildpath = modpath + 
"/build";
 
 2938    switch (itsCompileState)
 
 2941    case CompilationState::Start:
 
 2942      LINFO(
"Start compiling " << itsNewMapping.srcpath());
 
 2943      itsIdleBlocked = 
true;
 
 2944      for (std::string & s : itsCompileMessages) s.clear();
 
 2945      std::filesystem::remove_all(buildpath);
 
 2946      itsCompileState = CompilationState::Cmake;
 
 2951        std::filesystem::path sp(modpath + 
"/rebuild.sh");
 
 2953        std::ofstream ofs(sp);
 
 2954        if (ofs.is_open() == 
false)
 
 2955          reportError(
"Cannot write " + sp.string() + 
" -- check that you are running as root.");
 
 2959          ofs << 
"#!/bin/sh" << std::endl << 
"set -e" << std::endl;
 
 2960          ofs << 
"cmake -S " << modpath << 
" -B " << buildpath << 
" -DJEVOIS_HARDWARE=PRO" 
 2961#ifdef JEVOIS_PLATFORM 
 2962              << 
" -DJEVOIS_PLATFORM=ON -DJEVOIS_NATIVE=ON" 
 2965          ofs << 
"JEVOIS_SRC_ROOT=none cmake --build " << buildpath << std::endl;
 
 2966          ofs << 
"cmake --install " << buildpath << std::endl;
 
 2967          ofs << 
"cd " << buildpath <<
 
 2968            " && cpack && mkdir -p /jevoispro/debs && /bin/mv *.deb /jevoispro/debs/" << std::endl;
 
 2972          using std::filesystem::perms;
 
 2973          std::filesystem::permissions(sp, perms::owner_all | perms::group_read | perms::group_exec |
 
 2974                                       perms::others_read | perms::others_exec);
 
 2980    case CompilationState::Cmake:
 
 2981      if (compileCommand(
"cmake -S " + modpath + 
" -B " + buildpath +
 
 2982                         " -DJEVOIS_HARDWARE=PRO" 
 2983#ifdef JEVOIS_PLATFORM
 
 2984                         " -DJEVOIS_PLATFORM=ON -DJEVOIS_NATIVE=ON" 
 2986                         , itsCompileMessages[0]))
 
 2987        itsCompileState = CompilationState::Make;
 
 2991    case CompilationState::Make:
 
 2992      if (compileCommand(
"JEVOIS_SRC_ROOT=none cmake --build " + buildpath, itsCompileMessages[1]))
 
 2993        itsCompileState = CompilationState::Install;
 
 2997    case CompilationState::Install:
 
 2998      if (compileCommand(
"cmake --install " + buildpath, itsCompileMessages[2]))
 
 2999        itsCompileState = CompilationState::CPack;
 
 3003    case CompilationState::CPack:
 
 3004      if (compileCommand(
"cd " + buildpath + 
" && cpack && mkdir -p /jevoispro/debs && /bin/mv *.deb /jevoispro/debs/",
 
 3005                         itsCompileMessages[3]))
 
 3006        itsCompileState = CompilationState::Success;
 
 3010    case CompilationState::Success:
 
 3012      ImGui::TextUnformatted(
"Compilation success!");
 
 3013      ImGui::TextUnformatted(
"See below for details...");
 
 3015      static int run_default = 0;
 
 3016      int ret = modal(
"Success! Run the module now?", 
"Compilation success!\n\nA deb package of your module is in " 
 3017                      "/jevoispro/debs/\nif you want to share it.\n\nLoad and run the new module now?",
 
 3018                      &run_default, 
"Yes", 
"No");
 
 3023        itsIdleBlocked = 
false;
 
 3024        itsCompileState = CompilationState::Idle;
 
 3029        itsIdleBlocked = 
false;
 
 3030        itsCompileState = CompilationState::Idle;
 
 3032        itsRefreshVideoMappings = 
true;
 
 3040    case CompilationState::Error:
 
 3042      itsIdleBlocked = 
false;
 
 3043      highlightText(
"Compilation failed!");
 
 3044      ImGui::TextUnformatted(
"You may need to edit the two files above.");
 
 3045      ImGui::TextUnformatted(
"See below for details...");
 
 3047      static bool show_modal = 
false;
 
 3049      ImGui::AlignTextToFramePadding();
 
 3050      if (ImGui::Button(
"Edit CMakeLists.txt"))
 
 3051      { itsCodeEditor->loadFile(itsNewMapping.cmakepath()); show_modal = 
true; }
 
 3053      ImGui::SameLine(); ImGui::TextUnformatted(
"    "); ImGui::SameLine();
 
 3054      if (ImGui::Button((
"Edit " + itsNewMapping.modulename + 
".C").c_str()))
 
 3055      { itsCodeEditor->loadFile(itsNewMapping.srcpath()); show_modal = 
true; }
 
 3057      ImGui::SameLine(); ImGui::TextUnformatted(
"    "); ImGui::SameLine();
 
 3058      if (ImGui::Button(
"Compile again")) itsCompileState = CompilationState::Start;
 
 3064        static int doit_default = 0;
 
 3065        int ret = modal(
"Ready to edit", 
"File will now be loaded in the Code tab of the main window and " 
 3066                        "ready to edit. Please switch to the Code tab in the main window.\n\n" 
 3067                        "When you save it, we will try to compile it again.",
 
 3068                        &doit_default, 
"Close Compilation Window", 
"Keep Open");
 
 3071        case 1: show_modal = 
false; itsCompileState = CompilationState::Idle; 
break;
 
 3072        case 2: show_modal = 
false; 
break; 
 
 3081      LERROR(
"Internal error: invalid compilation state " << 
int(itsCompileState) << 
" -- RESET TO IDLE");
 
 3082      itsCompileState = CompilationState::Idle;
 
 3083      itsIdleBlocked = 
false;
 
 3085  } 
catch (...) { reportAndIgnoreException(); }
 
 3088  for (std::string & s : itsCompileMessages)
 
 3089    if (s.empty() == 
false)
 
 3091      ImGui::TextUnformatted(s.c_str());
 
 3096  ImGui::PopStyleColor();
 
 3099  if (keep_window_open == 
false) { itsIdleBlocked = 
false; itsCompileState = CompilationState::Idle; }
 
 
 3106  if (itsCompileFut.valid() == 
false)
 
 3109    msg = 
"Running: " + cmd + 
"\nPlease wait ...\n";
 
 3110    LINFO(
"Running: " + cmd);
 
 3112  else if (itsCompileFut.wait_for(std::chrono::milliseconds(1)) == std::future_status::ready)
 
 3115      msg += itsCompileFut.get() + 
"\nSuccess!";
 
 3116      LINFO(
"Success running: " << cmd);
 
 3121      LERROR(
"Failed running: " << cmd);
 
 3122      itsCompileState = CompilationState::Error;
 
 
#define JEVOIS_MODULE_PATH
Base path for modules.
 
#define JEVOIS_CUSTOM_DNN_URL
URL where custom converted DNN models can be downloaded:
 
#define JEVOIS
Helper string that evaluates to "jevois" or "jevoispro" depending on values of JEVOIS_A33 and JEVOIS_...
 
#define JEVOIS_VERSION_STRING
Software version, as string.
 
#define JEVOIS_CUSTOM_DNN_PATH
Directory where custom DNN models are stored:
 
#define JEVOISPRO_GSERIAL_FILE
Flag file for whether to enable g_serial at boot on jevoispro.
 
#define JEVOIS_SHARE_PATH
Base path for shared files (e.g., neural network weights, etc)
 
#define JEVOIS_PYDNN_PATH
Directory where python pre/net/post DNN processors are stored:
 
#define JEVOIS_ROOT_PATH
Root path for runtime jevois config files, videomappings.cfg, modules, etc.
 
void drawTinyImGUIdemo(ImDrawList *d, V a, V b, V, ImVec4, F t)
 
#define JEVOIS_WAIT_GET_FUTURE(f)
Wait for a future to become ready for 5 seconds, get(), warn and ignore exception,...
 
#define JEVOISPRO_FMT_GUI
JeVois-Pro zero-copy display of camera input frame (to be used as output mode in VideoMapping)
 
A component of a model hierarchy.
 
void setParamValUnique(std::string const ¶mdescriptor, T const &val)
Set a parameter value, simple version assuming only one parameter match.
 
void foreachParam(std::function< void(std::string const &compname, ParameterBase *p)> func, std::string const &cname="")
Run a function on every param we hold.
 
std::string getParamStringUnique(std::string const ¶mdescriptor) const
Get a parameter value by string, simple version assuming only one parameter match.
 
void setParamStringUnique(std::string const ¶mdescriptor, std::string const &val)
Set a parameter value by string, simple version assuming only one parameter match.
 
T getParamValUnique(std::string const ¶mdescriptor) const
Get a parameter value, simple version assuming only one parameter match.
 
JeVois processing engine - gets images from camera sensor, processes them, and sends results over USB...
 
void requestSetFormat(int idx)
Use this to request a format change from within process()
 
void drawCameraGUI()
Draw all camera controls into our GUI.
 
void nextDemo()
When in demo mode, switch to next demo.
 
std::shared_ptr< Module > module() const
Get a pointer to our current module (may be null)
 
void abortDemo()
When in demo mode, abort demo mode.
 
void quit()
Terminate the program.
 
VideoMapping const & getCurrentVideoMapping() const
Get the current video mapping.
 
void reloadVideoMappings()
Re-load video mappings from videomappings.cfg.
 
void foreachVideoMapping(std::function< void(VideoMapping const &m)> &&func)
Run a function on every video mapping.
 
Class to hold a GPUtexture, GPUprogram, and other data associated with rendering an image in OpenGL.
 
ImVec2 i2ds(ImVec2 const &p)
Convert a 2D size from within a rendered image to on-screen.
 
ImVec2 i2d(ImVec2 const &p)
Convert coordinates of a point from within a rendered image to on-screen.
 
ImVec2 d2i(ImVec2 const &p)
Convert coordinates of a point from on-screen to within a rendered image.
 
ImVec2 d2is(ImVec2 const &p)
Convert a 2D size from on-screen to within a rendered image.
 
Simple console with coloring and completion.
 
void draw()
Render into ImGui.
 
Editor panel for JeVois-Pro GUI.
 
void drawCircle(float x, float y, float r, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw circle over an image.
 
void endFrame()
Finish current frame and render it.
 
bool seroutEnabled() const
Tell whether user enabled serout messages to GUI console.
 
bool combo(std::string const &name, std::vector< std::string > const &items, int &selected_index)
Helper to draw a combobox from a vector of strings.
 
void resetstate(bool modulechanged=true)
Reset to default state, typically called on Module or video format change.
 
std::shared_ptr< GUIeditor > itsCfgEditor
 
ImVec2 iline(int line=-1, char const *name=nullptr)
Get coordinates of the start of a given line of text to be drawn as overlay on top of an image.
 
void reportAndIgnoreException(std::string const &prefix="")
Report current exception in a modal dialog, then ignore it.
 
void drawInputFrame(char const *name, InputFrame const &frame, int &x, int &y, unsigned short &w, unsigned short &h, bool noalias=false, bool casync=false)
Draw the input video frame from the camera using zero-copy.
 
bool startFrame(unsigned short &w, unsigned short &h)
Start a new rendering frame.
 
ImVec2 i2ds(ImVec2 p, char const *name=nullptr)
Convert a 2D size from within a rendered image to on-screen.
 
void drawText(float x, float y, char const *txt, ImU32 col=IM_COL32(128, 255, 128, 255))
Draw text over an image.
 
void reportErrorOrInfo(std::string const &err, bool is_info)
 
void drawEllipse(float x, float y, float rx, float ry, float rot=0.0F, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw ellipse over an image.
 
virtual ~GUIhelper()
Destructor.
 
void drawRect(float x1, float y1, float x2, float y2, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw rectangular box over an image.
 
void onParamChange(gui::scale const ¶m, float const &newval) override
 
bool frameStarted() const
Helper to indicate that startFrame() was called, and thus endFrame() should be called.
 
void startCompilation()
Compile a newly created module.
 
void drawInputFrame2(char const *name, InputFrame const &frame, int &x, int &y, unsigned short &w, unsigned short &h, bool noalias=false, bool casync=false)
Draw the second (scaled) input video frame from the camera using zero-copy.
 
std::shared_ptr< GUIeditor > itsCodeEditor
 
void clearErrors()
Clear all errors currently displayed in the JeVois-Pro GUI.
 
void newModEntry(char const *wname, std::string &str, char const *desc, char const *hint, char const *hlp)
 
void releaseImage(char const *name)
Release an image.
 
void iinfo(jevois::InputFrame const &inframe, std::string const &fpscpu, unsigned short winw=0, unsigned short winh=0)
Display processing and video info at bottom of screen.
 
void helpMarker(char const *msg, char const *msg2=nullptr, char const *msg3=nullptr)
Display a (?) label and show tooltip when it is hovered.
 
void demoBanner(std::string const &title="", std::string const &msg="")
Display some text in a big banner, used by demo mode.
 
void highlightText(std::string const &str)
Like ImGui::Textunformatted but in a highlight color (typically, red)
 
void reportError(std::string const &err)
Report an error in an overlay window.
 
void headlessDisplay()
Show a message that we are running headless.
 
ImVec2 i2d(ImVec2 p, char const *name=nullptr)
Convert coordinates of a point from within a rendered image to on-screen.
 
void reportAndRethrowException(std::string const &prefix="")
Report current exception in a modal dialog, then re-throw it.
 
bool selectImageBox(int &state, ImVec2 &tl, ImVec2 &br, ImU32 col=IM_COL32(128, 255, 128, 255))
Helper to select a rectangular box by dragging the mouse over the display.
 
bool idle() const
Check for idle in case startFrame() was called elsewhere.
 
ImVec2 d2is(ImVec2 p, char const *name=nullptr)
Convert a 2D size from on-screen to within a rendered image.
 
void drawLine(float x1, float y1, float x2, float y2, ImU32 col=IM_COL32(128, 255, 128, 255))
Draw line over an image.
 
void itext(char const *txt, ImU32 const &col=IM_COL32_BLACK_TRANS, int line=-1)
Draw some overlay text on top of an image.
 
void releaseImage2(char const *name)
Release an image, second video stream.
 
InputFrame const * getInputFrame() const
Get access to the InputFrame last drawn with drawInputFrame()
 
ImU32 applyFillAlpha(ImU32 col) const
 
int modal(std::string const &title, char const *text, int *default_val=nullptr, char const *b1txt="Ok", char const *b2txt="Cancel")
Helper to draw a modal with 2 choices.
 
void drawPoly(std::vector< cv::Point > const &pts, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw polygon over an image.
 
void drawPolyInternal(ImVec2 const *pts, size_t npts, ImU32 col, bool filled)
 
void setparstr(std::string const &descriptor, std::string const &val)
 
std::string itsWindowTitle
 
bool compileCommand(std::string const &cmd, std::string &msg)
 
void reportInfo(std::string const &inf)
Report a transient info message in an overlay window.
 
GUIhelper(std::string const &instance, bool conslock=false)
Constructor.
 
ImVec2 d2i(ImVec2 p, char const *name=nullptr)
Convert coordinates of a point from on-screen to within a rendered image.
 
bool toggleButton(char const *name, bool *val)
Helper to draw a toggle button.
 
void drawImage(char const *name, RawImage const &img, int &x, int &y, unsigned short &w, unsigned short &h, bool noalias=false, bool isoverlay=false)
Draw a RawImage, copying pixel data to an OpenGL texture.
 
bool serlogEnabled() const
Tell whether user enabled serlog messages to GUI console.
 
Simple class to monitor a serial port in the JeVois-Pro GUI.
 
std::shared_ptr< Comp > getComponent(std::string const &instanceName) const
Get a top-level component by instance name.
 
Base class for Parameter.
 
bool hidden() const
Returns whether parameter is hidden.
 
virtual ParameterSummary const summary() const =0
Get summary info about this parameter.
 
ParameterSummary provides a summary about a parameter.
 
std::string name
Plain name of the parameter.
 
std::string category
Category of the parameter, as a string.
 
T const & min() const
Return the minimum value.
 
T const & max() const
Return the maximum value.
 
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
 
unsigned int fmt
Pixel format as a V4L2_PIX_FMT_XXX.
 
size_t bufindex
The index of the data buffer in the kernel driver.
 
unsigned int width
Image width in pixels.
 
unsigned int height
Image height in pixels.
 
Base class for a module that supports standardized serial messages.
 
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
 
std::string getSysInfoCPU()
Get CPU info: frequency, thermal, load.
 
std::string warnAndIgnoreException(std::string const &prefix="")
Convenience function to catch an exception, issue some LERROR (depending on type),...
 
#define PLFATAL(msg)
Like LDEBUG but appends errno and strerror(errno), to be used when some system call fails.
 
std::string getSysInfoMem()
Get memory info.
 
std::string getSysInfoVersion()
Get O.S. version info.
 
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
 
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
 
std::string getPythonExceptionString(boost::python::error_already_set &)
Python exception translation to string so we can print the traceback to our serlog stream.
 
std::string shapestr(cv::Mat const &m)
Get a string of the form: "nD AxBxC... TYPE" from an n-dimensional cv::Mat with data type TYPE.
 
void paramStringToVal(std::string const &valstring, T &result)
Machine-readable conversion from string to T, for use in jevois::Parameter.
 
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async(Function &&f, Args &&... args)
Async execution using a thread pool.
 
std::string extractString(std::string const &str, std::string const &startsep, std::string const &endsep)
Extract a portion of a string between two delimiters.
 
std::string tolower(std::string const &str)
Convert string to lowercase.
 
std::string getFileString(char const *fname, int skip=0)
Read one line from a file and return it as a string.
 
std::string system(std::string const &cmd, bool errtoo=true)
Execute a command and grab stdout output to a string.
 
std::string join(std::vector< T > const &tokens, std::string const &delimiter)
Concatenate a vector of tokens into a string.
 
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
Create a string using printf style arguments.
 
size_t replaceStringAll(std::string &str, std::string const &from, std::string const &to)
Replace all instances of 'from' with 'to'.
 
bool stringStartsWith(std::string const &str, std::string const &prefix)
Return true if str starts with prefix (including if both strings are equal)
 
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
 
std::vector< std::string > split(std::string const &input, std::string const ®ex="\\s+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
 
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async_little(Function &&f, Args &&... args)
Async execution using a thread pool.
 
Main namespace for all JeVois classes and functions.
 
size_t getNumInstalledVPUs()
Get the number of Myriad-X VPUs present on this system.
 
int getFanSpeed()
Get fan speed in percent, only meaningful on JeVois-Pro Platform, all others return 0.
 
size_t getNumInstalledNPUs()
Get the number of JeVois-Pro NPUs present on this system.
 
size_t getNumInstalledTPUs()
Get the number of Coral TPUs present on this system.
 
size_t getNumInstalledSPUs()
Get the number of Hailo8 SPUs present on this system.
 
bool operator<(TinyImGUIdemo &o)
 
Simple struct to hold video mapping definitions for the processing Engine.
 
WDRtype wdr
Type of wide-dynamic-range (WDR) to use, if sensor supports it.
 
unsigned int cfmt
camera pixel format
 
unsigned int ow
output width
 
unsigned int c2fmt
When crop is CropScale, pixel format of the scaled images, otherwise 0.
 
std::string modinfopath() const
Return the full absolute path and file name of the module's modinfo.html file.
 
unsigned int c2w
When crop is CropScale, width of the scaled images, otherwise 0.
 
CropType crop
Type of crop/scale to apply if camera size does not match sensor native.
 
std::string modulename
Name of the Module that will process this mapping.
 
std::string str() const
Convenience function to print out the whole mapping in a human-friendly way.
 
float cfps
camera frame rate in frames/sec
 
bool ispython
True if the module is written in Python; affects behavior of sopath() only.
 
std::string menustr2() const
Convenience function to print out the whole mapping in a human-friendly way to be used in a menu.
 
std::string path() const
Return the full absolute path the module's directory.
 
unsigned int cw
camera width
 
float ofps
output frame rate in frames/sec
 
unsigned int c2h
When crop is CropScale, height of the scaled images, otherwise 0.
 
unsigned int ch
camera height
 
unsigned int oh
output height
 
std::string srcpath() const
Return the full absolute path and file name of the module's .C or .py file.
 
std::string menustr() const
Convenience function to print out the whole mapping in a human-friendly way to be used in a menu.
 
std::string vendor
Module creator name, used as a directory to organize the modules.
 
std::string cmakepath() const
Return the full absolute path and file name of the module's CMakeLists.txt file.
 
unsigned int ofmt
output pixel format, or 0 for no output over USB