Loading...
Searching...
No Matches
d/Spline3D/GeneratorDialog.hpp
1#pragma once
2#include <Process/Script/ScriptEditor.hpp>
3
4#include <ossia/math/math_expression.hpp>
5
6#include <QDialog>
7#include <QDoubleSpinBox>
8#include <QFormLayout>
9#include <QHBoxLayout>
10
11#include <cmath>
12
13#include <Spline3D/Commands.hpp>
14
15namespace Spline3D
16{
18{
19public:
21 const ProcessModel& model, const score::DocumentContext& ctx, QWidget* parent)
22 : Process::ScriptDialog{"exprtk", ctx, parent}
23 , m_model{model}
24 {
25 auto step = new QDoubleSpinBox{this};
26 step->setRange(0.0001, 0.3);
27 step->setValue(m_step);
28 step->setSingleStep(0.001);
29 step->setDecimals(8);
30 //step->setStepType(QSpinBox::AdaptiveDecimalStepType);
31 auto lay = static_cast<QBoxLayout*>(this->layout());
32 auto controls = new QFormLayout;
33 controls->addRow("Step (smaller is more precise)", step);
34 lay->insertLayout(2, controls);
35 connect(
36 step, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
37 [this](double step) { m_step = step; });
38
39 expr.add_variable("t", t);
40 expr.add_variable("x", x);
41 expr.add_variable("y", y);
42 expr.add_variable("z", z);
43 expr.add_constants();
44 expr.register_symbol_table();
45
46 setText(R"_(x := cos(2 * pi * t);
47y := sin(2 * pi * t);
48z := sin(7 * pi * t);
49)_");
50 }
51
52 void on_accepted() override
53 {
54 this->setError(0, QString{});
55 auto txt = this->text().toStdString();
56 bool ok = expr.set_expression(txt);
57 if(!ok)
58 {
59 setError(0, QString::fromStdString(expr.error()));
60 return;
61 }
62 else
63 {
64 ossia::spline3d_data data;
65 QString error;
66 auto add_point = [&] {
67 expr.value();
68 if(expr.interrupted())
69 error = tr("The expression runs for too long (a loop does not end)");
70 else if(!(std::isfinite(x) && std::isfinite(y) && std::isfinite(z)))
71 error = tr("The expression gives an undefined point at t = %1").arg(t);
72 else
73 data.points.push_back({x, y, z});
74 return error.isEmpty();
75 };
76 bool complete = true;
77 for(t = 0.; t < 1. && complete; t += m_step)
78 complete = add_point();
79 if(complete)
80 {
81 t = 1.;
82 complete = add_point();
83 }
84 if(!complete)
85 {
86 setError(0, error);
87 return;
88 }
89
90 CommandDispatcher<>{m_context.commandStack}.submit<ChangeSpline>(
91 m_model, std::move(data));
92 }
93 }
94 double t{}, x{}, y{}, z{};
95 double m_step{0.03};
96 ossia::math_expression expr;
97
98 const ProcessModel& m_model;
99};
100
101}
The CommandDispatcher class.
Definition CommandDispatcher.hpp:13
Definition ScriptEditor.hpp:22
Definition plugins/score-plugin-spline3d/Spline3D/commands.hpp:14
Definition d/Spline3D/GeneratorDialog.hpp:18
Definition score-plugin-spline3d/Spline3D/Model.hpp:20
Definition DocumentContext.hpp:18