PeriDyno 1.0.0
Loading...
Searching...
No Matches
WPythonWidget.cpp
Go to the documentation of this file.
1#include "WPythonWidget.h"
2
3#include <Wt/WTextArea.h>
4#include <Wt/WPushButton.h>
5#include <Wt/WVBoxLayout.h>
6#include <Wt/WMessageBox.h>
7#include <Wt/WJavaScript.h>
8
9#include <SceneGraph.h>
10
11// python
12#include <pybind11/embed.h>
13namespace py = pybind11;
14
16{
17 this->setLayoutSizeAware(true);
18 this->setOverflow(Wt::Overflow::Auto);
19 this->setHeight(Wt::WLength("100%"));
20 this->setMargin(0);
21
22 auto layout = this->setLayout(std::make_unique<Wt::WVBoxLayout>());
23 layout->setContentsMargins(0, 0, 0, 0);
24
25 mCodeEditor = layout->addWidget(std::make_unique<Wt::WText>(), 1);
26 mCodeEditor->setInline(false);
27 mCodeEditor->setWidth(Wt::WLength("640px"));
28
29 // ACE editor
30 std::string ref = mCodeEditor->jsRef(); // is a text string that will be the element when executed in JS
31
32 std::string command =
33 ref + ".editor = ace.edit(" + ref + ");" +
34 ref + ".editor.setTheme(\"ace/theme/monokai\");" +
35 ref + ".editor.getSession().setMode(\"ace/mode/python\");" +
36 ref + ".editor.setFontSize(14);" +
37 "ace.require(\"ace/ext/language_tools\");" +
38 ref + ".editor.setOptions({enableBasicAutocompletion: true,enableSnippets : true,enableLiveAutocompletion : true});" +
39 ref + ".editor.setOption(\"wrap\",\"free\")";
40 mCodeEditor->doJavaScript(command);
41
42 // create signal
43 auto jsignal = new Wt::JSignal<std::string>(mCodeEditor, "update");
44 jsignal->connect(this, &WPythonWidget::execute);
45
46 auto str = jsignal->createCall({ ref + ".editor.getValue()" });
47 command = "function(object, event) {" + str + ";}";
48 auto btn = layout->addWidget(std::make_unique<Wt::WPushButton>("Update"), 0);
49 btn->clicked().connect(command);
50
51 // some default code here...
52 std::string source = R"====(# dyno sample
53import PyPeridyno as dyno
54
55scene = dyno.SceneGraph()
56
57emitter = dyno.SquareEmitter3f()
58emitter.var_location().set_value(dyno.Vector3f([0.5, 0.5, 0.5]))
59
60fluid = dyno.ParticleFluid3f()
61fluid.load_particles(dyno.Vector3f([0, 0, 0]), dyno.Vector3f([0.2, 0.2, 0.2]), 0.05)
62
63emitter.connect(fluid.import_particle_emitters())
64
65calculateNorm = dyno.CalculateNorm3f()
66colorMapper = dyno.ColorMapping3f()
67colorMapper.var_max().set_value(0.5)
68
69ptRender = dyno.GLPointVisualModule()
70ptRender.set_color(dyno.Color(1, 0, 0))
71ptRender.set_color_map_mode(ptRender.ColorMapMode.PER_VERTEX_SHADER)
72
73fluid.state_velocity().connect(calculateNorm.in_vec())
74fluid.state_point_set().connect(ptRender.in_point_set())
75calculateNorm.out_norm().connect(colorMapper.in_scalar())
76colorMapper.out_color().connect(ptRender.in_color())
77
78fluid.graphics_pipeline().push_module(calculateNorm)
79fluid.graphics_pipeline().push_module(colorMapper)
80fluid.graphics_pipeline().push_module(ptRender)
81
82container = dyno.StaticBoundary3f()
83container.load_cube(dyno.Vector3f([0, 0, 0]), dyno.Vector3f([1.0, 1.0, 1.0]), 0.02, True)
84
85fluid.connect(container.import_particle_systems())
86
87scene.add_node(emitter)
88scene.add_node(fluid)
89scene.add_node(container)
90)====";
91
92 setText(source);
93}
94
95
97{
98 Wt::log("warning") << "WPythonWidget destory";
99}
100
101void WPythonWidget::setText(const std::string& text)
102{
103 // update code editor content
104 std::string ref = mCodeEditor->jsRef();
105 std::string command = ref + ".editor.setValue(`" + text + "`, 1);";
106 mCodeEditor->doJavaScript(command);
107 //mCodeEditor->refresh();
108}
109
110void WPythonWidget::execute(const std::string& src)
111{
112 bool flag = true;
113 py::scoped_interpreter guard{};
114
115 try {
116 auto locals = py::dict();
117 py::exec(src, py::globals(), locals);
118
119 if (locals.contains("scene"))
120 {
121 auto scene = locals["scene"].cast<std::shared_ptr<dyno::SceneGraph>>();
122 if (scene) mSignal.emit(scene);
123 }
124 else
125 {
126 Wt::WMessageBox::show("Error", "Please define 'scene = dyno.SceneGraph()'", Wt::StandardButton::Ok);
127 }
128 }
129 catch (const std::exception& e) {
130 Wt::WMessageBox::show("Error", e.what(), Wt::StandardButton::Ok);
131 flag = false;
132 }
133
134}
Wt::WText * mCodeEditor
Wt::Signal< std::shared_ptr< dyno::SceneGraph > > mSignal
void execute(const std::string &src)
void setText(const std::string &text)