0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

地盤技術者が自作FEMプログラム用にGUIを開発する話(第2回)

0
Posted at

はじめに

第2回ではポストプロセッサーとしてx-yグラフを表示したいと思います。
有限要素解析としては土-水連成解析を対象としています。
土-水連成解析の概要は以下をご覧ください。

やったこと

結果をX-Yグラフで出力させた

現時点で以下のようなGUIが完成しました。

image.png

プログラムの構成を作った

今のところ以下のような構造にしています

.
└── src
    ├── data
    │       └── result.rs
    ├── post
    │       └── plot.rs
    ├── app.rs
    ├── data.rs
    ├── lib.rs
    ├── main.rs
    └── post.rs

main.rs: GUIの呼び出し
app.rs: GUIのデザインを構成
result.rs: 結果ファイル(.csv)を読み込み
plot.rs: 結果をグラフとして表示

苦労したところ

Hello world表示

あるあるかもしれませんが、GUI画面上で「Hello World」を表示させるまでにだいぶ時間がかかりました。
最初は前節で示した構成ではなくmain.rsだけで以下のように試しました。

use eframe::egui;

#[derive(Default)]
struct MyApp {}

impl eframe::App for MyApp {
    fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show_inside(ui, |ui| {
            ui.heading("GeoGEN");
            ui.label("Hello GeoGEN!");
        });
    }
}

fn main() -> eframe::Result<()> {
    let options = eframe::NativeOptions::default();
    eframe::run_native(
        "GeoGEN GUI",
        options,
        Box::new(|_cc| Ok(Box::new(MyApp::default()))),
    )
}

ちなみにGeoGENは今開発中のFEMプログラムの仮称です。

画面がダークモードになる

eguiでは画面がOSのダーク/ライトモードに引っ張られるようです。
画面を表示してみると、ダークモードになり非常に見にくかったです。
強制的にライトモードにするには以下のようにCentralPanelで包んでやる必要があります。
これを実装するまでにかなり時間を要しました。

impl eframe::App for MyApp {
    fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
        ui.ctx().set_visuals(egui::Visuals::light());

        egui::CentralPanel::default().show_inside(ui, |ui| {
            self.draw_header(ui);
            ui.separator();

            self.draw_controls(ui);
            ui.separator();

            if let Some(message) = &self.error_message {
                ui.colored_label(egui::Color32::RED, message);
                ui.separator();
            }

            draw_plot(ui, &self.cases, self.plot_type);
        });
    }
}

グラフの出力

第2回の肝です。
最初はこのような感じでグラフ出力しました。

まず、MyAPPにデータを持たせます。

struct MyApp {
    data: Vec<ElementResult>,
}

次にボタンクリックしてcsv選択→読み込み→指定した変数をグラフとして出力するまでを実装しました。

impl eframe::App for MyApp {
    fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show_inside(ui, |ui| {
            ui.heading("GeoGEN");
            ui.label("Hello GeoGEN!");

            let btn = ui.add(egui::Button::new(
                egui::RichText::new("Open CSV").size(16.0),
            ));

            if btn.clicked() {
                if let Some(path) = rfd::FileDialog::new()
                    .add_filter("CSV", &["csv"])
                    .pick_file()
                {
                    match read_csv(&path) {
                        Ok(data) => {
                            self.data = data;
                        }

                        Err(e) => {
                            eprintln!("CSV read error: {}", e);
                        }
                    }
                }
            }

            for row in self.data.iter().take(5) {
                ui.label(format!(
                    "step={} p'={} q={}",
                    row.step, row.mean_effective_stress, row.deviatoric_stress
                ));
            }
        });
    }
}

fn read_csv(path: &Path) -> Result<Vec<ElementResult>, Box<dyn Error>> {
    let mut reader = csv::Reader::from_path(path)?;
    let mut data = Vec::new();

    for result in reader.deserialize() {
        let row: ElementResult = result?;
        data.push(row);
    }

    Ok(data)
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?