From c7e2a2b361ced18ab297c61e8787dcbd13fa666e Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Sat, 15 Nov 2025 18:32:43 +0100 Subject: [PATCH 01/15] add ProgressBar --- CMakeLists.txt | 7 +++++ default.nix | 2 ++ flake.nix | 47 +++++++++++++++++++++++++++++ src/CMakeLists.txt | 6 +++- src/main.cpp | 4 +-- src/ui/{ => cli}/cli.cpp | 11 +++++-- src/ui/{ => cli}/cli.hpp | 4 +-- src/ui/cli/progress.cpp | 62 +++++++++++++++++++++++++++++++++++++++ src/ui/cli/progress.hpp | 39 ++++++++++++++++++++++++ src/ui/qt/main_window.cpp | 6 ++++ src/ui/qt/main_window.ui | 2 ++ src/ui/qt/progress.cpp | 53 +++++++++++++++++++++++++++++++++ src/ui/qt/progress.hpp | 36 +++++++++++++++++++++++ src/utils/progress.cpp | 47 +++++++++++++++++++++++++++++ src/utils/progress.hpp | 47 +++++++++++++++++++++++++++++ 15 files changed, 366 insertions(+), 7 deletions(-) rename src/ui/{ => cli}/cli.cpp (97%) rename src/ui/{ => cli}/cli.hpp (91%) create mode 100644 src/ui/cli/progress.cpp create mode 100644 src/ui/cli/progress.hpp create mode 100644 src/ui/qt/progress.cpp create mode 100644 src/ui/qt/progress.hpp create mode 100644 src/utils/progress.cpp create mode 100644 src/utils/progress.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 07d18f0e..db1647b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,13 @@ if( CLI11_FOUND ) message( STATUS "Found CLI11: ${CLI11_DIR} ${CLI11_VERSION}" ) endif() +# TODO match indicators and spdlog +# https://github.com/bkryza/clang-uml/blob/fc3fc12/src/common/generators/progress_indicator.cc +find_package( indicators REQUIRED ) +if( indicators_FOUND ) + message( STATUS "Found indicators: ${indicators_DIR} ${indicators_VERSION}" ) +endif() + find_package( Qt6 COMPONENTS Core REQUIRED diff --git a/default.nix b/default.nix index 15006c8d..0b47584e 100644 --- a/default.nix +++ b/default.nix @@ -5,6 +5,7 @@ , git , texlive , cli11 +, indicators , pugixml , qtbase , wrapQtAppsHook @@ -46,6 +47,7 @@ stdenv.mkDerivation { buildInputs = [ cli11 + indicators (pugixml.override { shared = true; }) qtbase ]; diff --git a/flake.nix b/flake.nix index 78e0429e..a259d904 100644 --- a/flake.nix +++ b/flake.nix @@ -162,6 +162,7 @@ pkgs = final: prev: { openemsh = prev.qt6.callPackage ./default.nix { inherit lib; + inherit (final) indicators; }; openemshMingw64 = prev.pkgsCross.mingwW64.qt6.callPackage ./default.nix { @@ -171,6 +172,52 @@ inherit (prev.python3Packages) cairosvg; + indicators = prev.callPackage ( + { lib, stdenv, fetchpatch, fetchFromGitHub, cmake, ninja }: + stdenv.mkDerivation rec { + pname = "indicators"; +# version = "2.3"; + version = "master"; + + src = fetchFromGitHub { + owner = "p-ranav"; + repo = "indicators"; +# rev = "v${version}"; + rev = version; +# hash = "sha256-FA07UbuhsA7HThbyxHxS+V4H5ha0LAXU7sukVfPVpdg="; + hash = "sha256-1/Ut6Qilabqq2az5mu3r5vIUV7aXan26wglaY4SDU1U="; + }; + + patches = [ + (fetchpatch { + # https://github.com/p-ranav/indicators/pull/130 + url = "https://github.com/p-ranav/indicators/pull/130.patch"; + hash = "sha256-OEF6CnCPMBCETm5MEtF1DmbNCs+UK54lSE4e1S6zAmc="; + }) +# (fetchpatch { +# # https://github.com/p-ranav/indicators/pull/133 +# url = "https://github.com/p-ranav/indicators/pull/133.patch"; +# hash = "sha256-A3HZnBE8JNKMZprmmIZNLfa8eyCzSBKhvmpmNhiIgK0="; +# }) + ]; + + nativeBuildInputs = [ cmake ninja ]; + + cmakeFlags = [ + "-DBUILD_SHARED_LIBS=ON" + "-DINDICATORS_SAMPLES=OFF" + "-DINDICATORS_DEMO=OFF" + "-DINDICATORS_TESTS=OFF" + ]; + + meta = with lib; { + description = "Activity Indicators for Modern C++"; + homepage = "https://github.com/p-ranav/indicators"; + license = licenses.mit; + maintainers = with maintainers; []; + }; + }) {}; + csxcad = (prev.csxcad.overrideAttrs (new: old: { version = "0.6.3"; src = prev.fetchFromGitHub { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d168d11..ef6b6c85 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources( openemsh "${CMAKE_CURRENT_SOURCE_DIR}/utils/entity.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/utils/tree_node.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/utils/state_management.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/utils/progress.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/space.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/relation.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/bounding.cpp" @@ -80,7 +81,8 @@ add_executable( openemsh_bin WIN32 ) target_sources( openemsh_bin PRIVATE - "${CMAKE_CURRENT_SOURCE_DIR}/ui/cli.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ui/cli/cli.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ui/cli/progress.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/utils/nodegraph/highlightable.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/utils/nodegraph/port.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/utils/nodegraph/text.cpp" @@ -122,6 +124,7 @@ target_sources( openemsh_bin "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/about_dialog.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/icons.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/main_window.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/progress.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/style.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ui/qt/resources.qrc" "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" @@ -163,6 +166,7 @@ target_link_libraries( openemsh_bin PRIVATE openemsh CLI11::CLI11 + indicators::indicators Qt6::Core Qt6::Gui Qt6::Widgets diff --git a/src/main.cpp b/src/main.cpp index 9ce8f1d5..3effed48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,12 +9,12 @@ #include #include "app/openemsh.hpp" -#include "ui/cli.hpp" +#include "ui/cli/cli.hpp" #include "ui/qt/main_window.hpp" //****************************************************************************** int main(int argc, char* argv[]) { - app::OpenEMSH oemsh(ui::cli(argc, argv)); + app::OpenEMSH oemsh(ui::cli::cli(argc, argv)); if(!oemsh.get_params().gui) { oemsh.parse(); diff --git a/src/ui/cli.cpp b/src/ui/cli/cli.cpp similarity index 97% rename from src/ui/cli.cpp rename to src/ui/cli/cli.cpp index b8a22ace..9f7a7ede 100644 --- a/src/ui/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -15,6 +15,7 @@ #include "utils/concepts.hpp" #include "utils/unreachable.hpp" +#include "progress.hpp" #include "cli.hpp" @@ -25,7 +26,7 @@ // TODO CLI --board // TODO CLI --structure -zx -yz -xy -namespace ui { +namespace ui::cli { using namespace std; @@ -214,7 +215,13 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { apply(to_override); }; + if(params.verbose) + Progress::singleton().register_impl_builder( + [](size_t max, string const& message) { + return make_unique(max, message); + }); + return params; } -} // namespace ui +} // namespace ui::cli diff --git a/src/ui/cli.hpp b/src/ui/cli/cli.hpp similarity index 91% rename from src/ui/cli.hpp rename to src/ui/cli/cli.hpp index 1837d5e0..b29b7e0a 100644 --- a/src/ui/cli.hpp +++ b/src/ui/cli/cli.hpp @@ -8,9 +8,9 @@ #include "app/openemsh.hpp" -namespace ui { +namespace ui::cli { //****************************************************************************** app::OpenEMSH::Params cli(int argc, char* argv[]) noexcept(false); -} // namespace ui +} // namespace ui::cli diff --git a/src/ui/cli/progress.cpp b/src/ui/cli/progress.cpp new file mode 100644 index 00000000..35a91c46 --- /dev/null +++ b/src/ui/cli/progress.cpp @@ -0,0 +1,62 @@ +///***************************************************************************** +/// @date Feb 2021 +/// @copyright GPL-3.0-or-later +/// @author Thomas Lepoix +///***************************************************************************** + +#include + +#include "progress.hpp" + +using namespace std; + +namespace ui::cli { + +//****************************************************************************** +ProgressBar::ProgressBar(size_t max, string const& prefix) +: bar(make_unique( +// indicators::option::BarWidth { 100 }, + indicators::option::Start { "[" }, + indicators::option::End { "]" }, + indicators::option::ForegroundColor { indicators::Color::green }, + indicators::option::ShowPercentage { true }, + indicators::option::ShowElapsedTime { true }, + indicators::option::PrefixText { prefix }, + indicators::option::MaxProgress { max } +)) +, max(to_string(max)) +, prefix(prefix) +{} + +//****************************************************************************** +ProgressBar::~ProgressBar() = default; + +//****************************************************************************** +void ProgressBar::tick(size_t i) { + string postfix(to_string(++i) + "/" + max); + resize_to_term(postfix); + bar->set_option(indicators::option::PostfixText { postfix }); + bar->set_progress(i); +} + +//****************************************************************************** +void ProgressBar::tick(size_t i, size_t j) { + string postfix(to_string(i) + "/" + to_string(j) + "/" + max); + resize_to_term(postfix); + bar->set_option(indicators::option::PostfixText { postfix }); + bar->set_progress(j); +} + +//****************************************************************************** +void ProgressBar::resize_to_term(string const& postfix) { + // TODO This does not take into account percentage nor time + // " 100% [000m:00s] " 17 chars + bar->set_option(indicators::option::BarWidth { 100 - prefix.size() - postfix.size() - 19 }); +} + +//****************************************************************************** +void ProgressBar::complete() { + bar->mark_as_completed(); +} + +} // namespace ui::cli diff --git a/src/ui/cli/progress.hpp b/src/ui/cli/progress.hpp new file mode 100644 index 00000000..2af5ae98 --- /dev/null +++ b/src/ui/cli/progress.hpp @@ -0,0 +1,39 @@ +///***************************************************************************** +/// @date Feb 2021 +/// @copyright GPL-3.0-or-later +/// @author Thomas Lepoix +///***************************************************************************** + +#pragma once + +#include +#include +#include + +#include "utils/progress.hpp" + +namespace indicators { +class BlockProgressBar; +} // namespace indicators + +namespace ui::cli { + +//****************************************************************************** +class ProgressBar final : public Progress::IBar { +public: + ProgressBar(std::size_t max, std::string const& prefix); + ~ProgressBar() override; + + void tick(std::size_t i) override; + void tick(std::size_t i, std::size_t j) override; + void complete() override; + +private: + void resize_to_term(std::string const& postfix); + + std::unique_ptr bar; + std::string max; + std::string prefix; +}; + +} // namespace ui::cli diff --git a/src/ui/qt/main_window.cpp b/src/ui/qt/main_window.cpp index e261e9c9..18307ef7 100644 --- a/src/ui/qt/main_window.cpp +++ b/src/ui/qt/main_window.cpp @@ -19,6 +19,7 @@ #include "utils/state_management.hpp" #include "utils/unreachable.hpp" #include "about_dialog.hpp" +#include "progress.hpp" #include "settings.hpp" #include "ui_main_window.h" @@ -45,6 +46,11 @@ MainWindow::MainWindow(app::OpenEMSH& oemsh, QWidget* parent) // TODO Init StructureView & ProcessingView stuff from buttons default values + Progress::singleton().register_impl_builder( + [this](std::size_t max, std::string const& message) { + return make_unique(ui->statusBar, max, message); + }); + for(auto const& style : Style::available_styles) { auto* const action = new QAction(style.name, ui->ag_styles); action->setCheckable(true); diff --git a/src/ui/qt/main_window.ui b/src/ui/qt/main_window.ui index b9f07ec2..f39987e4 100644 --- a/src/ui/qt/main_window.ui +++ b/src/ui/qt/main_window.ui @@ -659,6 +659,8 @@ + + About diff --git a/src/ui/qt/progress.cpp b/src/ui/qt/progress.cpp new file mode 100644 index 00000000..e644834d --- /dev/null +++ b/src/ui/qt/progress.cpp @@ -0,0 +1,53 @@ +///***************************************************************************** +/// @date Feb 2021 +/// @copyright GPL-3.0-or-later +/// @author Thomas Lepoix +///***************************************************************************** + +#include +#include +#include +#include + +#include "progress.hpp" + +using namespace std; + +namespace ui::qt { + +//****************************************************************************** +ProgressBar::ProgressBar(QStatusBar* status_bar, size_t max, string const& message) +: status_bar(status_bar) +, bar(new QProgressBar()) +, label(new QLabel(QString::fromStdString(message))) +{ + bar->setRange(0, max); + status_bar->addWidget(bar); + status_bar->addWidget(label); +} + +//****************************************************************************** +ProgressBar::~ProgressBar() { + status_bar->removeWidget(label); + status_bar->removeWidget(bar); + delete label; + delete bar; +} + +//****************************************************************************** +void ProgressBar::tick(size_t i) { + bar->setValue(++i); +} + +//****************************************************************************** +void ProgressBar::tick(size_t /*i*/, size_t j) { + bar->setValue(++j); +} + +//****************************************************************************** +void ProgressBar::complete() { + status_bar->removeWidget(label); + status_bar->removeWidget(bar); +} + +} // namespace ui::qt diff --git a/src/ui/qt/progress.hpp b/src/ui/qt/progress.hpp new file mode 100644 index 00000000..05f686b4 --- /dev/null +++ b/src/ui/qt/progress.hpp @@ -0,0 +1,36 @@ +///***************************************************************************** +/// @date Feb 2021 +/// @copyright GPL-3.0-or-later +/// @author Thomas Lepoix +///***************************************************************************** + +#pragma once + +#include +#include + +#include "utils/progress.hpp" + +class QLabel; +class QProgressBar; +class QStatusBar; + +namespace ui::qt { + +//****************************************************************************** +class ProgressBar final : public Progress::IBar { +public: + ProgressBar(QStatusBar* status_bar, std::size_t max, std::string const& message); + ~ProgressBar() override; + + void tick(std::size_t i) override; + void tick(std::size_t i, std::size_t j) override; + void complete() override; + +private: + QStatusBar* status_bar; + QProgressBar* bar; + QLabel* label; +}; + +} // namespace ui::qt diff --git a/src/utils/progress.cpp b/src/utils/progress.cpp new file mode 100644 index 00000000..88a97314 --- /dev/null +++ b/src/utils/progress.cpp @@ -0,0 +1,47 @@ +///***************************************************************************** +/// @date Feb 2021 +/// @copyright GPL-3.0-or-later +/// @author Thomas Lepoix +///***************************************************************************** + +#include "progress.hpp" + +using namespace std; + +//****************************************************************************** +Progress::Bar::Bar(size_t max, string const& prefix) { + for(auto& builder : Progress::singleton().impl_builders) + impls.push_back(builder(max, prefix)); +} + +//****************************************************************************** +Progress::Bar::~Bar() = default; + +//****************************************************************************** +void Progress::Bar::tick(size_t i) { + for(auto& impl : impls) + impl->tick(i); +} + +//****************************************************************************** +void Progress::Bar::tick(size_t i, size_t j) { + for(auto& impl : impls) + impl->tick(i, j); +} + +//****************************************************************************** +void Progress::Bar::complete() { + for(auto& impl : impls) + impl->complete(); +} + +//****************************************************************************** +Progress& Progress::singleton() { + static Progress p; + return p; +} + +//****************************************************************************** +void Progress::register_impl_builder(function (size_t, string const&)> const& builder) { + impl_builders.push_back(builder); +} diff --git a/src/utils/progress.hpp b/src/utils/progress.hpp new file mode 100644 index 00000000..94427dcd --- /dev/null +++ b/src/utils/progress.hpp @@ -0,0 +1,47 @@ +///***************************************************************************** +/// @date Feb 2021 +/// @copyright GPL-3.0-or-later +/// @author Thomas Lepoix +///***************************************************************************** + +#pragma once + +#include +#include +#include +#include +#include + +//****************************************************************************** +class Progress { +public: + + //************************************************************************** + class IBar { + public: + virtual ~IBar() = default; + virtual void tick(std::size_t i) = 0; + virtual void tick(std::size_t i, std::size_t j) = 0; + virtual void complete() = 0; + }; + + //************************************************************************** + class Bar final : public IBar { + private: + std::vector> impls; + + public: + Bar(std::size_t max, std::string const& prefix); + ~Bar() override; + + void tick(std::size_t i) override; + void tick(std::size_t i, std::size_t j) override; + void complete() override; + }; + + static Progress& singleton(); + void register_impl_builder(std::function (std::size_t, std::string const&)> const& builder); + +private: + std::vector (std::size_t, std::string const&)>> impl_builders; +}; From a585f3b4d3723ad01463f64f4e2fc8c06a6c06d0 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Mon, 17 Nov 2025 19:08:28 +0100 Subject: [PATCH 02/15] add cell number in status bar --- src/domain/board.cpp | 6 ++++++ src/domain/board.hpp | 1 + src/domain/meshline_policy_manager.cpp | 8 ++++++++ src/domain/meshline_policy_manager.hpp | 1 + src/ui/qt/main_window.cpp | 16 +++++++++++++++- src/ui/qt/main_window.hpp | 2 ++ src/ui/qt/main_window.ui | 8 +++++++- 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/domain/board.cpp b/src/domain/board.cpp index e85453f6..4c5dee6d 100644 --- a/src/domain/board.cpp +++ b/src/domain/board.cpp @@ -518,4 +518,10 @@ vector> const& Board::get_conflicts return conflict_manager->get_too_close_meshline_policies(axis); } +//****************************************************************************** +size_t Board::get_mesh_cell_number() const { + return line_policy_manager->get_mesh_cell_number(); +} + + } // namespace domain diff --git a/src/domain/board.hpp b/src/domain/board.hpp index 1d406178..ced0b468 100644 --- a/src/domain/board.hpp +++ b/src/domain/board.hpp @@ -108,6 +108,7 @@ class Board std::vector> const& get_conflicts_edge_in_polygons(Plane const plane) const; std::vector> const& get_conflicts_colinear_edges(Axis const axis) const; std::vector> const& get_conflicts_too_close_meshline_policies(Axis const axis) const; + std::size_t get_mesh_cell_number() const; private: std::shared_ptr find_ambient_material(Plane plane, Segment const& segment) const; diff --git a/src/domain/meshline_policy_manager.cpp b/src/domain/meshline_policy_manager.cpp index 9015e7b8..5cfbe0aa 100644 --- a/src/domain/meshline_policy_manager.cpp +++ b/src/domain/meshline_policy_manager.cpp @@ -212,4 +212,12 @@ vector> const& MeshlinePolicyManager::get_intervals(Axis ax return get_current_state().intervals[axis]; } +//****************************************************************************** +size_t MeshlinePolicyManager::get_mesh_cell_number() const { + size_t n = 1; + for(auto const& axis : get_current_state().meshlines) + n *= axis.size(); + return n; +} + } // namespace domain diff --git a/src/domain/meshline_policy_manager.hpp b/src/domain/meshline_policy_manager.hpp index 3e0c81cf..61822053 100644 --- a/src/domain/meshline_policy_manager.hpp +++ b/src/domain/meshline_policy_manager.hpp @@ -69,6 +69,7 @@ class MeshlinePolicyManager // TODO MeshlineManager std::vector> const& get_meshlines(Axis axis) const; std::vector> const& get_meshline_policies(Axis axis) const; std::vector> const& get_intervals(Axis axis) const; + std::size_t get_mesh_cell_number() const; }; #ifdef UNITTEST diff --git a/src/ui/qt/main_window.cpp b/src/ui/qt/main_window.cpp index 18307ef7..6265ad3e 100644 --- a/src/ui/qt/main_window.cpp +++ b/src/ui/qt/main_window.cpp @@ -46,6 +46,8 @@ MainWindow::MainWindow(app::OpenEMSH& oemsh, QWidget* parent) // TODO Init StructureView & ProcessingView stuff from buttons default values + ui->statusBar->addPermanentWidget(ui->l_cell_number); + Progress::singleton().register_impl_builder( [this](std::size_t max, std::string const& message) { return make_unique(ui->statusBar, max, message); @@ -80,18 +82,28 @@ void MainWindow::parse_and_display() { QGuiApplication::restoreOverrideCursor(); } +//****************************************************************************** +void MainWindow::update_cell_number(bool reset) { + static QString const base_str(ui->l_cell_number->text()); + // TODO space padding every 10^3 + ui->l_cell_number->setText(reset + ? base_str + : base_str + QString::number(oemsh.get_board().get_mesh_cell_number())); +} + //****************************************************************************** void MainWindow::update_title() { static QString const base_title(windowTitle()); if(!csx_file.isEmpty()) - setWindowTitle(base_title + " - " + csx_file); + setWindowTitle(csx_file + " - " + base_title); } //****************************************************************************** void MainWindow::clear() { ui->structure_view->clear(); ui->processing_view->clear(); + update_cell_number(true); } //****************************************************************************** @@ -403,6 +415,7 @@ void MainWindow::go_to_current_state() { ui->structure_view->go_to_current_state(); ui->processing_view->go_to_current_state(); update_navigation_buttons_visibility(); + update_cell_number(); update_show_buttons_pressing(); // TODO handle passing selection from a scene to its own future couterpart } @@ -432,6 +445,7 @@ void MainWindow::make_current_state_view() { this, &MainWindow::handle_edition_from); update_navigation_buttons_visibility(); + update_cell_number(); } //****************************************************************************** diff --git a/src/ui/qt/main_window.hpp b/src/ui/qt/main_window.hpp index 0fad6f76..27dc4ac8 100644 --- a/src/ui/qt/main_window.hpp +++ b/src/ui/qt/main_window.hpp @@ -36,6 +36,8 @@ class MainWindow : public QMainWindow { void update_title(); void update_navigation_buttons_visibility(); void update_show_buttons_pressing(); + void update_cell_number(bool reset = false); + void go_to_current_state(); void make_current_state_view(); void go_to_or_make_current_state(); diff --git a/src/ui/qt/main_window.ui b/src/ui/qt/main_window.ui index f39987e4..66ccab2b 100644 --- a/src/ui/qt/main_window.ui +++ b/src/ui/qt/main_window.ui @@ -659,7 +659,13 @@ - + + + + Mesh cells: + + + From 8bc86530b6df87ddf6c05c3948931290e16f4ad0 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Mon, 17 Nov 2025 20:18:32 +0100 Subject: [PATCH 03/15] add step number in progress bar --- src/app/openemsh.cpp | 10 ++++++++++ src/app/openemsh.hpp | 1 + src/app/steps.hpp | 29 +++++++++++++++++++++++++++++ src/main.cpp | 10 ++++++++++ src/ui/cli/cli.cpp | 7 ------- src/ui/qt/main_window.cpp | 5 ++++- src/ui/qt/progress.cpp | 5 ++--- src/ui/qt/progress.hpp | 5 +++-- 8 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/app/openemsh.cpp b/src/app/openemsh.cpp index 8d367499..a8ebb0a6 100644 --- a/src/app/openemsh.cpp +++ b/src/app/openemsh.cpp @@ -213,6 +213,16 @@ bool OpenEMSH::can_go_before() const { return Caretaker::singleton().find_first_ancestor_with_annotation(); } +//****************************************************************************** +optional OpenEMSH::get_current_step() const { + auto& c = Caretaker::singleton(); + auto* t = c.find_first_ancestor_with_annotation(true); + if(auto const* a = c.get_annotation(t); a) + return static_cast(a)->before_step; + else + return nullopt; +} + //****************************************************************************** Annotation::Annotation(Step before_step) : before_step(before_step) diff --git a/src/app/openemsh.hpp b/src/app/openemsh.hpp index dc7890be..496bdcbf 100644 --- a/src/app/openemsh.hpp +++ b/src/app/openemsh.hpp @@ -76,6 +76,7 @@ class OpenEMSH { bool can_run_a_next_step() const; bool can_go_before() const; + std::optional get_current_step() const; private: Params params; std::shared_ptr board; diff --git a/src/app/steps.hpp b/src/app/steps.hpp index 3cef9456..e9d25361 100644 --- a/src/app/steps.hpp +++ b/src/app/steps.hpp @@ -6,6 +6,10 @@ #pragma once +#include + +#include "utils/unreachable.hpp" + namespace app { //****************************************************************************** @@ -22,4 +26,29 @@ enum class Step { MESH }; +// TODO refactor with ITERABLE_ENUM +//****************************************************************************** +inline std::size_t index(std::optional step) { + if(!step.has_value()) return 0; + + switch(step.value()) { + case Step::ADJUST_EDGE_TO_MATERIAL: return 1; + case Step::DETECT_CONFLICT_EIP: return 2; + case Step::DETECT_CONFLICT_CE: return 3; + case Step::ADD_FIXED_MLP: return 4; + case Step::SOLVE_ALL_EIP: return 5; + case Step::SOLVE_ALL_CE: return 6; + case Step::DETECT_INDIVIDUAL_EDGES: return 7; + case Step::DETECT_AND_SOLVE_TCMLP: return 8; + case Step::DETECT_INTERVALS: return 9; + case Step::MESH: return 10; + default: ::unreachable(); + } +} + +//****************************************************************************** +inline std::size_t index_max() { + return index(Step::MESH); +} + } // namespace app diff --git a/src/main.cpp b/src/main.cpp index 3effed48..b0e7bff4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,12 +10,22 @@ #include "app/openemsh.hpp" #include "ui/cli/cli.hpp" +#include "ui/cli/progress.hpp" #include "ui/qt/main_window.hpp" //****************************************************************************** int main(int argc, char* argv[]) { app::OpenEMSH oemsh(ui::cli::cli(argc, argv)); + if(oemsh.get_params().verbose) + Progress::singleton().register_impl_builder( + [&oemsh](std::size_t max, std::string const& message) { + return std::make_unique(max, + std::to_string(app::index(oemsh.get_current_step())) + + "/" + std::to_string(app::index_max()) + + " " + message); + }); + if(!oemsh.get_params().gui) { oemsh.parse(); oemsh.run_all_steps(); diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index 9f7a7ede..980c98e3 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -15,7 +15,6 @@ #include "utils/concepts.hpp" #include "utils/unreachable.hpp" -#include "progress.hpp" #include "cli.hpp" @@ -215,12 +214,6 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { apply(to_override); }; - if(params.verbose) - Progress::singleton().register_impl_builder( - [](size_t max, string const& message) { - return make_unique(max, message); - }); - return params; } diff --git a/src/ui/qt/main_window.cpp b/src/ui/qt/main_window.cpp index 6265ad3e..7edcbd06 100644 --- a/src/ui/qt/main_window.cpp +++ b/src/ui/qt/main_window.cpp @@ -50,7 +50,10 @@ MainWindow::MainWindow(app::OpenEMSH& oemsh, QWidget* parent) Progress::singleton().register_impl_builder( [this](std::size_t max, std::string const& message) { - return make_unique(ui->statusBar, max, message); + return std::make_unique(ui->statusBar, max, + QString::number(app::index(this->oemsh.get_current_step())) + + "/" + QString::number(app::index_max()) + + " " + QString::fromStdString(message)); }); for(auto const& style : Style::available_styles) { diff --git a/src/ui/qt/progress.cpp b/src/ui/qt/progress.cpp index e644834d..28dcbd18 100644 --- a/src/ui/qt/progress.cpp +++ b/src/ui/qt/progress.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include "progress.hpp" @@ -16,10 +15,10 @@ using namespace std; namespace ui::qt { //****************************************************************************** -ProgressBar::ProgressBar(QStatusBar* status_bar, size_t max, string const& message) +ProgressBar::ProgressBar(QStatusBar* status_bar, size_t max, QString const& message) : status_bar(status_bar) , bar(new QProgressBar()) -, label(new QLabel(QString::fromStdString(message))) +, label(new QLabel(message)) { bar->setRange(0, max); status_bar->addWidget(bar); diff --git a/src/ui/qt/progress.hpp b/src/ui/qt/progress.hpp index 05f686b4..912423bb 100644 --- a/src/ui/qt/progress.hpp +++ b/src/ui/qt/progress.hpp @@ -7,7 +7,8 @@ #pragma once #include -#include + +#include #include "utils/progress.hpp" @@ -20,7 +21,7 @@ namespace ui::qt { //****************************************************************************** class ProgressBar final : public Progress::IBar { public: - ProgressBar(QStatusBar* status_bar, std::size_t max, std::string const& message); + ProgressBar(QStatusBar* status_bar, std::size_t max, QString const& message); ~ProgressBar() override; void tick(std::size_t i) override; From b46997a1c272cfd953ac09f58d5869ece24c0250 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Mon, 24 Nov 2025 03:15:24 +0100 Subject: [PATCH 04/15] add progress bar for each step --- src/domain/board.cpp | 56 +++++++++++++++++++++++--- src/domain/conflict_manager.cpp | 20 ++++++++- src/domain/meshline_policy_manager.cpp | 31 +++++++++++++- src/infra/parsers/parser_from_csx.cpp | 10 ++++- src/ui/cli/progress.cpp | 24 ++++++----- src/ui/cli/progress.hpp | 4 +- src/utils/progress.cpp | 23 ++++++++++- src/utils/progress.hpp | 7 +++- 8 files changed, 147 insertions(+), 28 deletions(-) diff --git a/src/domain/board.cpp b/src/domain/board.cpp index 4c5dee6d..d0df575f 100644 --- a/src/domain/board.cpp +++ b/src/domain/board.cpp @@ -7,8 +7,10 @@ #include #include -#include "utils/unreachable.hpp" +#include "infra/utils/to_string.hpp" +#include "utils/progress.hpp" #include "utils/signum.hpp" +#include "utils/unreachable.hpp" #include "utils/vector_utils.hpp" #include "board.hpp" @@ -198,6 +200,10 @@ pair, remove_const_t> Board::f //****************************************************************************** void Board::adjust_edges_to_materials(Plane const plane) { + auto [bar, found, i] = Progress::Bar::build( + get_current_state().edges[plane].size(), + "["s + to_string(plane) + "] Adjusting Edges to Materials "); + for(shared_ptr const& polygon : get_current_state().polygons[plane]) { for(shared_ptr const& edge : polygon->edges) { auto const& inner_material = polygon->material; @@ -222,20 +228,29 @@ void Board::adjust_edges_to_materials(Plane const plane) { if(immediate_ambient_outer_material && *immediate_ambient_outer_material > *inner_material) { + ++found; auto state = edge->get_current_state(); state.to_reverse = true; edge->set_next_state(state); } + bar.tick(found, ++i); } } + bar.complete(); } /// Detect all EDGE_IN_POLYGON. Will also detect some COLINEAR_EDGES. /// Overlapping edges should be EDGE_IN_POLYGON and not COLINEAR_EDGES. ///***************************************************************************** void Board::detect_edges_in_polygons(Plane const plane) { + auto [bar, found, k] = Progress::Bar::build( + get_current_state().polygons[plane].size() * get_current_state().polygons[plane].size(), + "["s + to_string(plane) + "] Detecting EDGES_IN_POLYGON conflicts "); + for(auto const& poly_a : get_current_state().polygons[plane]) { for(auto const& poly_b : get_current_state().polygons[plane]) { + ++k; + if(poly_b == poly_a) continue; @@ -281,6 +296,7 @@ void Board::detect_edges_in_polygons(Plane const plane) { if(r->axis == Segment::Axis::POINT) break; ranges.emplace_back(r.value(), relation::PolygonPoint::ON); + ++found; conflict_manager->add_edge_in_polygon(edge_a.get(), poly_b.get(), r.value(), edge_b.get()); } break; @@ -296,6 +312,7 @@ void Board::detect_edges_in_polygons(Plane const plane) { // && !ranges.size() && rel_p0 == relation::PolygonPoint::IN && rel_p1 == relation::PolygonPoint::IN) { + ++found; conflict_manager->add_edge_in_polygon(edge_a.get(), poly_b.get()); } else if(intersections.size()) { intersections.push_back(edge_a->p0()); @@ -334,9 +351,11 @@ void Board::detect_edges_in_polygons(Plane const plane) { if(range.mid.has_value() && poly_b->relation_to(range.mid.value()) == relation::PolygonPoint::IN) { /* || poly_b->relation_to(&range.mid.value()) == relation::PolygonPoint::ON)) -*/ conflict_manager->add_edge_in_polygon(edge_a.get(), poly_b.get(), range.range); +*/ ++found; + conflict_manager->add_edge_in_polygon(edge_a.get(), poly_b.get(), range.range); // range.rel_to_poly_b = poly_b->relation_to(&range.mid.value()); //TODO useless } else if(range.rel_to_poly_b == relation::PolygonPoint::IN) { + ++found; conflict_manager->add_edge_in_polygon(edge_a.get(), poly_b.get(), range.range); } } @@ -355,36 +374,51 @@ void Board::detect_edges_in_polygons(Plane const plane) { } } } + bar.tick(found, k); } + bar.complete(); } //****************************************************************************** void Board::detect_colinear_edges(Plane const plane) { auto const& s = get_current_state(); + auto [bar, found, k] = Progress::Bar::build( + ((s.edges[plane].size() * s.edges[plane].size()) - s.edges[plane].size()) / 2, // AB/BA deduplicated, AA dismissed. + "["s + to_string(plane) + "] Detecting COLINEAR_EDGES conflicts "); + for(size_t i = 0; i < s.edges[plane].size(); ++i) { if(s.edges[plane][i]->axis == Segment::Axis::DIAGONAL) // || !edges[i]->to_mesh) continue; - for(size_t j = i + 1; j < s.edges[plane].size(); ++j) { + for(size_t j = i + 1; j < s.edges[plane].size(); ++j, ++k) { if(s.edges[plane][j]->axis != s.edges[plane][i]->axis) continue; optional const axis = transpose(plane, s.edges[plane][i]->axis); if(axis) { - if(s.edges[plane][i]->axis == Segment::Axis::H && s.edges[plane][i]->p0().y == s.edges[plane][j]->p0().y) + if(s.edges[plane][i]->axis == Segment::Axis::H && s.edges[plane][i]->p0().y == s.edges[plane][j]->p0().y) { conflict_manager->add_colinear_edges(s.edges[plane][i], s.edges[plane][j]); - else if(s.edges[plane][i]->axis == Segment::Axis::V && s.edges[plane][i]->p0().x == s.edges[plane][j]->p0().x) + ++found; + } else if(s.edges[plane][i]->axis == Segment::Axis::V && s.edges[plane][i]->p0().x == s.edges[plane][j]->p0().x) { conflict_manager->add_colinear_edges(s.edges[plane][i], s.edges[plane][j]); + ++found; + } } } + bar.tick(found, k); } + bar.complete(); } //****************************************************************************** void Board::detect_individual_edges(Plane const plane) { + auto [bar, found, i] = Progress::Bar::build( + get_current_state().edges[plane].size(), + "["s + to_string(plane) + "] Adding fixed meshline policies "); + for(Edge* edge : get_current_state().edges[plane]) { optional const coord = domain::coord(edge->p0(), edge->axis); optional const axis = transpose(plane, edge->axis); @@ -395,6 +429,7 @@ void Board::detect_individual_edges(Plane const plane) { && (edge->get_current_state().conflicts.empty() || ranges::none_of(edge->get_current_state().conflicts, [](auto const& conflict) { return conflict ? conflict->kind == Conflict::Kind::COLINEAR_EDGES : false; })) && edge->get_current_state().to_mesh) { + ++found; auto [t, state_e] = edge->make_next_state(); state_e.meshline_policy = line_policy_manager->add_meshline_policy( { edge }, @@ -406,14 +441,23 @@ void Board::detect_individual_edges(Plane const plane) { t); edge->set_state(t, state_e); } + bar.tick(found, ++i); } + bar.complete(); } //****************************************************************************** void Board::add_fixed_meshline_policies(Axis axis) { + auto [bar, i, _] = Progress::Bar::build( + fixed_meshline_policy_creators[axis].size(), + "["s + to_string(axis) + "] Adding fixed meshline policies "); + auto* t = next_timepoint(); - for(auto const& create_meshline_policy : fixed_meshline_policy_creators[axis]) + for(auto const& create_meshline_policy : fixed_meshline_policy_creators[axis]) { create_meshline_policy(this, t); + bar.tick(++i); + } + bar.complete(); } //****************************************************************************** diff --git a/src/domain/conflict_manager.cpp b/src/domain/conflict_manager.cpp index a8adb8f6..d38a437d 100644 --- a/src/domain/conflict_manager.cpp +++ b/src/domain/conflict_manager.cpp @@ -7,6 +7,8 @@ #include "geometrics/edge.hpp" #include "geometrics/polygon.hpp" #include "mesh/meshline_policy.hpp" +#include "infra/utils/to_string.hpp" +#include "utils/progress.hpp" #include "conflict_manager.hpp" @@ -199,14 +201,28 @@ ConflictTooCloseMeshlinePolicies* ConflictManager::add_too_close_meshline_polici //****************************************************************************** void ConflictManager::auto_solve_all_edge_in_polygon(Plane const plane) { - for(auto const& conflict : get_current_state().all_edge_in_polygons[plane]) + auto [bar, i, _] = Progress::Bar::build( + get_current_state().all_edge_in_polygons[plane].size(), + "["s + to_string(plane) + "] Solving EDGES_IN_POLYGON conflicts "); + + for(auto const& conflict : get_current_state().all_edge_in_polygons[plane]) { conflict->auto_solve(*line_policy_manager); + bar.tick(i++); + } + bar.complete(); } //****************************************************************************** void ConflictManager::auto_solve_all_colinear_edges(Axis const axis) { - for(auto const& conflict : get_current_state().all_colinear_edges[axis]) + auto [bar, i, _] = Progress::Bar::build( + get_current_state().all_colinear_edges[axis].size(), + "["s + to_string(axis) + "] Solving COLINEAR_EDGES conflicts "); + + for(auto const& conflict : get_current_state().all_colinear_edges[axis]) { conflict->auto_solve(*line_policy_manager); + bar.tick(i++); + } + bar.complete(); } //****************************************************************************** diff --git a/src/domain/meshline_policy_manager.cpp b/src/domain/meshline_policy_manager.cpp index 5cfbe0aa..9d666b8a 100644 --- a/src/domain/meshline_policy_manager.cpp +++ b/src/domain/meshline_policy_manager.cpp @@ -8,6 +8,8 @@ #include #include "domain/geometrics/normal.hpp" +#include "infra/utils/to_string.hpp" +#include "utils/progress.hpp" #include "utils/unreachable.hpp" #include "utils/vector_utils.hpp" #include "conflict_manager.hpp" @@ -103,15 +105,26 @@ optional> detect_closest_meshline_policies( //****************************************************************************** void MeshlinePolicyManager::detect_and_solve_too_close_meshline_policies(Axis const axis) { + auto possible_max = get_current_state().line_policies[axis].size(); + auto [bar, found, i] = Progress::Bar::build( + possible_max, + "["s + to_string(axis) + "] Detecting & solving TCMLP conflicts "); + while(true) { + ++i; auto closest = detect_closest_meshline_policies(create_view(get_current_state().line_policies[axis]), global_params->get_current_state().proximity_limit); if(!closest) break; ConflictTooCloseMeshlinePolicies* conflict = conflict_manager->add_too_close_meshline_policies(closest->front(), closest->back()); - if(conflict) + if(conflict) { conflict->auto_solve(*this); + bar.tick(++found, i); + } } + + bar.tick(found, possible_max); + bar.complete(); } //****************************************************************************** @@ -125,6 +138,12 @@ void MeshlinePolicyManager::detect_intervals(Axis const axis) { return (!a->get_current_state().is_enabled); }); +// // TODO C++26 already implemented +// auto [bar, _, _] = Progress::Bar::build( + auto [bar, _, __] = Progress::Bar::build( + dimension.size(), + "["s + to_string(axis) + "] Detecting Intervals "); + ranges::sort(dimension, [](MeshlinePolicy const* a, MeshlinePolicy const* b) { return a->coord < b->coord; @@ -134,11 +153,12 @@ void MeshlinePolicyManager::detect_intervals(Axis const axis) { auto const& interval = state.intervals[axis].emplace_back(make_shared( dimension[i-1], dimension[i], axis, global_params, t)); get_caretaker().take_care_of(interval); - + bar.tick(i); // TODO add links MLP -> I ? } set_state(t, state); + bar.complete(); } //****************************************************************************** @@ -147,6 +167,10 @@ void MeshlinePolicyManager::mesh(Axis const axis) { auto dimension_view = create_view(state.intervals[axis]); + auto [bar, i, _] = Progress::Bar::build( + dimension_view.size() + state.line_policies[axis].size() + 1, + "["s + to_string(axis) + "] Meshing Intervals + Meshline Policies "); + ranges::sort(dimension_view, [](Interval const* a, Interval const* b) { return a->h < b->h; @@ -164,6 +188,7 @@ void MeshlinePolicyManager::mesh(Axis const axis) { interval_meshlines.emplace_back(interval->mesh()); new_size += interval_meshlines.back().size(); + bar.tick(++i); } for(auto const& line_policy : state.line_policies[axis]) { @@ -173,6 +198,7 @@ void MeshlinePolicyManager::mesh(Axis const axis) { interval_meshlines.emplace_back(std::move(v)); ++new_size; } + bar.tick(++i); } state.meshlines[axis].reserve(new_size); @@ -186,6 +212,7 @@ void MeshlinePolicyManager::mesh(Axis const axis) { }); set_state(t, state); + bar.complete(); } //****************************************************************************** diff --git a/src/infra/parsers/parser_from_csx.cpp b/src/infra/parsers/parser_from_csx.cpp index d850ef7b..709dc64b 100644 --- a/src/infra/parsers/parser_from_csx.cpp +++ b/src/infra/parsers/parser_from_csx.cpp @@ -18,6 +18,7 @@ #include "csxcad_layer/point_3d.hpp" #include "parser_from_csx.hpp" +#include "utils/progress.hpp" #include "utils/unreachable.hpp" #include "utils/vector_utils.hpp" @@ -306,6 +307,10 @@ void ParserFromCsx::parse() { } } + auto [bar, found, i] = Progress::Bar::build( + pimpl->primitives_ids.size(), + "Parsing primitives "); + pugi::xpath_node properties = doc.select_node("/openEMS/ContinuousStructure/Properties"); for(auto const& node : properties.node().children()) { auto material = pimpl->parse_property(node); @@ -313,10 +318,13 @@ void ParserFromCsx::parse() { pugi::xml_node primitives = node.child("Primitives"); for(auto const& node : primitives.children()) { if(material) - pimpl->parse_primitive(node, material); + if(pimpl->parse_primitive(node, material)) + ++found; + bar.tick(found, ++i); } } + bar.complete(); } //****************************************************************************** diff --git a/src/ui/cli/progress.cpp b/src/ui/cli/progress.cpp index 35a91c46..f9ac7081 100644 --- a/src/ui/cli/progress.cpp +++ b/src/ui/cli/progress.cpp @@ -12,10 +12,19 @@ using namespace std; namespace ui::cli { +//****************************************************************************** +size_t bar_width(size_t prefix_size, size_t postfix_size) { + // indicators::option::BarWidth does not take into account percentage nor time + // " 100% [000m:00s] " 17 chars + return 100 - prefix_size - postfix_size - 19; +} + //****************************************************************************** ProgressBar::ProgressBar(size_t max, string const& prefix) : bar(make_unique( -// indicators::option::BarWidth { 100 }, + // 2 padding for no suffix & no 'm' in elapsed time yet + // 2 padding for '100%' vs '0%' regarding whether max is 0 + indicators::option::BarWidth { bar_width(prefix.size(), 0) + (max ? 4 : 2) }, indicators::option::Start { "[" }, indicators::option::End { "]" }, indicators::option::ForegroundColor { indicators::Color::green }, @@ -24,8 +33,8 @@ ProgressBar::ProgressBar(size_t max, string const& prefix) indicators::option::PrefixText { prefix }, indicators::option::MaxProgress { max } )) +, prefix_size(prefix.size()) , max(to_string(max)) -, prefix(prefix) {} //****************************************************************************** @@ -34,7 +43,7 @@ ProgressBar::~ProgressBar() = default; //****************************************************************************** void ProgressBar::tick(size_t i) { string postfix(to_string(++i) + "/" + max); - resize_to_term(postfix); + bar->set_option(indicators::option::BarWidth { bar_width(prefix_size, postfix.size()) }); bar->set_option(indicators::option::PostfixText { postfix }); bar->set_progress(i); } @@ -42,18 +51,11 @@ void ProgressBar::tick(size_t i) { //****************************************************************************** void ProgressBar::tick(size_t i, size_t j) { string postfix(to_string(i) + "/" + to_string(j) + "/" + max); - resize_to_term(postfix); + bar->set_option(indicators::option::BarWidth { bar_width(prefix_size, postfix.size()) }); bar->set_option(indicators::option::PostfixText { postfix }); bar->set_progress(j); } -//****************************************************************************** -void ProgressBar::resize_to_term(string const& postfix) { - // TODO This does not take into account percentage nor time - // " 100% [000m:00s] " 17 chars - bar->set_option(indicators::option::BarWidth { 100 - prefix.size() - postfix.size() - 19 }); -} - //****************************************************************************** void ProgressBar::complete() { bar->mark_as_completed(); diff --git a/src/ui/cli/progress.hpp b/src/ui/cli/progress.hpp index 2af5ae98..97678ef7 100644 --- a/src/ui/cli/progress.hpp +++ b/src/ui/cli/progress.hpp @@ -29,11 +29,9 @@ class ProgressBar final : public Progress::IBar { void complete() override; private: - void resize_to_term(std::string const& postfix); - std::unique_ptr bar; + std::size_t prefix_size; std::string max; - std::string prefix; }; } // namespace ui::cli diff --git a/src/utils/progress.cpp b/src/utils/progress.cpp index 88a97314..82c34768 100644 --- a/src/utils/progress.cpp +++ b/src/utils/progress.cpp @@ -4,14 +4,33 @@ /// @author Thomas Lepoix ///***************************************************************************** +#include + #include "progress.hpp" using namespace std; +/// To be used like: +/// auto [bar, i, j] = Progress::Bar::build(max, message); +///***************************************************************************** +tuple Progress::Bar::build(size_t max, string const& message) { + return { Progress::Bar(max, message), 0, 0 }; +} + //****************************************************************************** -Progress::Bar::Bar(size_t max, string const& prefix) { +Progress::Bar::Bar(size_t max, string const& message) { for(auto& builder : Progress::singleton().impl_builders) - impls.push_back(builder(max, prefix)); + impls.push_back(builder(max, message)); +} + +//****************************************************************************** +Progress::Bar::Bar(Bar&& other) +: impls(std::move(other.impls)) +{} + +//****************************************************************************** +void Progress::Bar::operator=(Bar&& other) { + impls = std::move(other.impls); } //****************************************************************************** diff --git a/src/utils/progress.hpp b/src/utils/progress.hpp index 94427dcd..b6787a96 100644 --- a/src/utils/progress.hpp +++ b/src/utils/progress.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include //****************************************************************************** @@ -31,7 +32,11 @@ class Progress { std::vector> impls; public: - Bar(std::size_t max, std::string const& prefix); + static std::tuple build(std::size_t max, std::string const& message); + + Bar(std::size_t max, std::string const& message); + Bar(Bar&& other); + void operator=(Bar&& other); ~Bar() override; void tick(std::size_t i) override; From 94c90afb250df6caca362fa0c12f40cb259bd3ee Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Mon, 24 Nov 2025 14:07:57 +0100 Subject: [PATCH 05/15] print progress bars on stderr --- src/ui/cli/progress.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/cli/progress.cpp b/src/ui/cli/progress.cpp index f9ac7081..d369c266 100644 --- a/src/ui/cli/progress.cpp +++ b/src/ui/cli/progress.cpp @@ -4,6 +4,8 @@ /// @author Thomas Lepoix ///***************************************************************************** +#include + #include #include "progress.hpp" @@ -31,7 +33,8 @@ ProgressBar::ProgressBar(size_t max, string const& prefix) indicators::option::ShowPercentage { true }, indicators::option::ShowElapsedTime { true }, indicators::option::PrefixText { prefix }, - indicators::option::MaxProgress { max } + indicators::option::MaxProgress { max }, + indicators::option::Stream { cerr } )) , prefix_size(prefix.size()) , max(to_string(max)) From 9527bb4c0c353f72421c165858199eae9803c594 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Mon, 24 Nov 2025 18:01:57 +0100 Subject: [PATCH 06/15] Cli : fix enum handling --- src/ui/cli/cli.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index 980c98e3..a49ab21c 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -134,7 +134,8 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { { "plantuml", app::OpenEMSH::Params::OutputFormat::PLANTUML }, { "prettyprint", app::OpenEMSH::Params::OutputFormat::PRETTYPRINT } }; - app.add_option("--output-format", params.output_format, "Output format.")->transform(CLI::CheckedTransformer(map, CLI::ignore_case)); + // https://github.com/CLIUtils/CLI11/issues/554#issuecomment-932782337 + app.add_option("--output-format", params.output_format, "Output format.")->transform(CLI::CheckedTransformer(map, CLI::ignore_case).description(CLI::detail::generate_map(CLI::detail::smart_deref(map), true))); app.add_option("--ground", params.grounds, "Declare properties to be ground planes ('Name' XML field).")->group("Input options"); app.add_flag("--no-yz", [¶ms](size_t) { params.with_yz = false; }, "Don't process YZ plane.")->group("Input options"); From abc63a3bdc991ce849e4ecf520424e5a5443d828 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Mon, 24 Nov 2025 19:33:40 +0100 Subject: [PATCH 07/15] CMake : add indictors CPM dependency --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index db1647b6..120b138f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,15 @@ if( NOT CPM_DISABLE ) ) set( CLI11_DIR "${CLI11_BINARY_DIR}" ) + + CPMAddPackage( + NAME indicators + GITHUB_REPOSITORY p-ranav/indicators + VERSION 2.3 + PATCHES "https://github.com/p-ranav/indicators/pull/130.patch" + ) + + set( indicators_DIR "${indicators_BINARY_DIR}" ) endif() find_package( CMakeUtils QUIET ) From 63adfd481e7189089c9b683afb1d4180f24438e1 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Tue, 25 Nov 2025 17:08:59 +0100 Subject: [PATCH 08/15] refactor : fix some badsmells --- src/infra/parsers/parser_from_csx.cpp | 7 +++---- src/main.cpp | 8 +++++--- src/ui/cli/cli.cpp | 3 ++- src/ui/cli/progress.cpp | 9 +++++---- src/ui/qt/main_window.cpp | 9 ++++++--- src/ui/qt/progress.cpp | 6 +++--- src/ui/qt/progress.hpp | 4 ++-- src/utils/progress.cpp | 22 +++++----------------- src/utils/progress.hpp | 3 --- 9 files changed, 31 insertions(+), 40 deletions(-) diff --git a/src/infra/parsers/parser_from_csx.cpp b/src/infra/parsers/parser_from_csx.cpp index 709dc64b..62cb2c7d 100644 --- a/src/infra/parsers/parser_from_csx.cpp +++ b/src/infra/parsers/parser_from_csx.cpp @@ -303,7 +303,7 @@ void ParserFromCsx::parse() { for(auto const& primitive : primitives) for(auto const& node : primitive.node().children()) { pimpl->primitives_ids.emplace(node, id++); - cerr << node.name() << endl; +// cerr << node.name() << endl; } } @@ -317,9 +317,8 @@ void ParserFromCsx::parse() { pugi::xml_node primitives = node.child("Primitives"); for(auto const& node : primitives.children()) { - if(material) - if(pimpl->parse_primitive(node, material)) - ++found; + if(material && pimpl->parse_primitive(node, material)) + ++found; bar.tick(found, ++i); } diff --git a/src/main.cpp b/src/main.cpp index b0e7bff4..e841145d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "app/openemsh.hpp" #include "ui/cli/cli.hpp" @@ -21,9 +22,10 @@ int main(int argc, char* argv[]) { Progress::singleton().register_impl_builder( [&oemsh](std::size_t max, std::string const& message) { return std::make_unique(max, - std::to_string(app::index(oemsh.get_current_step())) - + "/" + std::to_string(app::index_max()) - + " " + message); + std::format("{}/{} {}", + app::index(oemsh.get_current_step()), + app::index_max(), + message)); }); if(!oemsh.get_params().gui) { diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index a49ab21c..c9585247 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -10,6 +10,7 @@ //#include #include +#include #include #include @@ -129,7 +130,7 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { app.add_option("-o,--output", params.output, "Output CSX file. If different from input, will copy and extend it.")->check(CLI::Validator((!CLI::ExistingFile)|FutureConditional(params.force,"Cannot overwrite a file without --force"), "FILE", "KO")); app.add_flag("-f,--force", params.force, "Allow overwriting a file.")->trigger_on_parse(); - static std::map const map { + static std::map> const map { { "csx", app::OpenEMSH::Params::OutputFormat::CSX }, { "plantuml", app::OpenEMSH::Params::OutputFormat::PLANTUML }, { "prettyprint", app::OpenEMSH::Params::OutputFormat::PRETTYPRINT } diff --git a/src/ui/cli/progress.cpp b/src/ui/cli/progress.cpp index d369c266..4ae2d26f 100644 --- a/src/ui/cli/progress.cpp +++ b/src/ui/cli/progress.cpp @@ -4,10 +4,11 @@ /// @author Thomas Lepoix ///***************************************************************************** -#include - #include +#include +#include + #include "progress.hpp" using namespace std; @@ -45,7 +46,7 @@ ProgressBar::~ProgressBar() = default; //****************************************************************************** void ProgressBar::tick(size_t i) { - string postfix(to_string(++i) + "/" + max); + auto postfix = format("{}/{}", ++i, max); bar->set_option(indicators::option::BarWidth { bar_width(prefix_size, postfix.size()) }); bar->set_option(indicators::option::PostfixText { postfix }); bar->set_progress(i); @@ -53,7 +54,7 @@ void ProgressBar::tick(size_t i) { //****************************************************************************** void ProgressBar::tick(size_t i, size_t j) { - string postfix(to_string(i) + "/" + to_string(j) + "/" + max); + auto postfix = format("{}/{}/{}", i, j, max); bar->set_option(indicators::option::BarWidth { bar_width(prefix_size, postfix.size()) }); bar->set_option(indicators::option::PostfixText { postfix }); bar->set_progress(j); diff --git a/src/ui/qt/main_window.cpp b/src/ui/qt/main_window.cpp index 7edcbd06..6f0bea6a 100644 --- a/src/ui/qt/main_window.cpp +++ b/src/ui/qt/main_window.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include "domain/geometrics/space.hpp" #include "edit/edit_dialog.hpp" #include "edit/edit_model.hpp" @@ -51,9 +53,10 @@ MainWindow::MainWindow(app::OpenEMSH& oemsh, QWidget* parent) Progress::singleton().register_impl_builder( [this](std::size_t max, std::string const& message) { return std::make_unique(ui->statusBar, max, - QString::number(app::index(this->oemsh.get_current_step())) - + "/" + QString::number(app::index_max()) - + " " + QString::fromStdString(message)); + QString::fromStdString(std::format("{}/{} {}", + app::index(this->oemsh.get_current_step()), + app::index_max(), + message))); }); for(auto const& style : Style::available_styles) { diff --git a/src/ui/qt/progress.cpp b/src/ui/qt/progress.cpp index 28dcbd18..185aba0d 100644 --- a/src/ui/qt/progress.cpp +++ b/src/ui/qt/progress.cpp @@ -20,7 +20,7 @@ ProgressBar::ProgressBar(QStatusBar* status_bar, size_t max, QString const& mess , bar(new QProgressBar()) , label(new QLabel(message)) { - bar->setRange(0, max); + bar->setRange(0, (int) max); status_bar->addWidget(bar); status_bar->addWidget(label); } @@ -35,12 +35,12 @@ ProgressBar::~ProgressBar() { //****************************************************************************** void ProgressBar::tick(size_t i) { - bar->setValue(++i); + bar->setValue((int) ++i); } //****************************************************************************** void ProgressBar::tick(size_t /*i*/, size_t j) { - bar->setValue(++j); + bar->setValue((int) ++j); } //****************************************************************************** diff --git a/src/ui/qt/progress.hpp b/src/ui/qt/progress.hpp index 912423bb..567e6ae2 100644 --- a/src/ui/qt/progress.hpp +++ b/src/ui/qt/progress.hpp @@ -6,10 +6,10 @@ #pragma once -#include - #include +#include + #include "utils/progress.hpp" class QLabel; diff --git a/src/utils/progress.cpp b/src/utils/progress.cpp index 82c34768..c3a5b169 100644 --- a/src/utils/progress.cpp +++ b/src/utils/progress.cpp @@ -19,38 +19,26 @@ tuple Progress::Bar::build(size_t max, string con //****************************************************************************** Progress::Bar::Bar(size_t max, string const& message) { - for(auto& builder : Progress::singleton().impl_builders) + for(auto const& builder : Progress::singleton().impl_builders) impls.push_back(builder(max, message)); + impls.shrink_to_fit(); } -//****************************************************************************** -Progress::Bar::Bar(Bar&& other) -: impls(std::move(other.impls)) -{} - -//****************************************************************************** -void Progress::Bar::operator=(Bar&& other) { - impls = std::move(other.impls); -} - -//****************************************************************************** -Progress::Bar::~Bar() = default; - //****************************************************************************** void Progress::Bar::tick(size_t i) { - for(auto& impl : impls) + for(auto const& impl : impls) impl->tick(i); } //****************************************************************************** void Progress::Bar::tick(size_t i, size_t j) { - for(auto& impl : impls) + for(auto const& impl : impls) impl->tick(i, j); } //****************************************************************************** void Progress::Bar::complete() { - for(auto& impl : impls) + for(auto const& impl : impls) impl->complete(); } diff --git a/src/utils/progress.hpp b/src/utils/progress.hpp index b6787a96..ee8051dd 100644 --- a/src/utils/progress.hpp +++ b/src/utils/progress.hpp @@ -35,9 +35,6 @@ class Progress { static std::tuple build(std::size_t max, std::string const& message); Bar(std::size_t max, std::string const& message); - Bar(Bar&& other); - void operator=(Bar&& other); - ~Bar() override; void tick(std::size_t i) override; void tick(std::size_t i, std::size_t j) override; From 9c5b6c75eb9024121209bb598f1dae8ae3cc482b Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Tue, 25 Nov 2025 18:23:44 +0100 Subject: [PATCH 09/15] CMake : fix CPM indicators dependency --- CMakeLists.txt | 2 +- flake.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 120b138f..38d945ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,7 @@ if( NOT CPM_DISABLE ) CPMAddPackage( NAME indicators GITHUB_REPOSITORY p-ranav/indicators - VERSION 2.3 + GIT_TAG 3872f37 PATCHES "https://github.com/p-ranav/indicators/pull/130.patch" ) diff --git a/flake.nix b/flake.nix index a259d904..35ab78da 100644 --- a/flake.nix +++ b/flake.nix @@ -177,7 +177,7 @@ stdenv.mkDerivation rec { pname = "indicators"; # version = "2.3"; - version = "master"; + version = "3872f37"; src = fetchFromGitHub { owner = "p-ranav"; From b24dccd1be47c4e76af5f81390f0c7356b9b7a3d Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Wed, 26 Nov 2025 00:08:46 +0100 Subject: [PATCH 10/15] Cli : allow input as positional arg --- doc/openemsh.1.in | 4 +++- pack/openemsh.desktop | 2 +- src/ui/cli/cli.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/openemsh.1.in b/doc/openemsh.1.in index a0fd55ba..500ac6ff 100644 --- a/doc/openemsh.1.in +++ b/doc/openemsh.1.in @@ -6,6 +6,8 @@ OpenEMSH \- OpenEMS mesher .SH SYNOPSIS \fBopenemsh\fR [\fIOPTION\fR] ... .br +\fBopenemsh\fR [\fICSX_FILE\fR] [\fIOPTION\fR] ... +.br \fBopenemsh\fR [\fB-i\fR \fICSX_FILE\fR] [\fIOPTION\fR] ... .br \fBopenemsh\fR [\fB-i\fR \fICSX_FILE\fR] [\fB-G\fR] [\fIOPTION\fR] ... @@ -31,7 +33,7 @@ Verbose mode. GUI mode (no arguments equals to \fB-G\fR) .TP \fB-i\fR \fIFILENAME\fR -Input CSX XML file. +Input CSX XML file. (is also a positional argument) .TP \fB-o\fR \fIFILENAME\fR Output CSX XML file. If different from input, will copy and extend it. diff --git a/pack/openemsh.desktop b/pack/openemsh.desktop index 917585b0..17c0a28d 100644 --- a/pack/openemsh.desktop +++ b/pack/openemsh.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Name=OpenEMSH TryExec=openemsh -Exec=bash -c "F="%f" && test -n "$F" && openemsh -G -i $F || openemsh" +Exec=openemsh -G %f Icon=openemsh Type=Application Comment=OpenEMS mesher draft diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index c9585247..03936391 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -124,7 +124,7 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { app.set_version_flag("--version", OEMSH_VERSION, "Display version and exit."); app.add_flag("-v,--verbose", params.verbose, "Verbose mode.")->capture_default_str(); auto* g = app.add_flag("-G", params.gui, "GUI mode."); - auto* i = app.add_option("-i,--input", params.input, "Input CSX file.")->check(CLI::ExistingFile)->required(); + auto* i = app.add_option("input,-i,--input", params.input, "Input CSX file.")->check(CLI::ExistingFile)->required(); g->trigger_on_parse()->check(JustDo([i]() { i->required(false); })); // app.add_option("-o,--output", params.output, "Output CSX file. If different from input, will copy and extend it.")->check((!CLI::ExistingFile)|FutureConditional(params.force,"Cannot overwrite a file without --force")); app.add_option("-o,--output", params.output, "Output CSX file. If different from input, will copy and extend it.")->check(CLI::Validator((!CLI::ExistingFile)|FutureConditional(params.force,"Cannot overwrite a file without --force"), "FILE", "KO")); From 0261dfe3de66b3d3e3ca146b4f7cd9cfb7d07d9d Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Thu, 27 Nov 2025 05:01:23 +0100 Subject: [PATCH 11/15] fix : GUI don't try to parse if no file provided --- src/ui/qt/main_window.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ui/qt/main_window.cpp b/src/ui/qt/main_window.cpp index 6f0bea6a..b5223575 100644 --- a/src/ui/qt/main_window.cpp +++ b/src/ui/qt/main_window.cpp @@ -79,6 +79,9 @@ MainWindow::~MainWindow() = default; //****************************************************************************** void MainWindow::parse_and_display() { + if(csx_file.isEmpty()) + return; + QGuiApplication::setOverrideCursor(Qt::WaitCursor); update_title(); oemsh.parse(); From 7ccc29daba7082916b2887f1d884b7b249342f58 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Thu, 27 Nov 2025 19:16:26 +0100 Subject: [PATCH 12/15] refactor : remove some old useless stuff --- doc/openemsh.1.in | 5 +---- src/app/openemsh.hpp | 10 ---------- src/domain/global.hpp | 2 -- src/infra/parsers/parser_from_csx.hpp | 2 -- src/ui/cli/cli.cpp | 27 --------------------------- src/ui/qt/edit/edit_model_global.cpp | 4 ---- 6 files changed, 1 insertion(+), 49 deletions(-) diff --git a/doc/openemsh.1.in b/doc/openemsh.1.in index 500ac6ff..f7251151 100644 --- a/doc/openemsh.1.in +++ b/doc/openemsh.1.in @@ -56,9 +56,6 @@ Output format. .RE .PD .SS Input options -.TP - \fB--ground\fR \fITEXT\fR ... -Declare properties to be ground planes ('Name' XML field). .TP \fB--no-yz\fR Don't process YZ plane. @@ -104,7 +101,7 @@ Currently, diagonals and circular shapes are not supported. .SH SEE ALSO @OEMSH_OEMS_MESHING@ .PP -.BR AppCSXCAD (7), +.BR AppCSXCAD (1), .SH REPORTING BUGS @OEMSH_BUGREPORT@ diff --git a/src/app/openemsh.hpp b/src/app/openemsh.hpp index 496bdcbf..1bd4dea2 100644 --- a/src/app/openemsh.hpp +++ b/src/app/openemsh.hpp @@ -40,16 +40,6 @@ class OpenEMSH { PRETTYPRINT } output_format = OutputFormat::CSX; - bool with_step_adjust_edges_to_material = true; - bool with_step_detect_edges_in_polygons = true; - bool with_step_detect_colinear_edges = true; - bool with_step_auto_solve_all_edge_in_polygon = true; - bool with_step_auto_solve_all_colinear_edges = true; - bool with_step_detect_individual_edges = true; - bool with_step_detect_and_solve_too_close_meshline_policies = true; - bool with_step_detect_intervals = true; - bool with_step_mesh = true; - std::function override_from_cli; }; diff --git a/src/domain/global.hpp b/src/domain/global.hpp index d0bb12d8..cd336129 100644 --- a/src/domain/global.hpp +++ b/src/domain/global.hpp @@ -14,8 +14,6 @@ namespace domain { //****************************************************************************** struct Params { - double metal_res; - double substrate_res; double proximity_limit = 1; // TODO must be linked to initial d double lambda = 2; std::size_t lmin = 10; diff --git a/src/infra/parsers/parser_from_csx.hpp b/src/infra/parsers/parser_from_csx.hpp index 603ba3a1..af0f72a7 100644 --- a/src/infra/parsers/parser_from_csx.hpp +++ b/src/infra/parsers/parser_from_csx.hpp @@ -27,7 +27,6 @@ class ParserFromCsx { bool with_yz = true; bool with_zx = true; bool with_xy = true; - std::vector grounds; }; ~ParserFromCsx(); @@ -35,7 +34,6 @@ class ParserFromCsx { [[nodiscard]] static std::shared_ptr run(std::filesystem::path const& input); [[nodiscard]] static std::shared_ptr run(std::filesystem::path const& input, Params params); [[nodiscard]] static std::shared_ptr run(std::filesystem::path const& input, Params params, std::function const& override_domain_params); - [[nodiscard]] static std::shared_ptr run(std::filesystem::path const& input, std::vector ground_names, Params params); private: ParserFromCsx(std::filesystem::path const& input); diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index 03936391..e7f72985 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -138,37 +138,10 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { // https://github.com/CLIUtils/CLI11/issues/554#issuecomment-932782337 app.add_option("--output-format", params.output_format, "Output format.")->transform(CLI::CheckedTransformer(map, CLI::ignore_case).description(CLI::detail::generate_map(CLI::detail::smart_deref(map), true))); - app.add_option("--ground", params.grounds, "Declare properties to be ground planes ('Name' XML field).")->group("Input options"); app.add_flag("--no-yz", [¶ms](size_t) { params.with_yz = false; }, "Don't process YZ plane.")->group("Input options"); app.add_flag("--no-zx", [¶ms](size_t) { params.with_zx = false; }, "Don't process ZX plane.")->group("Input options"); app.add_flag("--no-xy", [¶ms](size_t) { params.with_xy = false; }, "Don't process XY plane.")->group("Input options"); - // TODO processing options -// app.add_flag("--step-detect-edges-in-polygons", params.with_step_detect_edges_in_polygons, "Do EdgeInPolygon conflicts detection step.")->group("Processing options"); -// app.add_flag("--step-detect-colinear-edges", params.with_step_detect_colinear_edges, "Do ColinearEdges conflicts detection step.")->group("Processing options"); -// app.add_flag("--step-detect-non-conflicting-edges", params.with_step_detect_non_conflicting_edges, "Do non-conflicting edges detection step.")->group("Processing options"); -// app.add_flag("--step-auto-solve-all-edge-in-polygon", params.with_step_auto_solve_all_edge_in_polygon, "Do EdgeInPolygon conflicts autosolving step.")->group("Processing options"); -// app.add_flag("--step-auto-solve-all-colinear-edges", params.with_step_auto_solve_all_colinear_edges, "Do ColinearEdges conflicts autosolving step.")->group("Processing options"); -// app.add_flag("--step-detect-and-solve-too-close-meshline-policies", params.with_step_detect_and_solve_too_close_meshline_policies, "Do TooCloseMeshlinePolicies conflicts detection and autosolving step.")->group("Processing options"); -// app.add_flag("--step-detect-intervals", params.with_step_detect_intervals, "Do intervals detection step.")->group("Processing options"); -// app.add_flag("--step-mesh", params.with_step_mesh, "Do intervals meshing step.")->group("Processing options"); - - // Mesher options -// app.add_option_function("--metal_res", -// make_overrider<&domain::Params::metal_res>(domain_overrides), -// "Desired mesh resolution for metal regions." -// )->group("Mesher options"); - -// app.add_option_function("--air_res", -// make_overrider<&domain::Params::air_res>(domain_overrides), -// "Desired mesh resolution for air regions." -// )->group("Mesher options"); - -// app.add_option_function("--substrate_res", -// make_overrider<&domain::Params::substrate_res>(domain_overrides), -// "Desired mesh resolution for substrate / ground plane regions." -// )->group("Mesher options"); - app.add_option_function("--proximity-limit", make_overrider<&domain::Params::proximity_limit>(domain_overrides), "Distance under which two adjacent lines trigger a conflict." diff --git a/src/ui/qt/edit/edit_model_global.cpp b/src/ui/qt/edit/edit_model_global.cpp index 19ab5198..3425b905 100644 --- a/src/ui/qt/edit/edit_model_global.cpp +++ b/src/ui/qt/edit/edit_model_global.cpp @@ -26,8 +26,6 @@ EditModelGlobal::EditModelGlobal(domain::GlobalParams* global, QObject* parent) auto const& params = global->get_current_state(); setRowCount(4); -// make_row(0, "metal_res", QString::number(params.metal_res), ""); -// make_row(1, "substrate_res", QString::number(params.substrate_res), ""); make_row(0, "Proximity limit", QString::number(params.proximity_limit), "Distance below which two MeshlinePolicies will be merged."); make_row(1, "Smoothness", QString::number(params.lambda), @@ -43,8 +41,6 @@ void EditModelGlobal::commit() { domain::Params params; std::array does_succeed = { -// try_to_double(item(0, V)->text(), params.metal_res), -// try_to_double(item(1, V)->text(), params.substrate_res), try_to_double(item(0, V)->text(), params.proximity_limit), try_to_double(item(1, V)->text(), params.lambda), try_to_ulong(item(2, V)->text(), params.lmin), From 508281e7488d6a0d436cbdedc34292fdf7f4944e Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Fri, 28 Nov 2025 00:30:30 +0100 Subject: [PATCH 13/15] refactor : lambda -> smoothness --- src/domain/global.hpp | 2 +- src/domain/mesh/interval.cpp | 106 ++++++------ src/domain/mesh/interval.hpp | 12 +- src/domain/meshline_policy_manager.cpp | 2 +- .../serializers/serializer_to_plantuml.cpp | 4 +- src/ui/cli/cli.cpp | 4 +- src/ui/qt/edit/edit_model_global.cpp | 4 +- src/ui/qt/edit/edit_model_interval.cpp | 8 +- .../processing_view/processing_interval.cpp | 28 ++-- test/unit/domain/mesh/test_interval.cpp | 154 +++++++++--------- 10 files changed, 161 insertions(+), 163 deletions(-) diff --git a/src/domain/global.hpp b/src/domain/global.hpp index cd336129..e9ca3690 100644 --- a/src/domain/global.hpp +++ b/src/domain/global.hpp @@ -15,7 +15,7 @@ namespace domain { //****************************************************************************** struct Params { double proximity_limit = 1; // TODO must be linked to initial d - double lambda = 2; + double smoothness = 2; std::size_t lmin = 10; double dmax = 2.5; }; diff --git a/src/domain/mesh/interval.cpp b/src/domain/mesh/interval.cpp index d5b0c52a..70db3abf 100644 --- a/src/domain/mesh/interval.cpp +++ b/src/domain/mesh/interval.cpp @@ -18,10 +18,10 @@ namespace domain { using namespace std; //****************************************************************************** -Interval::Side::Side(MeshlinePolicy* meshline_policy, size_t lmin, double lambda, Coord h, function d_init) +Interval::Side::Side(MeshlinePolicy* meshline_policy, size_t lmin, double smoothness, Coord h, function d_init) : meshline_policy(meshline_policy) , lmin(lmin) -, lambda(lambda) +, smoothness(smoothness) , d_init_(std::move(d_init)) { if(meshline_policy->get_current_state().d > h) { @@ -45,7 +45,7 @@ Coord calc_h(Coord const& a, Coord const& b) noexcept { Interval::Interval(MeshlinePolicy* before, MeshlinePolicy* after, Axis axis, GlobalParams* global_params, Timepoint* t) : Originator(t, { .dmax = global_params->get_current_state().dmax, - .before = Side(before, global_params->get_current_state().lmin, global_params->get_current_state().lambda, calc_h(before->coord, after->coord), [before](double d) noexcept { + .before = Side(before, global_params->get_current_state().lmin, global_params->get_current_state().smoothness, calc_h(before->coord, after->coord), [before](double d) noexcept { switch(before->get_current_state().policy) { case MeshlinePolicy::Policy::ONELINE: return 0.0; case MeshlinePolicy::Policy::HALFS: return d / 2.0; @@ -62,7 +62,7 @@ Interval::Interval(MeshlinePolicy* before, MeshlinePolicy* after, Axis axis, Glo default: ::unreachable(); } }), - .after = Side(after, global_params->get_current_state().lmin, global_params->get_current_state().lambda, calc_h(before->coord, after->coord), [after](double d) noexcept { + .after = Side(after, global_params->get_current_state().lmin, global_params->get_current_state().smoothness, calc_h(before->coord, after->coord), [after](double d) noexcept { switch(after->get_current_state().policy) { case MeshlinePolicy::Policy::ONELINE: return 0.0; case MeshlinePolicy::Policy::HALFS: return d / 2.0; @@ -101,22 +101,22 @@ Coord Interval::s(Interval::Side const& side, double d) const { /// lines (d) is dmax. /// /// Computation is done regarding d as initial distance between adjacent lines, -/// lambda as smoothness factor and dmax as limitating maximal distance between +/// smoothness as smoothness factor and dmax as limitating maximal distance between /// adjacent lines. /// /// If z exceeds 2 * h, we round it to 2 * h. ///***************************************************************************** /* -vector find_lz(double d, double lambda, double dmax, Coord h) { - if(lambda == 1) +vector find_lz(double d, double smoothness, double dmax, Coord h) { + if(smoothness == 1) return { numeric_limits::infinity() }; -// double current_d = d; // TODO d * lambda - double current_d = d * lambda; // TODO d * lambda +// double current_d = d; + double current_d = d * smoothness; double current_z = 0; vector lz; while(current_d < dmax && current_z < 10 * h) { - current_d *= lambda; + current_d *= smoothness; if(current_d < dmax) { current_z += current_d; lz.push_back(current_z); @@ -131,16 +131,16 @@ vector find_lz(double d, double lambda, double dmax, Coord h) { /// from side's coord) to the middle of the interval (at h from side's coord). /// /// Computation is done regarding d as initial distance between adjacent lines, -/// lambda as smoothness factor and dmax as limitating maximal distance between +/// smoothness as smoothness factor and dmax as limitating maximal distance between /// adjacent lines. ///***************************************************************************** -vector find_ls(double d, double lambda, double dmax, Coord s) { +vector find_ls(double d, double smoothness, double dmax, Coord s) { double current_d = min(d, dmax); double current_s = 0; vector ls; while(current_s < s) { if(current_d < dmax) { - current_d *= lambda; + current_d *= smoothness; if(current_d > dmax) current_d = dmax; } @@ -156,30 +156,28 @@ vector find_ls(double d, double lambda, double dmax, Coord s) { /// Verifiy that ls satisfies the following criteras : /// - At least lmin lines in ls. /// - No space between adjacent lines should exceed dmax. -/// - No space between adjacent lines should be more than lambda times bigger +/// - No space between adjacent lines should be more than smoothness times bigger /// than the previous one. - -/// - The last space between adjacent lines should not be less than dmax/lambda. - +/// - The last space between adjacent lines should not be less than dmax/smoothness. ///***************************************************************************** -bool is_ls_valid_for_dmax_lmin_lambda(vector const& ls, double d, double lambda, double dmax, size_t lmin) { +bool is_ls_valid_for_dmax_lmin_smoothness(vector const& ls, double d, double smoothness, double dmax, size_t lmin) { if(d > dmax || ls.size() < lmin || ls.empty()) return false; - if(ls[0] > lambda * d + equality_tolerance + if(ls[0] > smoothness * d + equality_tolerance || ls[0] > dmax + equality_tolerance) return false; if(ls.size() >= 2) { - if(ls[1] - ls[0] > lambda * ls[0] + equality_tolerance + if(ls[1] - ls[0] > smoothness * ls[0] + equality_tolerance || ls[1] - ls[0] > dmax + equality_tolerance) return false; } for(size_t i = 2; i < ls.size(); ++i) { - if(ls[i] - ls[i-1] > lambda * (ls[i-1] - ls[i-2]) + equality_tolerance + if(ls[i] - ls[i-1] > smoothness * (ls[i-1] - ls[i-2]) + equality_tolerance || ls[i] - ls[i-1] > dmax + equality_tolerance) return false; } @@ -195,12 +193,12 @@ double find_dmax(Interval::Side const& side, double dmax) { else return (double) (side.lz[side.ls.size()-1] - side.lz[side.ls.size()-2]); if(side.ls.size()) - return last_d(side.ls) * side.lambda; + return last_d(side.ls) * side.smoothness; */ if(side.ls.size() > 1) - return min(dmax, side.lambda * (double) (side.ls.back() - side.ls[side.ls.size()-2])); + return min(dmax, side.smoothness * (double) (side.ls.back() - side.ls[side.ls.size()-2])); else if(side.ls.size() == 1) - return min(dmax, side.lambda * (double) side.ls[0]); + return min(dmax, side.smoothness * (double) side.ls[0]); else return dmax; } @@ -220,7 +218,7 @@ void Interval::update_ls(IntervalState& state) { //****************************************************************************** void Interval::update_ls(Interval::Side& side) { - side.ls = find_ls(side.meshline_policy->get_current_state().d, side.lambda, get_current_state().dmax, s(side)); + side.ls = find_ls(side.meshline_policy->get_current_state().d, side.smoothness, get_current_state().dmax, s(side)); } //****************************************************************************** @@ -232,9 +230,9 @@ tuple Interval::adjust_d_for_dmax_lmin(Interval::Side const& side, size_t counter = 0; bool is_limit_reached = false; - while(!is_ls_valid_for_dmax_lmin_lambda(current_ls, current_d, side.lambda, get_current_state().dmax, side.lmin)) { + while(!is_ls_valid_for_dmax_lmin_smoothness(current_ls, current_d, side.smoothness, get_current_state().dmax, side.lmin)) { current_d -= current_d / step; - current_ls = find_ls(current_d, side.lambda, get_current_state().dmax, s(side, current_d)); + current_ls = find_ls(current_d, side.smoothness, get_current_state().dmax, s(side, current_d)); if(counter++ >= iter_limit) { is_limit_reached = true; @@ -246,10 +244,10 @@ tuple Interval::adjust_d_for_dmax_lmin(Interval::Side const& side, /* size_t i; - for(i = 0; i < iter_limit && !check_ls_dmax_lmin_lambda(current_ls, current_d, side.lambda, dmax, side.lmin); ++i) { + for(i = 0; i < iter_limit && !check_ls_dmax_lmin_smoothness(current_ls, current_d, side.smoothness, dmax, side.lmin); ++i) { current_d -= current_d / step; - current_ls = find_ls(current_d, side.lambda, dmax, s(side, current_d)); + current_ls = find_ls(current_d, side.smoothness, dmax, s(side, current_d)); } return { current_d, i >= iter_limit }; @@ -267,7 +265,7 @@ tuple Interval::adjust_d_for_dmax_lmin(Interval::Side const& side, // bool is_limit_reached = false; // for(;;) { // double next_d = current_d - current_d / step; -// auto next_ls = find_ls(next_d, side.lambda, dmax, s(side, next_d)); +// auto next_ls = find_ls(next_d, side.smoothness, dmax, s(side, next_d)); // if(next_ls.size() > nlines) // break; // @@ -283,7 +281,7 @@ tuple Interval::adjust_d_for_dmax_lmin(Interval::Side const& side, // size_t i; // for(i = 0; i < iter_limit; ++i) { // double next_d = current_d - current_d / step; -// auto next_ls = find_ls(next_d, a.lambda, dmax, s(a, next_d)); +// auto next_ls = find_ls(next_d, a.smoothness, dmax, s(a, next_d)); // if(next_ls.size() > nlines) // break; // @@ -299,9 +297,9 @@ tuple Interval::adjust_d_for_dmax_lmin(Interval::Side const& side, // TODO make the previous line go a step further the m line: ls.size()-- //****************************************************************************** -tuple Interval::adjust_lambda_for_s(Interval::Side const& side, size_t iter_limit) const { +tuple Interval::adjust_smoothness_for_s(Interval::Side const& side, size_t iter_limit) const { size_t step = 10000; - double current_lambda = side.lambda; + double current_smoothness = side.smoothness; size_t nlines = side.ls.size(); vector current_ls = side.ls; @@ -309,12 +307,12 @@ tuple Interval::adjust_lambda_for_s(Interval::Side const& side, si size_t counter = 0; bool is_limit_reached = false; /* - while(current_lambda > 1 && current_ls.size() <= nlines) { - current_lambda -= current_lambda / step; - if(current_lambda < 1) - current_lambda = 1; + while(current_smoothness > 1 && current_ls.size() <= nlines) { + current_smoothness -= current_smoothness / step; + if(current_smoothness < 1) + current_smoothness = 1; - current_ls = find_ls(side.meshline_policy->get_current_state().d, current_lambda, dmax, s(side)); + current_ls = find_ls(side.meshline_policy->get_current_state().d, current_smoothness, dmax, s(side)); ++counter; if(counter >= iter_limit) { @@ -324,17 +322,17 @@ tuple Interval::adjust_lambda_for_s(Interval::Side const& side, si } */ for(;;) { - double next_lambda = current_lambda - current_lambda / step; - if(next_lambda < 1) - next_lambda = 1; + double next_smoothness = current_smoothness - current_smoothness / step; + if(next_smoothness < 1) + next_smoothness = 1; - auto next_ls = find_ls(side.meshline_policy->get_current_state().d, next_lambda, get_current_state().dmax, s(side)); + auto next_ls = find_ls(side.meshline_policy->get_current_state().d, next_smoothness, get_current_state().dmax, s(side)); if(next_ls.size() > nlines) break; - current_lambda = next_lambda; + current_smoothness = next_smoothness; - if(current_lambda == 1) + if(current_smoothness == 1) break; if(counter++ >= iter_limit) { @@ -345,20 +343,20 @@ tuple Interval::adjust_lambda_for_s(Interval::Side const& side, si /* size_t i; - for(i = 0; i < iter_limit && (current_lambda > 1 && current_ls.size() <= nlines); ++i) { - current_lambda -= current_lambda / step; - if(current_lambda < 1) - current_lambda = 1; + for(i = 0; i < iter_limit && (current_smoothness > 1 && current_ls.size() <= nlines); ++i) { + current_smoothness -= current_smoothness / step; + if(current_smoothness < 1) + current_smoothness = 1; - current_ls = find_ls(a.meshline_policy->get_current_state().d, current_lambda, dmax, s(a)); + current_ls = find_ls(a.meshline_policy->get_current_state().d, current_smoothness, dmax, s(a)); } if(i >= iter_limit) is_limit_reached = true; - return { current_lambda, i >= iter_limit }; + return { current_smoothness, i >= iter_limit }; */ - return { current_lambda, is_limit_reached }; + return { current_smoothness, is_limit_reached }; } //****************************************************************************** @@ -385,13 +383,13 @@ void Interval::auto_solve_d() { } //****************************************************************************** -void Interval::auto_solve_lambda() { +void Interval::auto_solve_smoothness() { auto state = get_current_state(); update_ls(state); - state.before.lambda = get<0>(adjust_lambda_for_s(state.before)); - state.after.lambda = get<0>(adjust_lambda_for_s(state.after)); + state.before.smoothness = get<0>(adjust_smoothness_for_s(state.before)); + state.after.smoothness = get<0>(adjust_smoothness_for_s(state.after)); update_ls(state); set_next_state(state); diff --git a/src/domain/mesh/interval.hpp b/src/domain/mesh/interval.hpp index 94b22f20..7b8e48cd 100644 --- a/src/domain/mesh/interval.hpp +++ b/src/domain/mesh/interval.hpp @@ -47,11 +47,11 @@ class Interval struct Side { MeshlinePolicy* const meshline_policy; size_t lmin; ///< Minimum line number to mesh this half of the interval. - double lambda; ///< Smoothness factor = ]1;2] . + double smoothness; ///< Smoothness factor = ]1;2] . std::function const d_init_; std::vector ls; // TODO avoid Coord::operator= -> double - Side(MeshlinePolicy* meshline_policy, size_t lmin, double lambda, Coord h, std::function d_init); + Side(MeshlinePolicy* meshline_policy, size_t lmin, double smoothness, Coord h, std::function d_init); double d_init() const; }; @@ -62,7 +62,7 @@ class Interval Interval(MeshlinePolicy* before, MeshlinePolicy* after, Axis axis, GlobalParams* global_params, Timepoint* t); void auto_solve_d(); - void auto_solve_lambda(); + void auto_solve_smoothness(); std::vector> mesh() const; private: @@ -76,7 +76,7 @@ class Interval std::tuple adjust_d_for_dmax_lmin( Side const& side, size_t iter_limit=std::numeric_limits::max()) const; - std::tuple adjust_lambda_for_s( + std::tuple adjust_smoothness_for_s( Side const& side, size_t iter_limit=std::numeric_limits::max()) const; }; @@ -97,9 +97,9 @@ double find_dmax(Interval::Side const& side, double dmax); double find_dmax(Interval::Side const& a, Interval::Side const& b, double dmax); //****************************************************************************** -std::vector find_ls(double d, double lambda, double dmax, Coord s); +std::vector find_ls(double d, double smoothness, double dmax, Coord s); //****************************************************************************** -bool is_ls_valid_for_dmax_lmin_lambda(std::vector const& ls, double d, double lambda, double dmax, size_t lmin); +bool is_ls_valid_for_dmax_lmin_smoothness(std::vector const& ls, double d, double smoothness, double dmax, size_t lmin); } // namespace domain diff --git a/src/domain/meshline_policy_manager.cpp b/src/domain/meshline_policy_manager.cpp index 9d666b8a..8e92106a 100644 --- a/src/domain/meshline_policy_manager.cpp +++ b/src/domain/meshline_policy_manager.cpp @@ -184,7 +184,7 @@ void MeshlinePolicyManager::mesh(Axis const axis) { for(auto* interval : dimension_view) { interval->auto_solve_d(); - interval->auto_solve_lambda(); + interval->auto_solve_smoothness(); interval_meshlines.emplace_back(interval->mesh()); new_size += interval_meshlines.back().size(); diff --git a/src/infra/serializers/serializer_to_plantuml.cpp b/src/infra/serializers/serializer_to_plantuml.cpp index 09d5f0ed..8e475b8e 100644 --- a/src/infra/serializers/serializer_to_plantuml.cpp +++ b/src/infra/serializers/serializer_to_plantuml.cpp @@ -222,9 +222,9 @@ void SerializerToPlantuml::visit(Interval& interval) { "state \" \" as " + id + "_out <>\n" + id + " : dmax = " + to_string(interval.get_current_state().dmax) + "\n" + id + " : before.lmin = " + to_string(interval.get_current_state().before.lmin) + "\n" + - id + " : before.lambda = " + to_string(interval.get_current_state().before.lambda) + "\n" + + id + " : before.smoothness = " + to_string(interval.get_current_state().before.smoothness) + "\n" + id + " : after.lmin = " + to_string(interval.get_current_state().after.lmin) + "\n" + - id + " : after.lambda = " + to_string(interval.get_current_state().after.lambda) + "\n" + + id + " : after.smoothness = " + to_string(interval.get_current_state().after.smoothness) + "\n" + to_string(interval.get_current_state().before.meshline_policy->id) + "_out ------> " + id + "_in1 \n" + to_string(interval.get_current_state().after.meshline_policy->id) + "_out ------> " + id + "_in2 \n" "}\n"; diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index e7f72985..376e2927 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -157,8 +157,8 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { "Minimum line number per interval half." )->group("Mesher options"); - app.add_option_function("--smoothness", - make_overrider<&domain::Params::lambda>(domain_overrides), + app.add_option_function("--smoothness", + make_overrider<&domain::Params::smoothness>(domain_overrides), "Smoothness factor ]1;2]." )->group("Mesher options")->check(BoundExclusiveInclusive(1.0, 2.0)); diff --git a/src/ui/qt/edit/edit_model_global.cpp b/src/ui/qt/edit/edit_model_global.cpp index 3425b905..dc30be2b 100644 --- a/src/ui/qt/edit/edit_model_global.cpp +++ b/src/ui/qt/edit/edit_model_global.cpp @@ -28,7 +28,7 @@ EditModelGlobal::EditModelGlobal(domain::GlobalParams* global, QObject* parent) make_row(0, "Proximity limit", QString::number(params.proximity_limit), "Distance below which two MeshlinePolicies will be merged."); - make_row(1, "Smoothness", QString::number(params.lambda), + make_row(1, "Smoothness", QString::number(params.smoothness), "Smoothness factor ]1;2]. Meshing algorithm will decrease it, better to start high."); make_row(2, "lmin", QString::number(params.lmin), "Minimum line number per Interval half."); @@ -42,7 +42,7 @@ void EditModelGlobal::commit() { std::array does_succeed = { try_to_double(item(0, V)->text(), params.proximity_limit), - try_to_double(item(1, V)->text(), params.lambda), + try_to_double(item(1, V)->text(), params.smoothness), try_to_ulong(item(2, V)->text(), params.lmin), try_to_double(item(3, V)->text(), params.dmax) }; diff --git a/src/ui/qt/edit/edit_model_interval.cpp b/src/ui/qt/edit/edit_model_interval.cpp index 8786b781..3115f590 100644 --- a/src/ui/qt/edit/edit_model_interval.cpp +++ b/src/ui/qt/edit/edit_model_interval.cpp @@ -27,13 +27,13 @@ EditModelInterval::EditModelInterval(domain::Interval* interval, QObject* parent make_row(1, "Before.lmin", QString::number(state.before.lmin), "Minimum line number in the minimal interval half. " "Note a line will always be placed at the interval center."); - make_row(2, "Before.Smoothness", QString::number(state.before.lambda), QString("2"), + make_row(2, "Before.Smoothness", QString::number(state.before.smoothness), QString("2"), "Smoothness factor ]1;2] around the minimal side. " "Meshing algorithm will decrease it, better to start high."); make_row(3, "After.lmin", QString::number(state.after.lmin), "Minimum line number in the maximal interval half. " "Note a line will always be placed at the interval center."); - make_row(4, "After.Smoothness", QString::number(state.after.lambda), QString("2"), + make_row(4, "After.Smoothness", QString::number(state.after.smoothness), QString("2"), "Smoothness factor ]1;2] around the maximal side. " "Meshing algorithm will decrease it, better to start high."); } @@ -45,9 +45,9 @@ void EditModelInterval::commit() { std::array does_succeed = { try_to_double(item(0, V)->text(), state.dmax), try_to_ulong(item(1, V)->text(), state.before.lmin), - try_to_double(item(2, V)->text(), state.before.lambda), + try_to_double(item(2, V)->text(), state.before.smoothness), try_to_ulong(item(3, V)->text(), state.after.lmin), - try_to_double(item(4, V)->text(), state.after.lambda) + try_to_double(item(4, V)->text(), state.after.smoothness) }; if(std::ranges::all_of(does_succeed, is_true)) { diff --git a/src/ui/qt/processing_view/processing_interval.cpp b/src/ui/qt/processing_view/processing_interval.cpp index 072f089d..cf883f08 100644 --- a/src/ui/qt/processing_view/processing_interval.cpp +++ b/src/ui/qt/processing_view/processing_interval.cpp @@ -70,16 +70,16 @@ ProcessingInterval::ProcessingInterval(domain::Interval const* interval, QGraphi QString dmax("dmax: "); QString before_lmin ("Before.lmin: "); - QString before_lambda ("Before.Smoothness: "); + QString before_smoothness ("Before.Smoothness: "); QString after_lmin("After.lmin: "); - QString after_lambda("After.Smoothness: "); + QString after_smoothness("After.Smoothness: "); if(interval) { auto const& state = interval->get_current_state(); dmax += QString::number(state.dmax); before_lmin += QString::number(state.before.lmin); - before_lambda += QString::number(state.before.lambda); + before_smoothness += QString::number(state.before.smoothness); after_lmin += QString::number(state.after.lmin); - after_lambda += QString::number(state.after.lambda); + after_smoothness += QString::number(state.after.smoothness); if(state.before.meshline_policy) to_wire.emplace_back(DataKeys::set_to_wire(state.before.meshline_policy, before_port)); if(state.after.meshline_policy) @@ -100,10 +100,10 @@ ProcessingInterval::ProcessingInterval(domain::Interval const* interval, QGraphi return locate_processing_interval_params().main; }; - auto* text_before_lambda = new nodegraph::Text(before_lambda, this); - text_before_lambda->setFlag(QGraphicsItem::ItemIsSelectable); - text_before_lambda->setAcceptedMouseButtons(Qt::NoButton); - text_before_lambda->locate_text_params = [this]() -> auto& { + auto* text_before_smoothness = new nodegraph::Text(before_smoothness, this); + text_before_smoothness->setFlag(QGraphicsItem::ItemIsSelectable); + text_before_smoothness->setAcceptedMouseButtons(Qt::NoButton); + text_before_smoothness->locate_text_params = [this]() -> auto& { return locate_processing_interval_params().main; }; @@ -114,18 +114,18 @@ ProcessingInterval::ProcessingInterval(domain::Interval const* interval, QGraphi return locate_processing_interval_params().main; }; - auto* text_after_lambda = new nodegraph::Text(after_lambda, this); - text_after_lambda->setFlag(QGraphicsItem::ItemIsSelectable); - text_after_lambda->setAcceptedMouseButtons(Qt::NoButton); - text_after_lambda->locate_text_params = [this]() -> auto& { + auto* text_after_smoothness = new nodegraph::Text(after_smoothness, this); + text_after_smoothness->setFlag(QGraphicsItem::ItemIsSelectable); + text_after_smoothness->setAcceptedMouseButtons(Qt::NoButton); + text_after_smoothness->locate_text_params = [this]() -> auto& { return locate_processing_interval_params().main; }; v_box2->addItem(text_dmax); v_box2->addItem(text_before_lmin); - v_box2->addItem(text_before_lambda); + v_box2->addItem(text_before_smoothness); v_box2->addItem(text_after_lmin); - v_box2->addItem(text_after_lambda); + v_box2->addItem(text_after_smoothness); v_box3->addStretch(); v_box3->addItem(output_port); v_box3->addStretch(); diff --git a/test/unit/domain/mesh/test_interval.cpp b/test/unit/domain/mesh/test_interval.cpp index 2c37de98..07e8dd51 100644 --- a/test/unit/domain/mesh/test_interval.cpp +++ b/test/unit/domain/mesh/test_interval.cpp @@ -13,27 +13,27 @@ #include "domain/mesh/interval.hpp" -/// @test Interval::Side::Side(MeshlinePolicy* meshline_policy, size_t lmin, double lambda, Coord h, function d_init) +/// @test Interval::Side::Side(MeshlinePolicy* meshline_policy, size_t lmin, double smoothness, Coord h, function d_init) /// @test double Interval::Side::d_init_(double d) /// @test Coord Interval::s(Interval::Side const& side) const @todo /// @test Coord Interval::s(Interval::Side const& side, double d) const @todo -/// @test std::vector find_ls(double d, double lambda, double dmax, Coord s) -/// @test bool is_ls_valid_for_dmax_lmin_lambda(std::vector const& ls, double d, double lambda, double dmax, size_t lmin) +/// @test std::vector find_ls(double d, double smoothness, double dmax, Coord s) +/// @test bool is_ls_valid_for_dmax_lmin_smoothness(std::vector const& ls, double d, double smoothness, double dmax, size_t lmin) /// @test void Interval::update_ls() @todo /// @test void Interval::update_ls(Interval::Side& side) @todo /// @test double find_dmax(Interval::Side const& side, double dmax) /// @test double find_dmax(Interval::Side const& side, Interval::Side const& b, double dmax) /// @test std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Side const& side, size_t iter_limit) const -/// @test std::tuple Interval::adjust_lambda_for_s(Interval::Side const& side, size_t iter_limit) const +/// @test std::tuple Interval::adjust_smoothness_for_s(Interval::Side const& side, size_t iter_limit) const /// @test void Interval::auto_solve_d() @todo -/// @test void Interval::auto_solve_lambda() @todo +/// @test void Interval::auto_solve_smoothness() @todo /// @test std::vector> Interval::mesh() const ///***************************************************************************** using namespace domain; //****************************************************************************** -SCENARIO("Interval::Side::Side(MeshlinePolicy* meshline_policy, size_t lmin, double lambda, Coord h, function d_init)", "[interval]") { +SCENARIO("Interval::Side::Side(MeshlinePolicy* meshline_policy, size_t lmin, double smoothness, Coord h, function d_init)", "[interval]") { Timepoint* t = Caretaker::singleton().get_history_root(); GIVEN("Two meshline policies") { GlobalParams p(t); @@ -189,7 +189,7 @@ SCENARIO("double Interval::Side::d_init_(double d)", "[interval]") { } //****************************************************************************** -SCENARIO("std::vector find_ls(double d, double lambda, double dmax, Coord s)", "[interval]") { +SCENARIO("std::vector find_ls(double d, double smoothness, double dmax, Coord s)", "[interval]") { GIVEN("d > dmax") { std::vector ls = find_ls(4.0, 2.0, 3.0, 10.0); THEN("Coordinates should grow according 'ls[n] = ls[n-1] + dmax' algorithm") { @@ -205,7 +205,7 @@ SCENARIO("std::vector find_ls(double d, double lambda, double dmax, Coord GIVEN("dmax will be reached to fill s") { std::vector ls = find_ls(0.1, 2.0, 3.0, 10.0); - THEN("Coordinates should grow according 'ls[n] = ls[n-1] + ls[n-1] * lambda' algorithm until ls[n] reaches dmax") { + THEN("Coordinates should grow according 'ls[n] = ls[n-1] + ls[n-1] * smoothness' algorithm until ls[n] reaches dmax") { REQUIRE(ls.size() == 7); REQUIRE(ls[0] == Coord(0.2)); REQUIRE(ls[1] == Coord(0.6)); @@ -223,7 +223,7 @@ SCENARIO("std::vector find_ls(double d, double lambda, double dmax, Coord GIVEN("dmax will not be reached to fill s") { std::vector ls = find_ls(0.1, 2.0, 30.0, 10.0); - THEN("Coordinates should grow according 'ls[n] = ls[n-1] + ls[n-1] * lambda' algorithm") { + THEN("Coordinates should grow according 'ls[n] = ls[n-1] + ls[n-1] * smoothness' algorithm") { REQUIRE(ls.size() == 6); REQUIRE(ls[0] == Coord(0.2)); REQUIRE(ls[1] == Coord(0.6)); @@ -246,11 +246,11 @@ SCENARIO("std::vector find_ls(double d, double lambda, double dmax, Coord } //****************************************************************************** -SCENARIO("bool is_ls_valid_for_dmax_lmin_lambda(std::vector const& ls, double d, double lambda, double dmax, size_t lmin)", "[interval]") { +SCENARIO("bool is_ls_valid_for_dmax_lmin_smoothness(std::vector const& ls, double d, double smoothness, double dmax, size_t lmin)", "[interval]") { GIVEN("An empty ls vector") { THEN("Should not be valid, disregarding lmin") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda({}, 1.0, 2.0, 3.0, 2)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda({}, 1.0, 2.0, 3.0, 0)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness({}, 1.0, 2.0, 3.0, 2)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness({}, 1.0, 2.0, 3.0, 0)); } } @@ -258,27 +258,27 @@ SCENARIO("bool is_ls_valid_for_dmax_lmin_lambda(std::vector const& ls, do std::vector ls { 0.2 }; WHEN("There is less than lmin lines") { THEN("Should not be valid") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 30.0, 10)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 30.0, 10)); } } WHEN("A space between two lines, including d exceeds dmax") { THEN("Should not be valid") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 0.05, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 0.05, 5)); } } - WHEN("A space between two lines is not between lambda times and 1/lambda times its adjacent spaces, d being the space previous the first ls space") { + WHEN("A space between two lines is not between smoothness times and 1/smoothness times its adjacent spaces, d being the space previous the first ls space") { THEN("Should not be valid") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.05, 2.0, 30.0, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.05, 2.0, 30.0, 5)); } } WHEN("There is lmin lines or more") { AND_WHEN("No space between two lines exceeds dmax") { - AND_WHEN("Every space between two lines is between lambda times and 1/lambda times its adjacent spaces") { + AND_WHEN("Every space between two lines is between smoothness times and 1/smoothness times its adjacent spaces") { THEN("Should be valid") { - REQUIRE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 30.0, 1)); + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 30.0, 1)); } } } @@ -289,37 +289,37 @@ SCENARIO("bool is_ls_valid_for_dmax_lmin_lambda(std::vector const& ls, do std::vector ls { 0.2, 0.6, 1.4, 3.0, 6.2, 12.6 }; WHEN("There is less than lmin lines") { THEN("Should not be valid") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 30.0, 10)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 30.0, 10)); } } WHEN("A space between two lines, including d exceeds dmax") { THEN("Should not be valid") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 0.05, 5)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 0.15, 5)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 0.25, 5)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 5.0, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 0.05, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 0.15, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 0.25, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 5.0, 5)); } } - WHEN("A space between two lines is not between lambda times and 1/lambda times its adjacent spaces, d being the space previous the first ls space") { + WHEN("A space between two lines is not between smoothness times and 1/smoothness times its adjacent spaces, d being the space previous the first ls space") { THEN("Should not be valid") { std::vector ls1 { 0.3, 0.6, 1.4, 3.0, 6.2, 12.6 }; std::vector ls2 { 0.2, 1.0, 1.4, 3.0, 6.2, 12.6 }; std::vector ls3 { 0.2, 0.6, 1.4, 3.0, 6.2, 13.6 }; - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.05, 2.0, 30.0, 5)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls1, 0.1, 2.0, 30.0, 5)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls2, 0.1, 2.0, 30.0, 5)); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda(ls3, 0.1, 2.0, 30.0, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.05, 2.0, 30.0, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls1, 0.1, 2.0, 30.0, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls2, 0.1, 2.0, 30.0, 5)); + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness(ls3, 0.1, 2.0, 30.0, 5)); } } WHEN("There is lmin lines or more") { AND_WHEN("No space between two lines exceeds dmax") { - AND_WHEN("Every space between two lines is between lambda times and 1/lambda times its adjacent spaces") { + AND_WHEN("Every space between two lines is between smoothness times and 1/smoothness times its adjacent spaces") { THEN("Should be valid") { - REQUIRE(is_ls_valid_for_dmax_lmin_lambda(ls, 0.1, 2.0, 30.0, 5)); + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness(ls, 0.1, 2.0, 30.0, 5)); } } } @@ -348,7 +348,7 @@ SCENARIO("double find_dmax(Interval::Side const& side, double dmax)", "[interval t); auto state_p = p.get_current_state(); auto state_a = a.get_current_state(); - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 1; p.set_next_state(state_p); a.set_next_state(state_a); @@ -365,7 +365,7 @@ SCENARIO("double find_dmax(Interval::Side const& side, double dmax)", "[interval state_i.before.ls = { 3.0 }; i.set_next_state(state_i); AND_WHEN("The line coord does not exceed dmax") { - THEN("Should return lambda times the line coord") { + THEN("Should return smoothness times the line coord") { REQUIRE(i.get_current_state().before.ls.size() == 1); REQUIRE(find_dmax(i.get_current_state().before, 8.0) == 6.0); } @@ -384,7 +384,7 @@ SCENARIO("double find_dmax(Interval::Side const& side, double dmax)", "[interval state_i.before.ls = { 1.0, 3.0, 6.0 }; i.set_next_state(state_i); AND_WHEN("The last space does not exceed dmax") { - THEN("Should return lambda times the last space") { + THEN("Should return smoothness times the last space") { REQUIRE(i.get_current_state().before.ls.size() == 3); REQUIRE(find_dmax(i.get_current_state().before, 8.0) == 6.0); } @@ -421,7 +421,7 @@ SCENARIO("double find_dmax(Interval::Side const& side, Interval::Side const& b, t); auto state_p = p.get_current_state(); auto state_a = a.get_current_state(); - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 1; p.set_next_state(state_p); a.set_next_state(state_a); @@ -471,10 +471,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si i.update_ls(state_i); i.set_next_state(state_i); THEN("Initial ls should be conform") { - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -513,10 +513,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si i.update_ls(state_i); i.set_next_state(state_i); THEN("Initial ls should not be conform") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -530,10 +530,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si auto state_i = i.get_current_state(); i.update_ls(state_i); i.set_next_state(state_i); - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -568,10 +568,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si i.update_ls(state_i); i.set_next_state(state_i); THEN("Initial ls should not be conform") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -585,10 +585,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si auto state_i = i.get_current_state(); i.update_ls(state_i); i.set_next_state(state_i); - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -623,10 +623,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si i.update_ls(state_i); i.set_next_state(state_i); THEN("Initial ls should not be conform") { - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -643,10 +643,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si auto state_i = i.get_current_state(); i.update_ls(state_i); i.set_next_state(state_i); - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -665,10 +665,10 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si auto state_i = i.get_current_state(); i.update_ls(state_i); i.set_next_state(state_i); - REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE_FALSE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); } @@ -679,9 +679,9 @@ SCENARIO("std::tuple Interval::adjust_d_for_dmax_lmin(Interval::Si } //****************************************************************************** -SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side const& side, size_t iter_limit) const", "[interval]") { +SCENARIO("std::tuple Interval::adjust_smoothness_for_s(Interval::Side const& side, size_t iter_limit) const", "[interval]") { Timepoint* t = Caretaker::singleton().get_history_root(); - GIVEN("A Side of an Interval with previously computed valid ls with lambda superior to 2") { + GIVEN("A Side of an Interval with previously computed valid ls with smoothness superior to 2") { GlobalParams p(t); MeshlinePolicy a( Y, @@ -701,7 +701,7 @@ SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side auto state_a = a.get_current_state(); state_p.dmax = 30.0; state_p.lmin = 5; - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 0.1; p.set_next_state(state_p); a.set_next_state(state_a); @@ -714,28 +714,28 @@ SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side i.set_next_state(state_i); j.set_next_state(state_j); Coord old_last_space = i.get_current_state().before.ls.back() - i.s(i.get_current_state().before); - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( j.get_current_state().before.ls, a.get_current_state().d, - j.get_current_state().before.lambda, + j.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); WHEN("Process iterations are unlimited") { - THEN("Side's lambda should be reduced") { + THEN("Side's smoothness should be reduced") { { - auto [new_lambda, is_limit_reached] = i.adjust_lambda_for_s(i.get_current_state().before); + auto [new_smoothness, is_limit_reached] = i.adjust_smoothness_for_s(i.get_current_state().before); auto state_i = i.get_current_state(); - state_i.before.lambda = new_lambda; + state_i.before.smoothness = new_smoothness; i.update_ls(state_i); i.set_next_state(state_i); REQUIRE_FALSE(is_limit_reached); - REQUIRE(i.get_current_state().before.lambda < p.get_current_state().lambda); + REQUIRE(i.get_current_state().before.smoothness < p.get_current_state().smoothness); } AND_THEN("The space between the last ls line and the middle of the Interval should be reduced") { @@ -743,15 +743,15 @@ SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side REQUIRE(new_last_space < old_last_space); AND_WHEN("Process iterations are limited") { - THEN("Side's lambda should be reduced") { + THEN("Side's smoothness should be reduced") { { - auto [new_lambda, is_limit_reached] = j.adjust_lambda_for_s(j.get_current_state().before, 20); + auto [new_smoothness, is_limit_reached] = j.adjust_smoothness_for_s(j.get_current_state().before, 20); auto state_j = j.get_current_state(); - state_j.before.lambda = new_lambda; + state_j.before.smoothness = new_smoothness; j.update_ls(state_j); j.set_next_state(state_j); REQUIRE(is_limit_reached); - REQUIRE(j.get_current_state().before.lambda < p.get_current_state().lambda); + REQUIRE(j.get_current_state().before.smoothness < p.get_current_state().smoothness); } AND_THEN("The space between the last ls line and the middle of the Interval should be reduced, but less than if unlimited") { @@ -766,7 +766,7 @@ SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side } } - GIVEN("A Side of an Interval with previously computed valid ls with lambda being 1") { + GIVEN("A Side of an Interval with previously computed valid ls with smoothness being 1") { GlobalParams p(t); MeshlinePolicy a( Y, @@ -786,7 +786,7 @@ SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side auto state_a = a.get_current_state(); state_p.dmax = 30.0; state_p.lmin = 5; - state_p.lambda = 1; + state_p.smoothness = 1; state_a.d = 0.1; p.set_next_state(state_p); a.set_next_state(state_a); @@ -795,20 +795,20 @@ SCENARIO("std::tuple Interval::adjust_lambda_for_s(Interval::Side i.update_ls(state_i); i.set_next_state(state_i); Coord old_last_space = i.get_current_state().before.ls.back() - i.s(i.get_current_state().before); - REQUIRE(is_ls_valid_for_dmax_lmin_lambda( + REQUIRE(is_ls_valid_for_dmax_lmin_smoothness( i.get_current_state().before.ls, a.get_current_state().d, - i.get_current_state().before.lambda, + i.get_current_state().before.smoothness, p.get_current_state().dmax, p.get_current_state().lmin)); - THEN("Side's lambda should not be reduced") { - auto [new_lambda, is_limit_reached] = i.adjust_lambda_for_s(i.get_current_state().before); + THEN("Side's smoothness should not be reduced") { + auto [new_smoothness, is_limit_reached] = i.adjust_smoothness_for_s(i.get_current_state().before); auto state_i = i.get_current_state(); - state_i.before.lambda = new_lambda; + state_i.before.smoothness = new_smoothness; i.update_ls(state_i); i.set_next_state(state_i); REQUIRE_FALSE(is_limit_reached); - REQUIRE(new_lambda == p.get_current_state().lambda); + REQUIRE(new_smoothness == p.get_current_state().smoothness); AND_THEN("The space between the last ls line and the middle of the Interval should not be reduced") { Coord new_last_space = i.get_current_state().before.ls.back() - i.s(i.get_current_state().before); @@ -868,7 +868,7 @@ SCENARIO("std::vector> Interval::mesh() const", "[inte auto state_d = d.get_current_state(); state_p.dmax = 2; state_p.lmin = 5; - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 0.1; state_b.d = 0.1; state_c.d = 0.1; @@ -968,7 +968,7 @@ SCENARIO("std::vector> Interval::mesh() const", "[inte auto state_b = b.get_current_state(); state_p.dmax = 1.5; state_p.lmin = 5; - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 0.1; state_b.d = 0.1; p.set_next_state(state_p); @@ -1053,7 +1053,7 @@ SCENARIO("std::vector> Interval::mesh() const", "[inte auto state_d = d.get_current_state(); state_p.dmax = 2; state_p.lmin = 5; - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 0.1; state_b.d = 0.1; state_c.d = 0.1; @@ -1100,7 +1100,7 @@ SCENARIO("std::vector> Interval::mesh() const", "[inte auto state_b = b.get_current_state(); state_p.dmax = 1.5; state_p.lmin = 5; - state_p.lambda = 2; + state_p.smoothness = 2; state_a.d = 0.1; state_b.d = 0.1; p.set_next_state(state_p); From 2e5c795e68aad84ed17034be30e502fbd4c73f59 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Fri, 28 Nov 2025 03:28:30 +0100 Subject: [PATCH 14/15] add test run_dual_dipole.xml --- test/run_dual_dipole.xml | 656 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 656 insertions(+) create mode 100644 test/run_dual_dipole.xml diff --git a/test/run_dual_dipole.xml b/test/run_dual_dipole.xml new file mode 100644 index 00000000..dc55829a --- /dev/null +++ b/test/run_dual_dipole.xml @@ -0,0 +1,656 @@ + + + + + + -1027.72,-1007.72,-987.72,-967.72,-947.72,-927.72,-907.72,-887.72,-867.72,-847.72,-827.72,-807.72,-787.72,-767.72,-747.72,-727.72,-707.72,-687.72,-667.72,-647.72,-627.72,-607.72,-587.72,-567.72,-547.72,-527.72,-510.500933243393,-493.281866486787,-476.06279973018,-462.808876239791,-452.607017429893,-444.754405088155,-438.710063391346,-434.057590436124,-430.47647181563,-427.72,-425.22,-422.72,-420.20903067804,-416.944770559492,-412.70123240538,-407.184632805034,-400.013053324585,-390.69,-381.366946675415,-374.195367194966,-368.67876759462,-364.435229440508,-361.17096932196,-358.66,-356.16,-353.66,s-351.39,-349.12,-346.62,-344.55,-342.48,-339.98,-337.48,-334.98,-331.800708126573,-327.67027542512,-322.304151464048,-315.332657568151,-306.275519214081,-294.508779346024,-279.221813230472,-259.361483552204,-239.501153873937,-219.640824195669,-199.780494517401,-179.920164839134,-160.059835160866,-140.199505482599,-120.339175804331,-100.478846126063,-80.6185164477959,-60.7581867695283,-45.4712206539763,-33.7044807859187,-24.6473424318488,-17.6758485359524,-12.30972457488,-8.17929187342651,-5,-2.5,0,2.5,5,8.21219771838785,12.3853806244492,17.8070442623226,24.8506935017421,34.0015737336695,45.8901000036093,61.3352870554434,81.401172233266,101.467057411089,121.532942588911,141.598827766734,161.664712944557,177.109899996391,188.998426266331,198.149306498258,205.192955737677,210.614619375551,214.787802281612,218,220.5,223,226,229,231.5,234,236.971881324672,240.8328529803,245.848901905874,252.365589690174,260.831858721467,271.830960363705,286.120635838119,304.68531791906,323.25,341.81468208094,360.379364161881,374.669039636295,385.668141278533,394.134410309826,400.651098094126,405.6671470197,409.528118675328,412.5,415,417.5,420.5,423.5,426,431,436,438.5,441,443.5,448.5,453.5,456,458.5,461,463.5,466.528373571798,470.465259215134,475.583210551472,482.236547288711,490.885885047122,502.130024133057,516.747404944771,535.75,554.752595055229,569.369975866943,580.614114952878,589.263452711289,595.916789448528,601.034740784866,604.971626428202,608,610.5,613,616,619,621.5,624,627.177482704453,631.305564992359,636.668635372519,643.63616215531,652.688146564931,664.448190595822,679.726457697286,699.575485899095,719.424514100905,739.273542302714,754.551809404178,766.311853435069,775.36383784469,782.331364627481,787.694435007641,791.822517295547,795,797.5,800,802.5,805,808.11457955972,812.160940125817,817.417840300277,824.247434201471,833.120220692992,844.647456611125,859.623266976819,879.07935321484,898.535439452861,917.991525690883,937.447611928904,956.903698166925,976.359784404947,995.815870642968,1015.27195688099,1034.72804311901,1054.18412935703,1073.64021559505,1093.09630183307,1112.5523880711,1132.00847430912,1151.46456054714,1170.92064678516,1190.37673302318,1205.35254338887,1216.87977930701,1225.75256579853,1232.58215969972,1237.83905987418,1241.88542044028,1245,1247.5,1250,1252.75647181563,1256.33759043612,1260.99006339135,1267.03440508815,1274.88701742989,1285.08887623979,1298.34279973018,1315.56186648679,1332.78093324339,1350,1370,1390,1410,1430,1450,1470,1490,1510,1530,1550,1570,1590,1610,1630,1650,1670,1690,1710,1730,1750,1770,1790,1810,1830,1850 + -1350,-1330,-1310,-1290,-1270,-1250,-1230,-1210,-1190,-1170,-1150,-1130,-1110,-1090,-1070,-1050,-1030,-1010,-990,-970,-950,-930,-910,-890,-870,-850,-832.780933243393,-815.561866486787,-798.34279973018,-785.088876239791,-774.887017429893,-767.034405088155,-760.990063391346,-756.337590436124,-752.75647181563,-750,-747.5,-745,-741.823548757295,-737.696806510978,-732.33547706931,-725.370212057241,-716.321166066654,-704.564939534299,-689.291632002895,-669.449047113363,-649.60646222383,-629.763877334298,-609.921292444766,-590.078707555234,-570.236122665702,-550.39353777617,-530.550952886637,-510.708367997105,-495.435060465701,-483.678833933346,-474.629787942759,-467.66452293069,-462.303193489022,-458.176451242705,-455,-452.5,-450,-447.5,-445,-441.766771984943,-437.566267200758,-432.10910786656,-425.01934377179,-415.80855261814,-403.842192025304,-388.29588515013,-368.098628383377,-347.901371616623,-327.70411484987,-312.157807974696,-300.19144738186,-290.98065622821,-283.89089213344,-278.433732799242,-274.233228015057,-271,-268.5,-266,-263,-260,-257.5,-255,-249.75,-244.5,-242,-239.5,-236.5,-233.5,-231,-228.5,-225.276062870043,-221.087628501905,-215.646150660047,-208.576759450607,-199.392436087628,-187.46046158845,-171.958828008894,-151.819609336298,-131.680390663702,-111.541171991106,-96.0395384115504,-84.107563912372,-74.9232405493933,-67.8538493399532,-62.412371498095,-58.2239371299566,-55,-52.5,-50,-47.5,-45,-42.3735251333441,-38.9591078066914,-34.520365282043,-28.75,-22.979634717957,-18.5408921933086,-15.1264748666559,-12.5,-10,-7.5,-5,-2.5,0,2.5,5,7.5,10,12.5,15.1264748666559,18.5408921933086,22.979634717957,28.75,34.520365282043,38.9591078066914,42.3735251333441,45,47.5,50,52.5,55,58.2239371299566,62.412371498095,67.8538493399532,74.9232405493933,84.107563912372,96.0395384115504,111.541171991106,131.680390663702,151.819609336298,171.958828008894,187.46046158845,199.392436087628,208.576759450607,215.646150660047,221.087628501905,225.276062870043,228.5,231,233.5,236.5,239.5,242,244.5,249.75,255,257.5,260,263,266,268.5,271,274.233228015057,278.433732799242,283.89089213344,290.98065622821,300.19144738186,312.157807974696,327.70411484987,347.901371616623,368.098628383377,388.29588515013,403.842192025304,415.80855261814,425.01934377179,432.10910786656,437.566267200758,441.766771984943,445,447.5,450,452.5,455,458.176451242705,462.303193489022,467.66452293069,474.629787942759,483.678833933346,495.435060465701,510.708367997105,530.550952886637,550.39353777617,570.236122665702,590.078707555234,609.921292444766,629.763877334298,649.60646222383,669.449047113363,689.291632002895,704.564939534299,716.321166066654,725.370212057241,732.33547706931,737.696806510978,741.823548757295,745,747.5,750,752.75647181563,756.337590436124,760.990063391346,767.034405088155,774.887017429893,785.088876239791,798.34279973018,815.561866486787,832.780933243393,850,870,890,910,930,950,970,990,1010,1030,1050,1070,1090,1110,1130,1150,1170,1190,1210,1230,1250,1270,1290,1310,1330,1350 + -500,-483.323806506617,-466.647613013234,-446.358586360485,-426.069559707736,-405.780533054986,-385.491506402237,-365.202479749488,-344.913453096738,-324.624426443989,-304.33539979124,-284.04637313849,-263.757346485741,-243.468319832992,-223.179293180242,-202.890266527493,-182.601239874744,-162.312213221994,-142.023186569245,-121.734159916496,-101.445133263747,-81.1561066109972,-60.8670799582479,-40.5780533054986,-20.2890266527493,0,16.4541235695014,32.9082471390027,53.197273791752,73.4863004445014,93.7753270972507,114.06435375,132.1648875,146.088375,156.79875,165.0375,171.375,176.25,180,181.875,183.75,184.79,185.21,185.75,186.24,186.78,187.27,187.81,188.3,188.84,189.33,190.1803,192.1803,193.5803,194.9803,196.4803,197.9803,198.7303,199.4803,199.8803,200.8178,201.7553,203.6303,208.5053,214.8428,223.08155,233.791925,247.7154125,265.81594625,286.104972902749,306.393999555499,326.683026208248,346.972052860997,367.261079513747,387.550106166496,407.839132819245,428.128159471995,448.417186124744,468.706212777493,488.995239430243,509.284266082992,529.573292735741,549.862319388491,570.15134604124,590.440372693989,610.729399346738,631.018425999488,651.307452652237,675.593876326118,699.8803 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 245000000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 245000000000 + + + + From e4dbb82333e2d7dd5946572efe73c56fbe713713 Mon Sep 17 00:00:00 2001 From: "tlepoix@localhost" Date: Fri, 28 Nov 2025 04:30:33 +0100 Subject: [PATCH 15/15] Cli : elaborate description --- src/ui/cli/cli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/cli/cli.cpp b/src/ui/cli/cli.cpp index 376e2927..5b4c405c 100644 --- a/src/ui/cli/cli.cpp +++ b/src/ui/cli/cli.cpp @@ -109,7 +109,7 @@ app::OpenEMSH::Params cli(int const argc, char* argv[]) { app::OpenEMSH::Params params; vector> domain_overrides; - CLI::App app("OpenEMSH mesher"); + CLI::App app("OpenEMSH - Mesher for the openEMS FDTD solver", "OpenEMSH"); #ifdef _WIN32 argv = app.ensure_utf8(argv);