├── .clang-format ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── Plama.pro ├── README.md ├── app ├── app.pro ├── data │ ├── project.cpp │ └── project.h ├── gui │ ├── plot.cpp │ ├── plot.h │ ├── windowmain.cpp │ └── windowmain.h ├── main.cpp ├── render │ ├── axis.cpp │ ├── axis.h │ ├── bar.cpp │ ├── bar.h │ ├── common.cpp │ ├── common.h │ ├── engine.cpp │ ├── engine.h │ ├── gradient.cpp │ ├── gradient.h │ ├── model.cpp │ └── model.h ├── res │ ├── icons │ │ ├── document-export.svg │ │ ├── document-open.svg │ │ ├── plama.svg │ │ ├── plot-gradient.svg │ │ ├── plot-shader.svg │ │ └── plot-step.svg │ ├── render │ │ ├── flat.fsh │ │ ├── flat.vsh │ │ ├── plain.fsh │ │ └── plain.vsh │ ├── res.qrc │ └── script │ │ └── plugins.py └── util │ ├── util.cpp │ └── util.h └── doc ├── Plama.ico ├── Report ├── fig │ ├── comp1.jpg │ ├── comp2.pdf │ ├── comp3.jpg │ ├── comp4.pdf │ ├── comp5.jpg │ ├── comp6.pdf │ ├── datamodule.pdf │ ├── datamodule.xml │ ├── datastruct.pdf │ ├── datastruct.xml │ ├── diagram1.pdf │ ├── diagram1.svg │ ├── diagram2.pdf │ ├── diagram2.svg │ ├── diagram3.pdf │ ├── diagram3.svg │ ├── dir.pdf │ ├── dir.svg │ ├── echarts.png │ ├── example1.pdf │ ├── example2.pdf │ ├── excel1.png │ ├── excel2.png │ ├── gantt.pdf │ ├── grid.pdf │ ├── grid.svg │ ├── index1.pdf │ ├── index2.pdf │ ├── interface.png │ ├── interp1.jpg │ ├── interp2.jpg │ ├── light1.jpg │ ├── light2.jpg │ ├── matlab0.pdf │ ├── matlab1.pdf │ ├── matlab2.pdf │ ├── matrix.pdf │ ├── matrix.svg │ ├── plasimo.png │ ├── sample1.pdf │ ├── sample1.svg │ ├── sample2.pdf │ ├── sample2.svg │ ├── sample3.pdf │ ├── sample3.svg │ ├── signature.png │ ├── toplevel.pdf │ ├── toplevel.xml │ ├── unit1.pdf │ ├── unit2.pdf │ ├── vec1.pdf │ └── vec2.pdf ├── final-report_juntong-liu_201219267.pdf ├── reference.bib ├── report.tex └── res │ ├── header.tex │ ├── myieee.bst │ ├── titlepage.tex │ └── univcrest.pdf ├── demo.7z ├── demo.png ├── dummy.py ├── logo.svg ├── plama.svg └── title.svg /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AlignAfterOpenBracket: DontAlign 3 | AlignConsecutiveAssignments: 'false' 4 | AlignConsecutiveDeclarations: 'false' 5 | AlignEscapedNewlinesLeft: 'false' 6 | AlignOperands: 'false' 7 | AlignTrailingComments: 'false' 8 | AllowShortCaseLabelsOnASingleLine: 'true' 9 | AllowShortFunctionsOnASingleLine: All 10 | AllowShortIfStatementsOnASingleLine: 'true' 11 | AllowShortLoopsOnASingleLine: 'true' 12 | AccessModifierOffset: -4 13 | ColumnLimit: 90 14 | IndentWidth: 4 15 | SpaceAfterTemplateKeyword: 'false' 16 | ... 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Plama.pro.user 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /Plama.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += app 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![title](doc/title.svg) 2 | 3 | This is Plama, a program for data visualization. It is designed to render the data in plasma simulation, but it should work well for different formats of data. 4 | 5 | Here is the main interface: 6 | 7 | ![demo](doc/demo.png) 8 | 9 | These are three main formats of rendering supported by this program as you can find in the screenshot. All the plots can be rotated and rendered in 3D space, toggling shader effect, and exported into jpg, svg and pdf images. The main advantage of this program is it has one variable dimension (the slider bar at the top), typically being the time, so you can easily check different quantities of one model at any time. For time-variant data, it can be also exported into videos. 10 | 11 | ## Why Use It 12 | 13 | The purpose of this project is to provide a universal interface and user-friendly workflow for basic visualization of most data formats. You can read, view and export data with several clicks. It also provides descent performance and rendering quality. 14 | 15 | So the typical usage is to load some formatted data. You need to install / write the plugin for this format, and enjoy. If you are a big fan of MATLAB or other similar tools, it might not be attractive at all. But to me, it provides better performance in rendering, simpler usage, optimized details and to be honest, the rendering style is closer to my taste. In addition, it uses python for data processing, which is more convenient for text and file processing, and it is more like the industrial standard in programming community. 16 | 17 | In one sentence, it is a light-weighted, free and flexible data visualizing tool. 18 | 19 | ## How to Use 20 | 21 | This program has built-in support for a plasma simulation file format called `MD2D`, so you can directly open projects in this format without any configuration. Simply choose open, and select all the output data, and the input model file, then it will handle all the things. 22 | 23 | If you do not have MD2D format data, [here](doc/demo.7z) is a simple example to help you run it an test most of the features. The data files are given in data folder and `pdp_demo.md2d` is the input model file. 24 | 25 | #### Installing the Plugin 26 | 27 | This program aims to provide zero-configuration experience for any data format, through a plugin system. When you have the plugin to process the data format, you only needs to click open, then select the files, easy. 28 | 29 | But you might have already thought about, you need to install the plugin first. A plugin is basically a python file. Simply throw it into the config folder , then the program will load it automatically if it runs. The config location is given below: 30 | 31 | - Linux: `/home/username/.config/Plama` 32 | - Windows: `C:/Users/username/AppData/Local/Plama` 33 | 34 | #### Write a Plugin 35 | 36 | This program implements possibly the easiest way to write plugins. For the description of plugin protocol, please find corresponding sections in the [full report](doc/Report/final-report_juntong-liu_201219267.pdf). 37 | 38 | ## How to Compile 39 | 40 | #### Linux 41 | 42 | First you need the dependencies (python3 please): 43 | 44 | `sudo pacman -S qt5-base qt5-svg python ffmpeg` 45 | 46 | Then the typical way for Qt projects: 47 | 48 | `qmake && make && make install` 49 | 50 | #### Windows 51 | 52 | Well, I don't suggest compile it yourself on Windows, not only because I use QtCreator to compile and run it on Windows, but also for the complicities of the dependencies. Why not use the released executable? By the way, I use mingw to compile it on Windows. 53 | 54 | #### OSX 55 | 56 | Not tested, not supported, have fun yourself. 57 | 58 | ## About the Project Name 59 | 60 | "Plama" sounds to be a strange name, and here is the reason. As stated before, the main purpose of this project is to display plasma properties, so it takes 5 letters from the word "plasma". And since I'm Chinese, and the animal "lama" has very popular jokes in Chinese (not so suitable for work), so it also provides 4 letters. In addition, "Plama" is a Polish word meaning stain, which is the logo of this project (No offense, Ubuntu!). And finally as a Linux user, here is the recursive abbreviation: Plama leaks all memory available! Just try not being a boring person. 61 | 62 | ## Credits 63 | 64 | - Project supervisor: Dr Mark Bowden 65 | - Project assessor: Dr James Walsh 66 | - Some icons from [Numix Project](https://github.com/numixproject) under GPLv3 67 | - [Qt5](https://www.qt.io/) under LGPLv3 68 | - [FFmpeg](https://www.ffmpeg.org/) under LGPLv3 69 | - [Python 3](https://www.python.org/) under PSF LICENSE 70 | -------------------------------------------------------------------------------- /app/app.pro: -------------------------------------------------------------------------------- 1 | QT += core gui widgets svg 2 | TARGET = Plama 3 | TEMPLATE = app 4 | 5 | CONFIG += no_keywords c++14 6 | 7 | SOURCES += \ 8 | main.cpp \ 9 | gui/windowmain.cpp \ 10 | render/engine.cpp \ 11 | render/model.cpp \ 12 | render/axis.cpp \ 13 | util/util.cpp \ 14 | gui/plot.cpp \ 15 | data/project.cpp \ 16 | render/bar.cpp \ 17 | render/gradient.cpp \ 18 | render/common.cpp 19 | 20 | HEADERS += \ 21 | gui/windowmain.h \ 22 | render/engine.h \ 23 | render/model.h \ 24 | render/axis.h \ 25 | util/util.h \ 26 | gui/plot.h \ 27 | data/project.h \ 28 | render/bar.h \ 29 | render/gradient.h \ 30 | render/common.h 31 | 32 | RESOURCES += \ 33 | res/res.qrc 34 | 35 | unix: LIBS += -lpython3.6m 36 | unix: INCLUDEPATH += /usr/include/python3.6m 37 | win32: LIBS += -L $$(PY_LIBS) -lpython36 38 | win32:INCLUDEPATH += -I $$(PY_INCLUDE) 39 | -------------------------------------------------------------------------------- /app/data/project.cpp: -------------------------------------------------------------------------------- 1 | #include "project.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | ProjectLoader::ProjectLoader() : globals(PyImport_AddModule("__main__")), list() { 14 | // read script 15 | QFile f(":script/plugins.py"); 16 | 17 | f.open(QFile::ReadOnly); 18 | QTextStream ts(&f); 19 | QString code = ts.readAll(); 20 | f.close(); 21 | QByteArray ba = code.toUtf8(); 22 | char *cmd = ba.data(); 23 | // config dir to PyObject 24 | QStringList dirs = 25 | QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation); 26 | PyObject *pDirs = PyList_New(0); 27 | for (QString s : dirs) 28 | PyList_Append(pDirs, PyUnicode_FromString(s.toLocal8Bit().data())); 29 | PyObject *args = Py_BuildValue("(O)", pDirs); 30 | // run python 31 | PyObject *rec; 32 | PyObject *variables = PyModule_GetDict(globals); 33 | rec = PyRun_String(cmd, Py_file_input, variables, variables); 34 | Py_DecRef(rec); 35 | PyObject *init = PyObject_GetAttrString(globals, "init"); 36 | PyObject *plugins = PyObject_CallObject(init, args); 37 | 38 | Py_DECREF(args); 39 | Py_DECREF(init); 40 | // PyObject to QStringList 41 | int len = PyObject_Length(plugins); 42 | QStringList ret; 43 | for (int i = 0; i < len; i++) { 44 | PyObject *name = PyList_GetItem(plugins, i); 45 | char *plugin = PyUnicode_AsUTF8(name); 46 | list << QString(plugin); 47 | } 48 | Py_DECREF(plugins); 49 | } 50 | 51 | const QStringList &ProjectLoader::plugins() const { return list; } 52 | 53 | std::unique_ptr ProjectLoader::load(QString name) const { 54 | PyObject *fArgs = PyObject_GetAttrString(globals, "args"); 55 | PyObject *fLoad = PyObject_GetAttrString(globals, "load"); 56 | PyObject *args = Py_BuildValue("(s)", name.toLocal8Bit().data()); 57 | PyObject *types = PyObject_CallObject(fArgs, args); 58 | Py_DECREF(args); 59 | int len = PyObject_Length(types); 60 | vector> typesConverted(len); 61 | for (int i = 0; i < len; i++) { 62 | PyObject *arg = PyList_GetItem(types, i); 63 | QString argName = QString(PyUnicode_AsUTF8(PyTuple_GetItem(arg, 0))); 64 | int argType = PyLong_AsLong(PyTuple_GetItem(arg, 1)); 65 | typesConverted[i] = {argName, argType}; 66 | } 67 | PyObject *pluginArgs = buildArgs(typesConverted); 68 | args = Py_BuildValue("(s, O)", name.toLocal8Bit().data(), pluginArgs); 69 | PyObject *data = PyObject_CallObject(fLoad, args); 70 | Py_DECREF(pluginArgs); 71 | Py_DECREF(args); 72 | Py_DECREF(types); 73 | return make_unique(data); 74 | } 75 | 76 | PyObject *ProjectLoader::buildArgs(const std::vector> &types) { 77 | PyObject *builder = PyList_New(0); 78 | for (auto &i : types) { 79 | switch (i.second) { 80 | case STRING_LIST: 81 | PyList_Append(builder, 82 | buildStringList(QFileDialog::getOpenFileNames(nullptr, i.first))); 83 | QApplication::processEvents(); 84 | break; 85 | default: Q_ASSERT(true); 86 | } 87 | } 88 | return builder; 89 | } 90 | 91 | PyObject *ProjectLoader::buildStringList(const QStringList &value) { 92 | PyObject *ret = PyList_New(0); 93 | for (const auto &i : value) 94 | PyList_Append(ret, PyUnicode_FromString(i.toLocal8Bit().data())); 95 | return ret; 96 | } 97 | 98 | Project::Project(PyObject *data) 99 | : nodes(), data(data, [](PyObject *o) { // 100 | Py_DECREF(o); 101 | }) { 102 | PyObject *value = PyTuple_GetItem(data, 0); 103 | PyObject *error = PyTuple_GetItem(data, 1); 104 | 105 | if (error == Py_None) { 106 | Py_ssize_t len = PyList_Size(value); 107 | for (Py_ssize_t i = 0; i < len; i++) nodes.emplace_back(PyList_GetItem(value, i)); 108 | } 109 | } 110 | 111 | QString Project::getError() const { 112 | PyObject *err = PyTuple_GetItem(data.get(), 1); 113 | return err == Py_None ? "" : QString(PyUnicode_AsUTF8(err)); 114 | } 115 | 116 | const vector &Project::getTopLevelNodes() const { return nodes; } 117 | 118 | SimTreeNode::SimTreeNode(PyObject *data) 119 | : raw(data), name(PyUnicode_AsUTF8(PyDict_GetItemString(data, "name"))), 120 | abbr(PyUnicode_AsUTF8(PyDict_GetItemString(data, "abbr"))), quantities(), 121 | children() { 122 | PyObject *pChildren = PyDict_GetItemString(data, "children"); 123 | PyObject *pQuantities = PyDict_GetItemString(data, "quantities"); 124 | Py_ssize_t len = PyList_Size(pChildren); 125 | 126 | for (Py_ssize_t i = 0; i < len; i++) 127 | children.emplace_back(PyList_GetItem(pChildren, i)); 128 | len = PyList_Size(pQuantities); 129 | for (Py_ssize_t i = 0; i < len; i++) 130 | quantities.emplace_back(PyList_GetItem(pQuantities, i)); 131 | } 132 | 133 | const QString &SimTreeNode::getName() const { return name; } 134 | const QString &SimTreeNode::getAbbr() const { return abbr; } 135 | const vector &SimTreeNode::getData() const { return quantities; } 136 | const vector &SimTreeNode::getChildren() const { return children; } 137 | 138 | SimQuantity::SimQuantity(PyObject *data) 139 | : raw(data), name(PyUnicode_AsUTF8(PyDict_GetItemString(data, "name"))), 140 | dimData(PyLong_AsLong(PyDict_GetItemString(data, "dimData"))), times(), sizeModel(), 141 | sizeData(), labels(), data(), max(0), min(0), initialized(false) { 142 | PyObject *pTimes = PyDict_GetItemString(data, "times"); 143 | PyObject *pSizeData = PyDict_GetItemString(data, "sizeData"); 144 | PyObject *pSizeModel = PyDict_GetItemString(data, "sizeModel"); 145 | PyObject *pLabels = PyDict_GetItemString(data, "labels"); 146 | Py_ssize_t len = PyList_Size(pTimes); 147 | 148 | for (Py_ssize_t i = 0; i < len; i++) 149 | times.push_back(PyFloat_AsDouble(PyList_GetItem(pTimes, i))); 150 | len = PyList_Size(pSizeModel); 151 | for (Py_ssize_t i = 0; i < len; i++) { 152 | PyObject *o = PyList_GetItem(pSizeModel, i); 153 | sizeModel.emplace_back(PyFloat_AsDouble(PyList_GetItem(o, 0)), 154 | PyFloat_AsDouble(PyList_GetItem(o, 1))); 155 | } 156 | 157 | len = PyList_Size(pSizeData); 158 | for (Py_ssize_t i = 0; i < len; i++) 159 | sizeData.push_back(PyLong_AsLong(PyList_GetItem(pSizeData, i))); 160 | 161 | for (Py_ssize_t i = 0; i < PyList_Size(pSizeData) + 2; i++) { 162 | labels.emplace_back(PyUnicode_AsUTF8(PyList_GetItem(pLabels, i))); 163 | } 164 | } 165 | 166 | const QString &SimQuantity::getName() const { return name; } 167 | const vector &SimQuantity::getTimes() const { return times; } 168 | const vector &SimQuantity::getSizeModel() const { return sizeModel; } 169 | const vector &SimQuantity::getSizeData() const { return sizeData; } 170 | 171 | const vector &SimQuantity::getDataAt(double time, int dim) { 172 | auto t = lower_bound(times.begin(), times.end(), time); 173 | int d = t - times.begin(); 174 | const vector &ret = getData()[dimData * d + dim]; 175 | return ret; 176 | } 177 | 178 | const vector> &SimQuantity::getData() { 179 | if (!initialized) initData(); 180 | return data; 181 | } 182 | 183 | const std::vector &SimQuantity::getLabels() const { return labels; } 184 | 185 | VectorD2D SimQuantity::getExtreme() { 186 | if (!initialized) initData(); 187 | return VectorD2D(min, max); 188 | } 189 | 190 | int SimQuantity::getDim() const { return dimData; } 191 | 192 | QString SimQuantity::getError() const { 193 | if (!initialized) return "Data not initialized"; 194 | return error; 195 | } 196 | 197 | QString SimQuantity::getError() { 198 | if (!initialized) initData(); 199 | return error; 200 | } 201 | 202 | void SimQuantity::initData() { 203 | 204 | PyObject *pDataFunc = PyDict_GetItemString(raw, "data"); 205 | PyObject *pDataRet = PyObject_CallObject(pDataFunc, NULL); 206 | PyObject *pData = PyTuple_GetItem(pDataRet, 0); 207 | PyObject *pErr = PyTuple_GetItem(pDataRet, 1); 208 | error = pErr == Py_None ? "" : QString(PyUnicode_AsUTF8(pErr)); 209 | initialized = true; 210 | 211 | if (!error.isEmpty()) return; 212 | 213 | Py_ssize_t lenI = PyList_Size(pData); 214 | for (Py_ssize_t i = 0; i < lenI; i++) { 215 | vector buf; 216 | PyObject *pBuf = PyList_GetItem(pData, i); 217 | Py_ssize_t lenJ = PyList_Size(pBuf); 218 | for (Py_ssize_t j = 0; j < lenJ; j++) 219 | buf.push_back(PyFloat_AsDouble(PyList_GetItem(pBuf, j))); 220 | data.push_back(buf); 221 | } 222 | 223 | if (dimData == 1) { 224 | max = data[0][0]; 225 | min = max; 226 | for (auto i : data) { 227 | for (auto j : i) { 228 | if (j > max) max = j; 229 | if (j < min) min = j; 230 | } 231 | } 232 | } else if (dimData == 2) { 233 | size_t sizeSection = data.size() / 2; 234 | size_t sizeNumber = 1; 235 | for (auto i : sizeData) sizeNumber *= i; 236 | 237 | max = magnitude(data[0][0], data[1][0]); 238 | min = 0; 239 | for (size_t i = 0; i < sizeSection; i++) { 240 | vector &vx = data[2 * i]; 241 | vector &vy = data[2 * i + 1]; 242 | for (size_t j = 0; j < sizeNumber; j++) { 243 | float x = vx[j]; 244 | float y = vy[j]; 245 | float m = magnitude(x, y); 246 | if (m > max) max = m; 247 | } 248 | } 249 | } 250 | 251 | Py_DECREF(pDataRet); 252 | } 253 | -------------------------------------------------------------------------------- /app/data/project.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_H 2 | #define PROJECT_H 3 | 4 | #include "util/util.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class SimTreeNode; 12 | 13 | class SimQuantity { 14 | public: 15 | SimQuantity(PyObject *data); 16 | const QString &getName() const; 17 | const std::vector &getTimes() const; 18 | const std::vector &getSizeModel() const; 19 | const std::vector &getSizeData() const; 20 | const std::vector &getDataAt(double time, int dim = 0); 21 | const std::vector> &getData(); 22 | const std::vector &getLabels() const; 23 | VectorD2D getExtreme(); 24 | int getDim() const; 25 | QString getError() const; 26 | QString getError(); 27 | 28 | private: 29 | PyObject *raw; 30 | QString name, error; 31 | int dimData; 32 | bool uniform; 33 | std::vector times; 34 | std::vector sizeModel; 35 | std::vector sizeData; 36 | std::vector labels; 37 | std::vector> data; 38 | float max, min; 39 | bool initialized; 40 | void initData(); 41 | }; 42 | 43 | class SimTreeNode { 44 | public: 45 | SimTreeNode(PyObject *data); 46 | SimTreeNode(SimTreeNode &&) = default; 47 | SimTreeNode &operator=(const SimTreeNode &) = delete; 48 | const QString &getName() const; 49 | const QString &getAbbr() const; 50 | const std::vector &getData() const; 51 | const std::vector &getChildren() const; 52 | 53 | private: 54 | PyObject *raw; 55 | QString name; 56 | QString abbr; 57 | std::vector quantities; 58 | std::vector children; 59 | }; 60 | 61 | class Project { 62 | public: 63 | Project(PyObject *data); 64 | QString getError() const; 65 | const std::vector &getTopLevelNodes() const; 66 | 67 | private: 68 | std::vector nodes; 69 | std::unique_ptr> data; 70 | }; 71 | 72 | class ProjectLoader { 73 | public: 74 | ProjectLoader(); 75 | const QStringList &plugins() const; 76 | std::unique_ptr load(QString name) const; 77 | 78 | private: 79 | const static int STRING_LIST = 1; 80 | PyObject *globals; 81 | QStringList list; 82 | static PyObject *buildArgs(const std::vector> &types); 83 | static PyObject *buildStringList(const QStringList &value); 84 | }; 85 | 86 | #endif // PROJECT_H 87 | -------------------------------------------------------------------------------- /app/gui/plot.cpp: -------------------------------------------------------------------------------- 1 | #include "plot.h" 2 | #include "render/bar.h" 3 | #include "render/model.h" 4 | #include "util/util.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | int mouseFuncForward(int x) { 27 | const int width = 20; 28 | const float slope = 0.5; 29 | if (x < width) 30 | return 0; 31 | else if (x < 90 / slope + width) 32 | return (x - width) * slope; 33 | else 34 | return 90; 35 | } 36 | 37 | int mouseFuncInverse(int x) { 38 | const int width = 20; 39 | const float slope = 0.5; 40 | if (x == 0) 41 | return 0; 42 | else if (x == 90) 43 | return 2 * width + 90 / slope; 44 | else 45 | return width + x / slope; 46 | } 47 | 48 | int mouseFuncForwardLoop(int x) { 49 | const int width = 20; 50 | const float slope = 0.5; 51 | const int radix = 2 * width + 90 / slope; 52 | QPair p = unify(x, radix); 53 | return p.first * 90 + mouseFuncForward(p.second); 54 | } 55 | 56 | int mouseFuncInverseLoop(int x) { 57 | const int width = 20; 58 | const float slope = 0.5; 59 | const int radix = 90; 60 | QPair p = unify(x, radix); 61 | return p.first * (2 * width + (int)(90 / slope)) + mouseFuncInverse(p.second); 62 | } 63 | 64 | void Plot::setTime(double t, bool update) { 65 | const vector × = quantity->getTimes(); 66 | double t1 = times[0]; 67 | double t2 = times[times.size() - 1]; 68 | if (plot->setQuantity(*quantity, t, step, update)) 69 | plot->setLabel((t - t1) / (t2 - t1), update); 70 | time = t; 71 | } 72 | 73 | Plot::Plot(SimQuantity &quantity) : time(quantity.getTimes()[0]), step(1) { 74 | static vector, function>> types = 75 | { 76 | {"JPEG image (*.jpg *.jpeg *.jpe)", {"jpg", "jpeg", "jpe"}, 77 | [](QString s, Plot &p) { 78 | QImage image(3000, 3000, QImage::Format_ARGB32); 79 | image.fill(Qt::white); 80 | p.plot->setEnLabel(false, false); 81 | p.plot->renderTo(image); 82 | p.plot->setEnLabel(true, false); 83 | QImage scaled = image.scaled( 84 | 1500, 1500, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 85 | scaled.save(s, "JPG", 100); 86 | }}, 87 | {"PNG image (*.png)", {"png"}, 88 | [](QString s, Plot &p) { 89 | QImage image(3000, 3000, QImage::Format_ARGB32); 90 | p.plot->setEnLabel(false, false); 91 | p.plot->renderTo(image); 92 | p.plot->setEnLabel(true, false); 93 | QImage scaled = image.scaled( 94 | 1500, 1500, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 95 | scaled.save(s, "PNG", 100); 96 | }}, 97 | {"SVG image (*.svg)", {"svg"}, 98 | [](QString s, Plot &p) { 99 | QSvgGenerator generator; 100 | generator.setFileName(s); 101 | generator.setSize(QSize(800, 800)); 102 | generator.setViewBox(QRect(0, 0, 800, 800)); 103 | p.plot->setEnLabel(false, false); 104 | p.plot->renderTo(generator); 105 | p.plot->setEnLabel(true, false); 106 | }}, 107 | {"PDF image (*.pdf)", {"pdf"}, 108 | [](QString s, Plot &p) { 109 | QPdfWriter writer(s); 110 | QSizeF size(100, 100); 111 | writer.setPageSizeMM(size); 112 | writer.setResolution(300); 113 | p.plot->setEnLabel(false, false); 114 | p.plot->renderTo(writer); 115 | p.plot->setEnLabel(true, false); 116 | }}, 117 | {"AVI video (*.avi)", {"avi"}, 118 | [](QString s, Plot &p) { p.renderVideo(s, 800, 800, 10, 20); }}, 119 | }; 120 | 121 | auto range = make_unique>(); 122 | auto labels = make_unique>(); 123 | if (quantity.getSizeModel().size() == 0) { 124 | *range = { 125 | {quantity.getTimes()[0], quantity.getTimes()[quantity.getTimes().size() - 1]}, 126 | quantity.getExtreme(), {0, 1}}; 127 | *labels = {quantity.getLabels()[0], quantity.getLabels()[1], ""}; 128 | } else { 129 | *range = {quantity.getSizeModel()[0], quantity.getSizeModel()[1], 130 | quantity.getExtreme()}; 131 | *labels = { 132 | quantity.getLabels()[2], quantity.getLabels()[3], quantity.getLabels()[1]}; 133 | } 134 | 135 | QVBoxLayout *l = new QVBoxLayout; 136 | l->setMargin(0); 137 | QToolBar *bar = new QToolBar; 138 | QSpinBox *nStep = new QSpinBox; 139 | nStep->setMinimum(1); 140 | nStep->setEnabled(false); 141 | QAction *aExport = new QAction(getIcon("document-export"), "Export"); 142 | QAction *aShader = new QAction(getIcon("plot-shader"), "Enable shader"); 143 | QAction *aBar = new QAction(getIcon("plot-gradient"), "Enable color bar"); 144 | QAction *aStep = new QAction(getIcon("plot-step"), "Set grid simplification"); 145 | aShader->setCheckable(true); 146 | aBar->setCheckable(true); 147 | aStep->setCheckable(true); 148 | connect(aExport, &QAction::triggered, [&]() { 149 | QString selected; 150 | QStringList filters; 151 | for (auto &i : types) filters << i.a; 152 | QString filter = filters.join(";;"); 153 | QString name = 154 | QFileDialog::getSaveFileName(this, "Export file", "", filter, &selected); 155 | if (name.isEmpty()) return; 156 | 157 | for (auto &i : types) { 158 | if (i.a == selected) { 159 | if (QFileInfo::exists(name)) 160 | i.c(name, *this); 161 | else { 162 | bool ext = false; 163 | for (auto &j : i.b) 164 | if (name.endsWith(j)) ext = true; 165 | if (!ext) name += "." + i.b[0]; 166 | i.c(name, *this); 167 | } 168 | } 169 | } 170 | }); 171 | connect(aShader, &QAction::toggled, [=](bool b) { plot->setShader(b); }); 172 | connect(aBar, &QAction::toggled, [=](bool b) { plot->setEnBar(b); }); 173 | connect(aStep, &QAction::toggled, [=](bool b) { 174 | nStep->setEnabled(b); 175 | if (b) 176 | this->setStep(nStep->value()); 177 | else 178 | this->setStep(1); 179 | }); 180 | connect(nStep, QOverload::of(&QSpinBox::valueChanged), 181 | [=](int v) { this->setStep(v); }); 182 | bar->addAction(aExport); 183 | bar->addAction(aShader); 184 | bar->addAction(aBar); 185 | bar->addAction(aStep); 186 | bar->addWidget(nStep); 187 | l->addWidget(bar); 188 | 189 | plot = new PlotInternal(make_unique(5, 5, 5), 190 | make_unique(Gradient::HEIGHT_MAP, 5), std::move(range), std::move(labels)); 191 | plot->setQuantity(quantity, quantity.getTimes()[0], step); 192 | l->addWidget(QWidget::createWindowContainer(plot)); 193 | l->setMargin(0); 194 | setLayout(l); 195 | this->quantity = &quantity; 196 | } 197 | 198 | void Plot::setRotation(int x, int y, bool update) { plot->setRotation(x, y, update); } 199 | 200 | void Plot::setPartition(float p, bool update) { 201 | const vector × = quantity->getTimes(); 202 | double t1 = times[0]; 203 | double t2 = times[times.size() - 1]; 204 | double td = t2 - t1; 205 | setTime(t1 + td * p, update); 206 | } 207 | 208 | void Plot::setStep(int s, bool update) { 209 | step = s; 210 | plot->setQuantity(*quantity, time, step, update); 211 | } 212 | 213 | QSize Plot::sizeHint() const { return QSize(1000, 1000); } 214 | QSize Plot::minimumSizeHint() const { return QSize(100, 100); } 215 | 216 | void Plot::renderVideo(QString dir, int sizeX, int sizeY, int len, int fps) { 217 | QProgressDialog *progress = new QProgressDialog(this); 218 | progress->setRange(0, 0); 219 | progress->setLabelText("Processing..."); 220 | progress->show(); 221 | 222 | QTemporaryDir *tmp = new QTemporaryDir(); 223 | int total = len * fps; 224 | float lenStep = 1.0 / total; 225 | int sizeName = QString::number(total).length(); 226 | QString format = "%1.jpg"; 227 | QString f1, f2; 228 | f2 = format.arg(int(0), sizeName, 10, QLatin1Char('0')); 229 | float t = time; 230 | for (int i = 0; i < total; i++) { 231 | f1 = f2; 232 | f2 = format.arg(int(i), sizeName, 10, QLatin1Char('0')); 233 | setPartition(i * lenStep, false); 234 | QImage image(sizeX * 2, sizeY * 2, QImage::Format_ARGB32); 235 | image.fill(Qt::white); 236 | QString filePath = tmp->filePath(f2); 237 | plot->renderTo(image); 238 | image.save(filePath, Q_NULLPTR, 100); 239 | QApplication::processEvents(); 240 | } 241 | setTime(t, false); 242 | 243 | QProcess *process = new QProcess(this); 244 | process->setWorkingDirectory(tmp->path()); 245 | connect(progress, &QProgressDialog::canceled, [=]() { process->kill(); }); 246 | connect(process, QOverload::of(&QProcess::finished), [=]() { 247 | delete tmp; 248 | progress->close(); 249 | }); 250 | QString cmd = "ffmpeg -y -r 10 -i %0" + QString::number(sizeName) + 251 | "d.jpg -c:v libx264 -crf 12 -s " + QString::number(sizeX) + "x" + 252 | QString::number(sizeY) + " " + dir; 253 | process->start(cmd); 254 | } 255 | 256 | PlotInternal::PlotInternal(unique_ptr &&axis, unique_ptr &&bar, 257 | unique_ptr> &&size, unique_ptr> &&labels) 258 | : model(new Model()) { 259 | shared_ptr pa = move(axis); 260 | shared_ptr> ps = move(size); 261 | shared_ptr pb = move(bar); 262 | shared_ptr> pl = move(labels); 263 | 264 | engineGL = make_unique(model, pa, pb, ps, pl); 265 | engineQt = make_unique(model, pa, pb, ps, pl); 266 | } 267 | 268 | void PlotInternal::setRotation(int x, int y, bool update) { 269 | engineGL->setRotation(x, y); 270 | engineQt->setRotation(x, y); 271 | if (update) requestUpdate(); 272 | } 273 | 274 | void PlotInternal::setLabel(float pos, bool update) { 275 | engineGL->setLine(pos); 276 | engineQt->setLine(pos); 277 | if (update) requestUpdate(); 278 | } 279 | 280 | void PlotInternal::setShader(bool en, bool update) { 281 | engineGL->setShader(en); 282 | engineQt->setShader(en); 283 | if (update) requestUpdate(); 284 | } 285 | 286 | void PlotInternal::setEnBar(bool en, bool update) { 287 | engineGL->setEnBar(en); 288 | engineQt->setEnBar(en); 289 | if (update) requestUpdate(); 290 | } 291 | 292 | void PlotInternal::setEnLabel(bool en, bool update) { 293 | engineGL->setEnLabel(en); 294 | engineQt->setEnLabel(en); 295 | if (update) requestUpdate(); 296 | } 297 | 298 | bool PlotInternal::setQuantity(SimQuantity &sq, float time, int step, bool update) { 299 | bool ret = model->setQuantity(sq, time, step); 300 | if (update) requestUpdate(); 301 | return ret; 302 | } 303 | 304 | void PlotInternal::renderTo(QPaintDevice &d) { 305 | QPainter p(&d); 306 | engineQt->resize(d.width(), d.height()); 307 | engineQt->render(p); 308 | p.end(); 309 | } 310 | 311 | void PlotInternal::mouseMoveEvent(QMouseEvent *event) { 312 | if ((event->buttons() & Qt::LeftButton) == 0) return; 313 | 314 | QPoint diff = event->pos() - mouse; 315 | int mx = mouseFuncInverseLoop(rotation.x()) + diff.x(); 316 | int my = mouseFuncInverseLoop(rotation.y()) + diff.y(); 317 | int ry = mouseFuncForwardLoop(my); 318 | if (ry > 90) 319 | ry = 90; 320 | else if (ry < 0) 321 | ry = 0; 322 | setRotation(unify(mouseFuncForwardLoop(mx), 360).second, ry); 323 | } 324 | 325 | void PlotInternal::mousePressEvent(QMouseEvent *event) { 326 | if ((event->buttons() & Qt::LeftButton) == 0) return; 327 | mouse = event->pos(); 328 | rotation = engineGL->getRotation(); 329 | } 330 | 331 | void PlotInternal::mouseReleaseEvent(QMouseEvent *) { setMouseGrabEnabled(false); } 332 | 333 | void PlotInternal::initializeGL() { engineGL->initialize(); } 334 | 335 | void PlotInternal::resizeGL(int w, int h) { 336 | engineGL->resize(w, h); 337 | engineQt->resize(w, h); 338 | requestUpdate(); 339 | } 340 | 341 | void PlotInternal::paintGL() { 342 | QPainter p(this); 343 | engineGL->render(p); 344 | } 345 | -------------------------------------------------------------------------------- /app/gui/plot.h: -------------------------------------------------------------------------------- 1 | #ifndef PLOT_H 2 | #define PLOT_H 3 | 4 | #include "data/project.h" 5 | #include "render/engine.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class PlotInternal : public QOpenGLWindow { 13 | public: 14 | PlotInternal(std::unique_ptr &&axis, std::unique_ptr &&bar, 15 | std::unique_ptr> &&size, 16 | std::unique_ptr> &&labels); 17 | void setRotation(int x, int y, bool update = true); 18 | void setLabel(float pos, bool update = true); 19 | void setShader(bool en, bool update = true); 20 | void setEnBar(bool en, bool update = true); 21 | void setEnLabel(bool en, bool update = true); 22 | bool setQuantity(SimQuantity &sq, float time, int step, bool update = true); 23 | void renderTo(QPaintDevice &d); 24 | 25 | private: 26 | std::shared_ptr model; 27 | std::unique_ptr engineGL; 28 | std::unique_ptr engineQt; 29 | QPoint mouse; 30 | QPoint rotation; 31 | 32 | protected: 33 | void mouseMoveEvent(QMouseEvent *) override; 34 | void mousePressEvent(QMouseEvent *) override; 35 | void mouseReleaseEvent(QMouseEvent *) override; 36 | void initializeGL() override; 37 | void resizeGL(int w, int h) override; 38 | void paintGL() override; 39 | }; 40 | 41 | class Plot : public QWidget { 42 | public: 43 | Plot(SimQuantity &quantity); 44 | void setRotation(int x, int y, bool update = true); 45 | void setTime(double t, bool update = true); 46 | void setPartition(float p, bool update = true); 47 | void setStep(int s, bool update = true); 48 | QSize sizeHint() const override; 49 | QSize minimumSizeHint() const override; 50 | 51 | private: 52 | PlotInternal *plot; 53 | SimQuantity *quantity; 54 | double time; 55 | int step; 56 | 57 | void renderVideo(QString dir, int sizeX, int sizeY, int len, int fps); 58 | }; 59 | 60 | #endif // PLOT_H 61 | -------------------------------------------------------------------------------- /app/gui/windowmain.cpp: -------------------------------------------------------------------------------- 1 | #include "windowmain.h" 2 | #include "data/project.h" 3 | #include "gui/plot.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | QTreeWidgetItem *generateTree(const SimTreeNode &n) { 21 | QTreeWidgetItem *ret = new QTreeWidgetItem(QStringList(n.getName())); 22 | 23 | ret->setData(0, 0x0101, QVariant::fromValue((void *)&n)); 24 | for (const SimTreeNode &i : n.getChildren()) ret->addChild(generateTree(i)); 25 | for (const SimQuantity &i : n.getData()) { 26 | QTreeWidgetItem *q = new QTreeWidgetItem(QStringList(i.getName())); 27 | q->setData(0, 0x0100, QVariant::fromValue((void *)&i)); 28 | ret->addChild(q); 29 | } 30 | return ret; 31 | } 32 | 33 | QList generateTree(const Project &a) { 34 | const vector &nodes = a.getTopLevelNodes(); 35 | 36 | QList ret; 37 | for (auto &i : nodes) ret.append(generateTree(i)); 38 | return ret; 39 | } 40 | 41 | WindowMain::WindowMain(QWidget *parent) : QMainWindow(parent), data() { 42 | static ProjectLoader m; 43 | static set activePlots; 44 | static set activeDocks; 45 | 46 | QToolBar *toolbar = new QToolBar("Hello"); 47 | QSlider *slider = new QSlider(Qt::Horizontal); 48 | slider->setMaximum(10000); 49 | slider->setMinimum(0); 50 | toolbar->addWidget(slider); 51 | 52 | addToolBar(toolbar); 53 | QWidget *empty = new QWidget(this); 54 | setCentralWidget(empty); 55 | resize(700, 500); 56 | 57 | setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | 58 | QMainWindow::AllowTabbedDocks); 59 | QDockWidget *dock = new QDockWidget("Data list", this); 60 | QTreeWidget *tree = new QTreeWidget(dock); 61 | dock->setWidget(tree); 62 | tree->header()->close(); 63 | dock->setAllowedAreas(Qt::LeftDockWidgetArea); 64 | dock->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 65 | addDockWidget(Qt::LeftDockWidgetArea, dock); 66 | 67 | connect(tree, &QTreeWidget::itemDoubleClicked, [=](QTreeWidgetItem *i) { 68 | QVariant q = i->data(0, 0x0100); 69 | if (q.isValid()) { 70 | QVariant p = i->parent()->data(0, 0x0101); 71 | SimTreeNode *sp = (SimTreeNode *)p.value(); 72 | SimQuantity *sq = (SimQuantity *)q.value(); 73 | vector size = sq->getSizeData(); 74 | 75 | if (sq->getError().isEmpty()) { 76 | QDockWidget *d = 77 | new QDockWidget(sp->getAbbr() + '>' + sq->getName(), this); 78 | d->setAttribute(Qt::WA_DeleteOnClose); 79 | Plot *plot = new Plot(*sq); 80 | plot->setRotation(90, 90); 81 | plot->setPartition(slider->value() / (float)10000); 82 | d->setWidget(plot); 83 | 84 | d->setAllowedAreas(Qt::LeftDockWidgetArea); 85 | addDockWidget(Qt::LeftDockWidgetArea, d); 86 | if (activePlots.size() == 0) 87 | splitDockWidget(dock, d, Qt::Horizontal); 88 | else { 89 | QDockWidget *dst = *activeDocks.begin(); 90 | QSize s = dst->size(); 91 | splitDockWidget( 92 | dst, d, s.width() > s.height() ? Qt::Horizontal : Qt::Vertical); 93 | } 94 | 95 | connect(d, &QDockWidget::visibilityChanged, [=](bool v) { 96 | if (v) { 97 | activeDocks.insert(d); 98 | activePlots.insert(plot); 99 | } else { 100 | activeDocks.erase(d); 101 | activePlots.erase(plot); 102 | if (activePlots.size() == 0) { 103 | QWidget *empty = new QWidget(this); 104 | setCentralWidget(empty); 105 | } 106 | } 107 | }); 108 | 109 | } else 110 | QMessageBox::warning(this, "Data Reading Error", sq->getError()); 111 | } 112 | }); 113 | 114 | connect(slider, &QSlider::sliderMoved, [](int i) { 115 | for (auto p : activePlots) p->setPartition(i / (float)10000); 116 | }); 117 | 118 | QMenu *mFile = menuBar()->addMenu("File"); 119 | QMenu *mFOpen = mFile->addMenu("Open"); 120 | for (QString i : m.plugins()) { 121 | QAction *a = new QAction(i, this); 122 | mFOpen->addAction(a); 123 | connect(a, &QAction::triggered, [=]() { 124 | unique_ptr tmp = m.load(i); 125 | if (tmp->getError().isEmpty()) { 126 | data = std::move(tmp); 127 | tree->clear(); 128 | tree->addTopLevelItems(generateTree(*data)); 129 | auto set = activeDocks; 130 | for (auto i : set) i->close(); 131 | } else 132 | QMessageBox::warning(this, "File Loading Error", tmp->getError()); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /app/gui/windowmain.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOWMAIN_H 2 | #define WINDOWMAIN_H 3 | 4 | #include "data/project.h" 5 | #include 6 | #include 7 | 8 | class WindowMain : public QMainWindow { 9 | Q_OBJECT 10 | 11 | public: 12 | explicit WindowMain(QWidget *parent = 0); 13 | ~WindowMain() = default; 14 | 15 | private: 16 | std::unique_ptr data; 17 | }; 18 | 19 | #endif // WINDOWMAIN_H 20 | -------------------------------------------------------------------------------- /app/main.cpp: -------------------------------------------------------------------------------- 1 | #include "gui/windowmain.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) { 11 | Py_Initialize(); 12 | 13 | int ret; 14 | { 15 | QSurfaceFormat format; 16 | 17 | format.setSamples(2); 18 | format.setSwapInterval(0); 19 | format.setDepthBufferSize(16); 20 | format.setRenderableType(QSurfaceFormat::OpenGL); 21 | QSurfaceFormat::setDefaultFormat(format); 22 | 23 | QApplication a(argc, argv); 24 | a.setWindowIcon(getIcon("plama")); 25 | if (QSysInfo::productType() == "windows") { 26 | QFont font("Segoe UI"); 27 | a.setFont(font); 28 | } 29 | 30 | WindowMain w(nullptr); 31 | w.show(); 32 | ret = a.exec(); 33 | } 34 | Py_Finalize(); 35 | return ret; 36 | } 37 | -------------------------------------------------------------------------------- /app/render/axis.cpp: -------------------------------------------------------------------------------- 1 | #include "axis.h" 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | Axis::Axis(int sizeX, int sizeY, int sizeZ) 8 | : point(12 * (sizeX + sizeY + sizeZ + 1)), color(12 * (sizeX + sizeY + sizeZ + 1)), 9 | index((sizeX + sizeY + sizeY + 3) * 16 + 12), sizeX(sizeX), sizeY(sizeY), 10 | sizeZ(sizeZ), offset(2 * OFFSET) { 11 | 12 | int countPnt = 0; 13 | int countIdx = 0; 14 | int tmp; 15 | 16 | for (int j = 0; j < 2; j++) { 17 | float diffX = 1.0f / sizeX; 18 | float diffY = 1.0f / sizeY; 19 | float diffZ = 1.0f / sizeZ; 20 | 21 | int xyStart = countPnt; 22 | for (int i = 0; i < sizeX; i++) { 23 | point[countPnt] = QVector3D(diffX * i, 0, -DIST); 24 | color[countPnt++] = GREY; 25 | } 26 | for (int i = 0; i < sizeY; i++) { 27 | point[countPnt] = QVector3D(1, diffY * i, -DIST); 28 | color[countPnt++] = GREY; 29 | } 30 | tmp = countPnt; 31 | for (int i = 0; i < sizeX; i++) { 32 | point[countPnt] = QVector3D(1 - diffX * i, 1, -DIST); 33 | color[countPnt++] = GREY; 34 | } 35 | for (int i = 0; i < sizeY; i++) { 36 | point[countPnt] = QVector3D(0, 1 - diffY * i, -DIST); 37 | color[countPnt++] = GREY; 38 | } 39 | color[tmp] = BLACK; 40 | 41 | int markXStrt = countPnt; 42 | for (int i = 0; i < sizeX + 1; i++) { 43 | point[countPnt] = QVector3D(diffX * i, 1 + EXTRA, -DIST); 44 | color[countPnt++] = BLACK; 45 | } 46 | int markXRight = countPnt; 47 | for (int i = 0; i < sizeX + 1; i++) { 48 | point[countPnt] = QVector3D(diffX * i, 1, -DIST - EXTRA); 49 | color[countPnt++] = BLACK; 50 | } 51 | int markYStrt = countPnt; 52 | for (int i = 0; i < sizeY + 1; i++) { 53 | point[countPnt] = QVector3D(1 + EXTRA, diffY * i, -DIST); 54 | color[countPnt++] = BLACK; 55 | } 56 | int markYRight = countPnt; 57 | for (int i = 0; i < sizeY + 1; i++) { 58 | point[countPnt] = QVector3D(1, diffY * i, -DIST - EXTRA); 59 | color[countPnt++] = BLACK; 60 | } 61 | 62 | int xzStart = countPnt; 63 | for (int i = 0; i < sizeX; i++) { 64 | point[countPnt] = QVector3D(diffX * i, -DIST, 0); 65 | color[countPnt++] = GREY; 66 | } 67 | for (int i = 0; i < sizeZ; i++) { 68 | point[countPnt] = QVector3D(1, -DIST, diffZ * i); 69 | color[countPnt++] = GREY; 70 | } 71 | tmp = countPnt; 72 | for (int i = 0; i < sizeX; i++) { 73 | point[countPnt] = QVector3D(1 - diffX * i, -DIST, 1); 74 | color[countPnt++] = GREY; 75 | } 76 | for (int i = 0; i < sizeZ; i++) { 77 | point[countPnt] = QVector3D(0, -DIST, 1 - diffZ * i); 78 | color[countPnt++] = GREY; 79 | } 80 | color[tmp] = BLACK; 81 | 82 | int markZStrt = countPnt; 83 | for (int i = 0; i < sizeZ + 1; i++) { 84 | point[countPnt] = QVector3D(1 + EXTRA, -DIST, diffZ * i); 85 | color[countPnt++] = BLACK; 86 | } 87 | int markZRight = countPnt; 88 | for (int i = 0; i < sizeZ + 1; i++) { 89 | point[countPnt] = QVector3D(1, -DIST - EXTRA, diffZ * i); 90 | color[countPnt++] = BLACK; 91 | } 92 | 93 | int yzStart = countPnt; 94 | for (int i = 0; i < sizeY; i++) { 95 | point[countPnt] = QVector3D(-DIST, diffY * i, 0); 96 | color[countPnt++] = GREY; 97 | } 98 | for (int i = 0; i < sizeZ; i++) { 99 | point[countPnt] = QVector3D(-DIST, 1, diffZ * i); 100 | color[countPnt++] = GREY; 101 | } 102 | for (int i = 0; i < sizeY; i++) { 103 | point[countPnt] = QVector3D(-DIST, 1 - diffY * i, 1); 104 | color[countPnt++] = GREY; 105 | } 106 | for (int i = 0; i < sizeZ; i++) { 107 | point[countPnt] = QVector3D(-DIST, 0, 1 - diffZ * i); 108 | color[countPnt++] = GREY; 109 | } 110 | 111 | offset[XY_X_B + j * OFFSET] = countIdx; 112 | index[countIdx++] = xyStart + 2 * sizeX + sizeY; 113 | index[countIdx++] = xyStart + sizeX + sizeY; 114 | offset[XY_X_G + j * OFFSET] = countIdx; 115 | tmp = countIdx; 116 | for (int i = 0; i < sizeY + 1; i++) { 117 | index[countIdx++] = xyStart + sizeX + i; 118 | index[countIdx++] = xyStart + 2 * sizeX + 2 * sizeY - i; 119 | } 120 | index[tmp + 1] = xyStart; 121 | offset[XY_Y_B + j * OFFSET] = countIdx; 122 | index[countIdx++] = xyStart + sizeX; 123 | index[countIdx++] = xyStart + sizeX + sizeY; 124 | offset[XY_Y_G + j * OFFSET] = countIdx; 125 | for (int i = 0; i < sizeX + 1; i++) { 126 | index[countIdx++] = xyStart + 2 * sizeX + sizeY - i; 127 | index[countIdx++] = xyStart + i; 128 | } 129 | 130 | offset[X_S + j * OFFSET] = countIdx; 131 | for (int i = 0; i < sizeX + 1; i++) { 132 | index[countIdx++] = xyStart + 2 * sizeX + sizeY - i; 133 | index[countIdx++] = markXStrt + i; 134 | } 135 | offset[X_R + j * OFFSET] = countIdx; 136 | for (int i = 0; i < sizeX + 1; i++) { 137 | index[countIdx++] = xyStart + 2 * sizeX + sizeY - i; 138 | index[countIdx++] = markXRight + i; 139 | } 140 | offset[Y_S + j * OFFSET] = countIdx; 141 | for (int i = 0; i < sizeY + 1; i++) { 142 | index[countIdx++] = xyStart + sizeX + i; 143 | index[countIdx++] = markYStrt + i; 144 | } 145 | offset[Y_R + j * OFFSET] = countIdx; 146 | for (int i = 0; i < sizeY + 1; i++) { 147 | index[countIdx++] = xyStart + sizeX + i; 148 | index[countIdx++] = markYRight + i; 149 | } 150 | 151 | offset[XZ + j * OFFSET] = countIdx; 152 | index[countIdx++] = xzStart + sizeX; 153 | index[countIdx++] = xzStart + sizeX + sizeZ; 154 | for (int i = 0; i < sizeX; i++) { 155 | index[countIdx++] = xzStart + 2 * sizeX + sizeZ - i; 156 | index[countIdx++] = xzStart + i; 157 | } 158 | tmp = countIdx; 159 | for (int i = 0; i < sizeZ + 1; i++) { 160 | index[countIdx++] = xzStart + sizeX + i; 161 | index[countIdx++] = xzStart + 2 * sizeX + 2 * sizeZ - i; 162 | } 163 | index[tmp + 1] = xzStart; 164 | 165 | offset[Z_S + j * OFFSET] = countIdx; 166 | for (int i = 0; i < sizeZ + 1; i++) { 167 | index[countIdx++] = xzStart + sizeX + i; 168 | index[countIdx++] = markZStrt + i; 169 | } 170 | offset[Z_R + j * OFFSET] = countIdx; 171 | for (int i = 0; i < sizeZ + 1; i++) { 172 | index[countIdx++] = xzStart + sizeX + i; 173 | index[countIdx++] = markZRight + i; 174 | } 175 | 176 | offset[YZ + j * OFFSET] = countIdx; 177 | tmp = countIdx; 178 | for (int i = 0; i < sizeZ + 1; i++) { 179 | index[countIdx++] = yzStart + sizeY + i; 180 | index[countIdx++] = yzStart + 2 * sizeY + 2 * sizeZ - i; 181 | } 182 | index[tmp + 1] = yzStart; 183 | for (int i = 0; i < sizeY + 1; i++) { 184 | index[countIdx++] = yzStart + 2 * sizeY + sizeZ - i; 185 | index[countIdx++] = yzStart + i; 186 | } 187 | 188 | tmp = sizeX; 189 | sizeX = sizeY; 190 | sizeY = tmp; 191 | } 192 | } 193 | 194 | const vector &Axis::getPoint() const { return point; } 195 | const vector &Axis::getColor() const { return color; } 196 | const vector &Axis::getIndex() const { return index; } 197 | 198 | vector> Axis::getSlice(int rotX, int rotY) { 199 | int rx = (360 - rotX) % 90; 200 | int dir = (360 - rotX) / 45 % 8; 201 | return getSlice(rx > 20 || rotY > 20, rx < 70 || rotY > 20, rotY<70, rx> 45, 202 | rotY > 20, dir % 4 > 1); 203 | } 204 | 205 | vector> Axis::getSlice( 206 | bool xEnable, bool yEnable, bool zEnable, bool zStrait, bool xyStrait, bool invert) { 207 | typedef QPair P; 208 | vector> ret; 209 | int i = invert ? OFFSET : 0; 210 | int x = invert ? sizeY : sizeX; 211 | int y = invert ? sizeX : sizeY; 212 | ret.push_back(P(offset[(xEnable ? XY_X_B : XY_X_G) + i], y + 1)); 213 | ret.push_back(P(offset[(yEnable ? XY_Y_B : XY_Y_G) + i], x + 1)); 214 | if (xEnable) ret.push_back(P(offset[(xyStrait ? X_S : X_R) + i], x + 1)); 215 | if (yEnable) ret.push_back(P(offset[(xyStrait ? Y_S : Y_R) + i], y + 1)); 216 | if (zEnable) ret.push_back(P(offset[XZ + i], x + sizeZ + 2)); 217 | if (zEnable) ret.push_back(P(offset[(zStrait ? Z_S : Z_R) + i], sizeZ + 1)); 218 | if (zEnable) ret.push_back(P(offset[YZ + i], sizeZ + y + 2)); 219 | return ret; 220 | } 221 | 222 | const vector>> &Axis::getNumber( 223 | int rotX, int rotY) const { 224 | int rx = (360 - rotX) % 90; 225 | int dir = (360 - rotX) / 45 % 8; 226 | return getNumber(dir, rx > 20 || rotY > 20, rx < 70 || rotY > 20, rotY<70, rx> 45, 227 | rotY > 20, rx == 0); 228 | } 229 | 230 | // position, base line dir, expand dir 231 | const vector &Axis::getLabel(int dir, bool xEnable, bool yEnable, 232 | bool zEnable, bool zStrait, bool xyStrait, bool front) const { 233 | static vector ret(3); 234 | float xy1 = xyStrait ? 1 + 2 * EXTRA : 1; 235 | float xy2 = xyStrait ? -DIST : -DIST - 2 * EXTRA; 236 | float z1 = zStrait ? 1 + 2 * EXTRA : 1; 237 | float z2 = zStrait ? -DIST : -DIST - 2 * EXTRA; 238 | int i1 = dir % 4 > 1 ? 1 : 0; 239 | int i2 = dir % 4 > 1 ? 0 : 1; 240 | 241 | if (zEnable) { 242 | ret[i1] = {xEnable ? (front ? PARALLEL : CENTER) : DISABLED, {0.5, xy1, xy2}, 243 | {1, 0, 0}, xyStrait ? QVector3D{0, 1, 0} : QVector3D{0, 1, -1}}; 244 | ret[i2] = {yEnable ? (front ? PARALLEL : CENTER) : DISABLED, {xy1, 0.5, xy2}, 245 | {0, 1, 0}, xyStrait ? QVector3D{1, 0, 0} : QVector3D{1, 0, -1}}; 246 | ret[2] = {zEnable ? PARALLEL : DISABLED, {z1, z2, 0.5}, {0, 0, 1}, 247 | zStrait ? QVector3D{1, 0, 0} : QVector3D{0, -1, 0}}; 248 | } else { 249 | ret[i1] = {xEnable ? PARALLEL : DISABLED, {0.5, xy1, xy2}, {1, 0, 0}, 250 | xyStrait ? QVector3D{0, 1, 0} : QVector3D{0, 1, -1}}; 251 | ret[i2] = {yEnable ? PARALLEL : DISABLED, {xy1, 0.5, xy2}, {0, 1, 0}, 252 | xyStrait ? QVector3D{1, 0, 0} : QVector3D{1, 0, -1}}; 253 | ret[2] = {DISABLED, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; 254 | } 255 | 256 | return ret; 257 | } 258 | 259 | const vector &Axis::getLabel(int rotX, int rotY) const { 260 | int rx = (360 - rotX) % 90; 261 | int dir = (360 - rotX) / 45 % 8; 262 | return getLabel(dir, rx > 20 || rotY > 20, rx < 70 || rotY > 20, rotY<70, rx> 45, 263 | rotY > 20, rx == 0); 264 | } 265 | 266 | bool Axis::getDir(int rotX, int rotY) const { 267 | (void)rotX; 268 | return rotY < 70; 269 | } 270 | 271 | QMatrix4x4 Axis::getTransform(int rotX, int rotY) const { 272 | return getTransform((360 - rotX) / 45 % 8, rotY >= 70); 273 | } 274 | 275 | QMatrix4x4 Axis::getTransform(int dir, bool flipX) const { 276 | QMatrix4x4 ret, tmp; 277 | ret.rotate(90 * (dir / 2), 0, 0, 1); 278 | if (flipX) tmp.data()[5] = -1; 279 | return ret * tmp; 280 | } 281 | 282 | const vector>> &Axis::getNumber(int dir, 283 | bool xEnable, bool yEnable, bool zEnable, bool zStrait, bool xyStrait, 284 | bool front) const { 285 | static vector>> ret(3); // true for right align 286 | for (int i = 0; i < 3; i++) ret[i].second.clear(); 287 | float diffX = 1.0f / sizeX; 288 | float diffY = 1.0f / sizeY; 289 | float diffZ = 1.0f / sizeZ; 290 | float xyEx = xyStrait ? 2 * EXTRA : 0; 291 | float zEx = xyStrait ? 0 : -2 * EXTRA; 292 | float xEx = zStrait ? 2 * EXTRA : 0; 293 | float yEx = -DIST + (zStrait ? 0 : -2 * EXTRA); 294 | 295 | int d = dir / 2; 296 | if (d == 0) { 297 | if (xEnable) 298 | for (int i = 0; i < sizeX + 1; i++) 299 | ret[0].second.push_back(QVector3D(diffX * i, 1 + xyEx, -DIST + zEx)); 300 | if (yEnable) { 301 | if (zEnable) 302 | for (int i = 0; i < sizeY + 1; i++) 303 | ret[1].second.push_back(QVector3D(1 + xyEx, diffY * i, -DIST + zEx)); 304 | else 305 | for (int i = 0; i < sizeY + 1; i++) 306 | ret[1].second.push_back( 307 | QVector3D(1 + xyEx, 1 - diffY * i, -DIST + zEx)); 308 | } 309 | ret[0].first = zEnable ? RIGHT : LEFT; 310 | ret[1].first = !front && xEnable ? LEFT : CENTER; 311 | } else if (d == 1) { 312 | if (xEnable) 313 | for (int i = 0; i < sizeY + 1; i++) 314 | ret[1].second.push_back(QVector3D(diffY * i, 1 + xyEx, -DIST + zEx)); 315 | if (yEnable) { 316 | if (zEnable) 317 | for (int i = 0; i < sizeX + 1; i++) 318 | ret[0].second.push_back( 319 | QVector3D(1 + xyEx, 1 - diffX * i, -DIST + zEx)); 320 | else 321 | for (int i = 0; i < sizeX + 1; i++) 322 | ret[0].second.push_back(QVector3D(1 + xyEx, diffX * i, -DIST + zEx)); 323 | } 324 | ret[0].first = !front && xEnable ? LEFT : CENTER; 325 | ret[1].first = zEnable ? RIGHT : LEFT; 326 | } else if (d == 2) { 327 | if (xEnable) 328 | for (int i = 0; i < sizeX + 1; i++) 329 | ret[0].second.push_back(QVector3D(1 - diffX * i, 1 + xyEx, -DIST + zEx)); 330 | if (yEnable) { 331 | if (zEnable) 332 | for (int i = 0; i < sizeY + 1; i++) 333 | ret[1].second.push_back( 334 | QVector3D(1 + xyEx, 1 - diffY * i, -DIST + zEx)); 335 | else 336 | for (int i = 0; i < sizeY + 1; i++) 337 | ret[1].second.push_back(QVector3D(1 + xyEx, diffY * i, -DIST + zEx)); 338 | } 339 | ret[0].first = zEnable ? RIGHT : LEFT; 340 | ret[1].first = !front && xEnable ? LEFT : CENTER; 341 | } else { 342 | if (xEnable) 343 | for (int i = 0; i < sizeY + 1; i++) 344 | ret[1].second.push_back(QVector3D(1 - diffY * i, 1 + xyEx, -DIST + zEx)); 345 | if (yEnable) { 346 | if (zEnable) 347 | for (int i = 0; i < sizeX + 1; i++) 348 | ret[0].second.push_back(QVector3D(1 + xyEx, diffX * i, -DIST + zEx)); 349 | else 350 | for (int i = 0; i < sizeX + 1; i++) 351 | ret[0].second.push_back( 352 | QVector3D(1 + xyEx, 1 - diffX * i, -DIST + zEx)); 353 | } 354 | ret[0].first = !front && xEnable ? LEFT : CENTER; 355 | ret[1].first = zEnable ? RIGHT : LEFT; 356 | } 357 | if (zEnable) 358 | for (int i = 0; i < sizeZ + 1; i++) 359 | ret[2].second.push_back(QVector3D(1 + xEx, yEx, diffZ * i)); 360 | ret[2].first = LEFT; 361 | 362 | return ret; 363 | } 364 | -------------------------------------------------------------------------------- /app/render/axis.h: -------------------------------------------------------------------------------- 1 | #ifndef AXIS_H 2 | #define AXIS_H 3 | 4 | #include "common.h" 5 | #include "util/util.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class Axis { 13 | public: 14 | Axis(int sizeX, int sizeY, int sizeZ); 15 | const std::vector &getPoint() const; 16 | const std::vector &getColor() const; 17 | const std::vector &getIndex() const; 18 | std::vector> getSlice(int rotX, int rotY); 19 | std::vector> getSlice(bool xEnable, bool yEnable, bool zEnable, 20 | bool zStrait, bool xyStrait, bool invert); 21 | const std::vector>> &getNumber(int dir, 22 | bool xEnable, bool yEnable, bool zEnable, bool zStrait, bool xyStrait, 23 | bool front) const; 24 | const std::vector>> &getNumber( 25 | int rotX, int rotY) const; 26 | const std::vector &getLabel(int dir, bool xEnable, bool yEnable, 27 | bool zEnable, bool zStrait, bool xyStrait, bool front) const; 28 | const std::vector &getLabel(int rotX, int rotY) const; 29 | bool getDir(int rotX, int rotY) const; 30 | 31 | QMatrix4x4 getTransform(int rotX, int rotY) const; 32 | QMatrix4x4 getTransform(int dir, bool flipX) const; 33 | 34 | private: 35 | std::vector point; 36 | std::vector color; 37 | std::vector index; 38 | int sizeX, sizeY, sizeZ; 39 | std::vector offset; 40 | static constexpr float DIST = 0.07f; 41 | static constexpr float EXTRA = 0.04f; 42 | static constexpr float LABEL = 0.5f; 43 | static constexpr QVector3D BLACK = QVector3D(0.4, 0.4, 0.4); 44 | static constexpr QVector3D GREY = QVector3D(0.8, 0.8, 0.8); 45 | static const int XY_X_B = 0; 46 | static const int XY_X_G = 1; 47 | static const int XY_Y_B = 2; 48 | static const int XY_Y_G = 3; 49 | static const int XZ = 4; 50 | static const int YZ = 5; 51 | static const int X_S = 6; 52 | static const int X_R = 7; 53 | static const int Y_S = 8; 54 | static const int Y_R = 9; 55 | static const int Z_S = 10; 56 | static const int Z_R = 11; 57 | static const int OFFSET = 12; 58 | }; 59 | 60 | #endif // AXIS_H 61 | -------------------------------------------------------------------------------- /app/render/bar.cpp: -------------------------------------------------------------------------------- 1 | #include "bar.h" 2 | #include "util/util.h" 3 | 4 | const float Bar::DIFF = -0.00001; 5 | const QVector3D Bar::BLACK = QVector3D(0.4, 0.4, 0.4); 6 | 7 | Bar::Bar(const Gradient &gradient, int steps) 8 | : point(104 + 2 * steps), index(310 + 2 * steps), color(104 + 2 * steps), 9 | number(steps + 1), pos{PARALLEL, {1.3, 0.5, 0}, {0, 1, 0}, {1, 0, 0}}, 10 | steps(steps) { 11 | int count = 0; 12 | float step = 1.0 / 50; 13 | for (int j = 0; j < 2; j++) { 14 | for (int i = 0; i < 51; i++) { 15 | point[count] = QVector3D(j, i * step, 0); 16 | color[count] = gradient.getColor(step / 2 + i * step); 17 | count++; 18 | } 19 | } 20 | for (int j = 0; j < 2; j++) { 21 | for (int i = 0; i < 2; i++) { 22 | point[count] = QVector3D(j, i, DIFF); 23 | color[count++] = BLACK; 24 | } 25 | } 26 | step = 1.0 / steps; 27 | for (int i = 1; i < steps; i++) { 28 | for (int j = 0; j < 2; j++) { 29 | point[count] = QVector3D(0.8 + 0.2 * j, i * step, DIFF); 30 | color[count++] = BLACK; 31 | } 32 | } 33 | count = 0; 34 | for (int i = 0; i < 50; i++) { 35 | index[count++] = 52 + i; 36 | index[count++] = 1 + i; 37 | index[count++] = i; 38 | index[count++] = 52 + i; 39 | index[count++] = i; 40 | index[count++] = 51 + i; 41 | } 42 | index[count++] = 102; 43 | index[count++] = 103; 44 | index[count++] = 103; 45 | index[count++] = 105; 46 | index[count++] = 105; 47 | index[count++] = 104; 48 | index[count++] = 104; 49 | index[count++] = 102; 50 | for (int i = 0; i < steps - 1; i++) { 51 | index[count++] = 106 + 2 * i; 52 | index[count++] = 107 + 2 * i; 53 | } 54 | 55 | for (int i = 0; i < steps + 1; i++) { 56 | number[i] = QVector3D(1.3, i * step, 0); 57 | } 58 | } 59 | 60 | const std::vector &Bar::getPoint() const { return point; } 61 | const std::vector &Bar::getColor() const { return color; } 62 | const std::vector &Bar::getIndex() const { return index; } 63 | const std::vector &Bar::getNumber() const { return number; } 64 | const PositionInfo &Bar::getLabel() const { return pos; } 65 | QPair Bar::getSliceL() const { return QPair(300, steps + 3); } 66 | QPair Bar::getSliceT() const { return QPair(0, 100); } 67 | -------------------------------------------------------------------------------- /app/render/bar.h: -------------------------------------------------------------------------------- 1 | #ifndef BAR_H 2 | #define BAR_H 3 | 4 | #include "common.h" 5 | #include "render/gradient.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class Bar { 14 | public: 15 | Bar(const Gradient &gradient, int steps); 16 | const std::vector &getPoint() const; 17 | const std::vector &getColor() const; 18 | const std::vector &getIndex() const; 19 | const std::vector &getNumber() const; 20 | const PositionInfo &getLabel() const; 21 | QPair getSliceL() const; 22 | QPair getSliceT() const; 23 | 24 | private: 25 | std::vector point; 26 | std::vector index; 27 | std::vector color; 28 | std::vector number; 29 | PositionInfo pos; 30 | int steps; 31 | static const float DIFF; 32 | static const QVector3D BLACK; 33 | }; 34 | 35 | #endif // BAR_H 36 | -------------------------------------------------------------------------------- /app/render/common.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | -------------------------------------------------------------------------------- /app/render/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | #include 4 | 5 | enum EnumPosition { LEFT, RIGHT, CENTER, PARALLEL, DISABLED }; 6 | 7 | struct PositionInfo { 8 | EnumPosition align; 9 | QVector3D base; 10 | QVector3D line; 11 | QVector3D expand; 12 | }; 13 | 14 | #endif // COMMON_H 15 | -------------------------------------------------------------------------------- /app/render/engine.h: -------------------------------------------------------------------------------- 1 | #ifndef ENGINE_H 2 | #define ENGINE_H 3 | 4 | #include "render/axis.h" 5 | #include "render/bar.h" 6 | #include "render/model.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | class Engine { 16 | public: 17 | Engine(std::shared_ptr &model, std::shared_ptr &axis, 18 | std::shared_ptr &bar, std::shared_ptr> &size, 19 | std::shared_ptr> &labels); 20 | virtual ~Engine() = default; 21 | virtual void initialize() = 0; 22 | virtual void render(QPainter &p) = 0; 23 | virtual void resize(int sizeX, int sizeY); 24 | QPoint getRotation(); 25 | void setModel(std::shared_ptr &model); 26 | void setRotation(int rotX, int rotY); 27 | void setLine(float pos); 28 | void setShader(bool en); 29 | void setEnBar(bool en); 30 | void setEnLabel(bool en); 31 | 32 | protected: 33 | int rotX, rotY; 34 | int sizeX, sizeY; 35 | std::shared_ptr model; 36 | std::shared_ptr axis; 37 | std::shared_ptr bar; 38 | std::shared_ptr> size; 39 | std::shared_ptr> labels; 40 | float line; 41 | bool enShader, enBar, enLine; 42 | }; 43 | 44 | class EngineGL : public Engine, protected QOpenGLFunctions { 45 | public: 46 | EngineGL(std::shared_ptr &model, std::shared_ptr &axis, 47 | std::shared_ptr &bar, std::shared_ptr> &size, 48 | std::shared_ptr> &labels); 49 | void initialize() override; 50 | void render(QPainter &p) override; 51 | 52 | private: 53 | int argFlatVecPos; 54 | int argFlatVecPnt; 55 | int argFlatVecNormal; 56 | int argFlatVecColor; 57 | int argFlatVecView; 58 | int argFlatVecLight; 59 | int argFlatMatTrans; 60 | int argFlatMatModel; 61 | int argFlatMatNormal; 62 | 63 | int argPlainVecPnt; 64 | int argPlainVecColor; 65 | int argPlainMatModel; 66 | int argPlainMatTrans; 67 | 68 | std::unique_ptr programFlat; 69 | std::unique_ptr programPlain; 70 | }; 71 | 72 | class EngineQt : public Engine { 73 | public: 74 | EngineQt(std::shared_ptr &model, std::shared_ptr &axis, 75 | std::shared_ptr &bar, std::shared_ptr> size, 76 | std::shared_ptr> &labels); 77 | void initialize() override{}; 78 | void render(QPainter &p) override; 79 | void render(QPaintDevice &p); 80 | }; 81 | 82 | #endif // ENGINE_H 83 | -------------------------------------------------------------------------------- /app/render/gradient.cpp: -------------------------------------------------------------------------------- 1 | #include "gradient.h" 2 | #include "util/util.h" 3 | #include 4 | 5 | using namespace std; 6 | 7 | Gradient Gradient::HEIGHT_MAP( 8 | {// 9 | {Qt::blue, 0.0}, {Qt::cyan, 0.2f}, {Qt::green, 0.4f}, {Qt::yellow, 0.6f}, 10 | {Qt::red, 0.8f}, {Qt::darkRed, 1.0f}}, 11 | 200); 12 | 13 | Gradient::Gradient(const vector> &data, int steps) 14 | : cache(steps), step(1.0f / steps) { 15 | QVector3D c1 = toV3D(data[0].first); 16 | QVector3D c2 = c1; 17 | float p1 = 0; 18 | float p2 = 0; 19 | int cnt = 0; 20 | for (auto i : data) { 21 | c1 = c2; 22 | p1 = p2; 23 | c2 = toV3D(i.first); 24 | p2 = i.second; 25 | for (float pos = cnt * step; pos < p2 && cnt < steps; cnt++, pos = cnt * step) 26 | cache[cnt] = (c1 * (p2 - pos) + c2 * (pos - p1)) / (p2 - p1); 27 | } 28 | } 29 | 30 | const QVector3D &Gradient::getColor(float pos) const { 31 | int index = pos / step; 32 | int size = cache.size(); 33 | return cache[index >= size ? size - 1 : index]; 34 | } 35 | -------------------------------------------------------------------------------- /app/render/gradient.h: -------------------------------------------------------------------------------- 1 | #ifndef GRADIENT_H 2 | #define GRADIENT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Gradient { 10 | public: 11 | Gradient(const std::vector> &data, int steps = 50); 12 | const QVector3D &getColor(float pos) const; 13 | 14 | static Gradient HEIGHT_MAP; 15 | 16 | private: 17 | std::vector cache; 18 | float step; 19 | }; 20 | 21 | #endif // GRADIENT_H 22 | -------------------------------------------------------------------------------- /app/render/model.cpp: -------------------------------------------------------------------------------- 1 | #include "render/model.h" 2 | #include "util/util.h" 3 | #include 4 | 5 | using namespace std; 6 | 7 | function &, int, int)> f0 = // 8 | [](function &f, int x, int y) { 9 | for (int i = 0; i < x; i++) 10 | for (int j = 0; j < y; j++) f(j * x + i); 11 | }; 12 | 13 | function &, int, int)> f1 = // 14 | [](function &f, int x, int y) { 15 | for (int i = x - 1; i >= 0; i--) 16 | for (int j = 0; j < y; j++) f(j * x + i); 17 | }; 18 | 19 | function &, int, int)> f2 = // 20 | [](function &f, int x, int y) { 21 | for (int i = 0; i < x; i++) 22 | for (int j = y - 1; j >= 0; j--) f(j * x + i); 23 | }; 24 | 25 | function &, int, int)> f3 = // 26 | [](function &f, int x, int y) { 27 | for (int i = x - 1; i >= 0; i--) 28 | for (int j = y - 1; j >= 0; j--) f(j * x + i); 29 | }; 30 | 31 | vector &, int, int)>> Model::indexFunc{ 32 | f0, f0, f1, f1, f3, f3, f2, f2}; 33 | 34 | Model::Model() : indexT(8, vector()), indexL(8, vector()) {} 35 | const vector &Model::getIndexT(int dir) const { return indexT[dir]; } 36 | const vector &Model::getIndexL(int dir) const { return indexL[dir]; } 37 | const vector &Model::getPoint() const { return point; } 38 | const vector &Model::getNormal() const { return normal; } 39 | const vector &Model::getColor() const { return color; } 40 | const vector &Model::getPosition() const { return position; } 41 | 42 | bool Model::setQuantity(SimQuantity &sq, float time, int step) { 43 | VectorD2D extreme = sq.getExtreme(); 44 | const vector &size = sq.getSizeModel(); 45 | auto dataAt = [&](int dim = 0) { 46 | return Sampler::gen(sq.getDataAt(time, dim), step, sq.getSizeData()[0]); 47 | }; 48 | auto data = [&](const auto &d) { return Sampler::gen(d, step); }; 49 | double ratio = sq.getSizeData().size() == 2 50 | ? (size[0].second - size[0].first) / (size[1].second - size[1].first) 51 | : 0; 52 | 53 | switch (sq.getSizeData().size()) { 54 | case 0: genLine(data(sq.getTimes()), data(sq.getData()), extreme); return true; 55 | case 2: 56 | switch (sq.getDim()) { 57 | case 1: genHeight(dataAt(), extreme); return false; 58 | case 2: genVector(dataAt(0), dataAt(1), extreme, ratio); return false; 59 | } 60 | break; 61 | } 62 | return false; 63 | } 64 | 65 | void Model::genLine(DATA x, DATA y, VectorD2D extreme) { 66 | if (checkSame(LINE, {x, y})) return; // TODO 67 | checkSize(x->sizeXI(), 0, (x->sizeXI() - 1) * 2); 68 | float xMin = x->get(0); 69 | float xMax = x->get(-1); 70 | float xDiff = xMax - xMin; 71 | double yMin = extreme.first; 72 | double yMax = extreme.second; 73 | double yDiff = yMax - yMin; 74 | 75 | if (yDiff == 0) { 76 | if (yMin == 0) { 77 | yMin = -1; 78 | yDiff = 2; 79 | } else { 80 | yMin *= 0.9; 81 | yMax *= 1.1; 82 | yDiff = yMax - yMin; 83 | } 84 | } 85 | 86 | for (int i = 0; i < x->sizeXI(); i++) { 87 | point[i] = QVector3D((x->get(i) - xMin) / xDiff, (y->get(i) - yMin) / yDiff, 0); 88 | normal[i] = QVector3D(0, 0, 1); 89 | color[i] = QVector3D(0, 0, 1); 90 | position[i] = point[i]; 91 | } 92 | 93 | for (int j = 0; j < 8; j++) { 94 | for (int i = 0; i < x->sizeXI() - 1; i++) { 95 | indexL[j][2 * i] = i; 96 | indexL[j][2 * i + 1] = i + 1; 97 | } 98 | } 99 | } 100 | 101 | void Model::genHeight(DATA data, VectorD2D extreme) { 102 | if (checkSame(HEIGHT, {data})) return; 103 | int sxi = data->sizeXI(); 104 | int syi = data->sizeYI(); 105 | float sxf = data->sizeXF(); 106 | float syf = data->sizeYF(); 107 | checkSize((sxi - 1) * (syi - 1) * 9, (sxi - 1) * (syi - 1) * 24, 0); 108 | 109 | static vector> order{ 110 | {0, 4, 3, 1, 4, 0, 3, 4, 6, 6, 4, 7, 2, 4, 1, 5, 4, 2, 7, 4, 8, 8, 4, 5}, 111 | {1, 4, 0, 0, 4, 3, 3, 4, 6, 6, 4, 7, 2, 4, 1, 5, 4, 2, 8, 4, 5, 7, 4, 8}, 112 | {2, 4, 1, 5, 4, 2, 1, 4, 0, 0, 4, 3, 8, 4, 5, 7, 4, 8, 3, 4, 6, 6, 4, 7}, 113 | {5, 4, 2, 2, 4, 1, 1, 4, 0, 0, 4, 3, 8, 4, 5, 7, 4, 8, 6, 4, 7, 3, 4, 6}, 114 | {8, 4, 5, 7, 4, 8, 5, 4, 2, 2, 4, 1, 6, 4, 7, 3, 4, 6, 1, 4, 0, 0, 4, 3}, 115 | {7, 4, 8, 8, 4, 5, 5, 4, 2, 2, 4, 1, 6, 4, 7, 3, 4, 6, 0, 4, 3, 1, 4, 0}, 116 | {6, 4, 7, 3, 4, 6, 7, 4, 8, 8, 4, 5, 0, 4, 3, 1, 4, 0, 5, 4, 2, 2, 4, 1}, 117 | {3, 4, 6, 6, 4, 7, 7, 4, 8, 8, 4, 5, 0, 4, 3, 1, 4, 0, 2, 4, 1, 5, 4, 2}}; 118 | 119 | float height = extreme.second - extreme.first; 120 | float offsetX = data->offsetX(); 121 | float offsetY = data->offsetY(); 122 | for (int y = 0; y < syi - 1; y++) { 123 | for (int x = 0; x < sxi - 1; x++) { 124 | double d[9]; 125 | float px[3]; 126 | float py[3]; 127 | QVector3D p[9]; 128 | 129 | int offsetPoint = (y * (sxi - 1) + x) * 9; 130 | 131 | if (height == 0) { 132 | for (int i = 0; i < 9; i++) d[i] = data->get(0); 133 | } else { 134 | d[0] = data->get(x, y); 135 | d[2] = data->get(x + 1, y); 136 | d[6] = data->get(x, y + 1); 137 | d[8] = data->get(x + 1, y + 1); 138 | d[0] = (d[0] - extreme.first) / height; 139 | d[2] = (d[2] - extreme.first) / height; 140 | d[6] = (d[6] - extreme.first) / height; 141 | d[8] = (d[8] - extreme.first) / height; 142 | d[1] = (d[0] + d[2]) / 2; 143 | d[3] = (d[0] + d[6]) / 2; 144 | d[5] = (d[2] + d[8]) / 2; 145 | d[7] = (d[6] + d[8]) / 2; 146 | d[4] = (d[3] + d[5]) / 2; 147 | } 148 | 149 | for (int i = 0; i < 3; i++) { 150 | px[i] = (x + 0.5f * i + offsetX) / sxf; 151 | py[i] = (y + 0.5f * i + offsetY) / syf; 152 | } 153 | 154 | for (int yy = 0; yy < 3; yy++) { 155 | for (int xx = 0; xx < 3; xx++) { 156 | int i = yy * 3 + xx; 157 | p[i] = QVector3D(px[xx], py[yy], d[i]); 158 | } 159 | } 160 | 161 | for (int i = 0; i < 9; i++) point[offsetPoint + i] = p[i]; 162 | 163 | normal[offsetPoint] = QVector3D::crossProduct(p[1] - p[0], p[4] - p[0]); 164 | normal[offsetPoint + 1] = QVector3D::crossProduct(p[2] - p[1], p[4] - p[1]); 165 | normal[offsetPoint + 2] = QVector3D::crossProduct(p[5] - p[2], p[4] - p[2]); 166 | normal[offsetPoint + 3] = QVector3D::crossProduct(p[0] - p[3], p[4] - p[3]); 167 | normal[offsetPoint + 4] = QVector3D(1, 1, 1); 168 | normal[offsetPoint + 5] = QVector3D::crossProduct(p[8] - p[5], p[4] - p[5]); 169 | normal[offsetPoint + 6] = QVector3D::crossProduct(p[3] - p[6], p[4] - p[6]); 170 | normal[offsetPoint + 7] = QVector3D::crossProduct(p[6] - p[7], p[4] - p[7]); 171 | normal[offsetPoint + 8] = QVector3D::crossProduct(p[7] - p[8], p[4] - p[8]); 172 | 173 | color[offsetPoint] = Gradient::HEIGHT_MAP.getColor(d[0]); 174 | color[offsetPoint + 3] = color[offsetPoint]; 175 | color[offsetPoint + 1] = Gradient::HEIGHT_MAP.getColor(d[2]); 176 | color[offsetPoint + 2] = color[offsetPoint + 1]; 177 | color[offsetPoint + 5] = Gradient::HEIGHT_MAP.getColor(d[8]); 178 | color[offsetPoint + 8] = color[offsetPoint + 5]; 179 | color[offsetPoint + 7] = Gradient::HEIGHT_MAP.getColor(d[6]); 180 | color[offsetPoint + 6] = color[offsetPoint + 7]; 181 | color[offsetPoint + 4] = Gradient::HEIGHT_MAP.getColor(0); 182 | 183 | position[offsetPoint] = (p[0] + p[1] + p[4]) / 3; 184 | position[offsetPoint + 1] = (p[1] + p[2] + p[4]) / 3; 185 | position[offsetPoint + 2] = (p[2] + p[5] + p[4]) / 3; 186 | position[offsetPoint + 3] = (p[0] + p[3] + p[4]) / 3; 187 | position[offsetPoint + 4] = p[4]; 188 | position[offsetPoint + 5] = (p[5] + p[8] + p[4]) / 3; 189 | position[offsetPoint + 6] = (p[6] + p[3] + p[4]) / 3; 190 | position[offsetPoint + 7] = (p[6] + p[7] + p[4]) / 3; 191 | position[offsetPoint + 8] = (p[7] + p[8] + p[4]) / 3; 192 | } 193 | } 194 | 195 | for (int i = 0; i < 8; i++) { 196 | int cnt = 0; 197 | function func = [&](int j) { 198 | int offsetPoint = j * 9; 199 | for (int j = 0; j < 24; j++) indexT[i][cnt++] = order[i][j] + offsetPoint; 200 | }; 201 | indexFunc[i](func, sxi - 1, syi - 1); 202 | } 203 | } 204 | 205 | void Model::genVector( 206 | Model::DATA dataX, Model::DATA dataY, VectorD2D extreme, float ratio) { 207 | static vector> polar; 208 | static float angle1 = PI * 13 / 12; 209 | static float angle2 = PI * 11 / 12; 210 | static vector bufY; 211 | 212 | int sizeX = dataX->sizeXI(); 213 | int sizeY = dataX->sizeYI(); 214 | int sizeT = sizeX * sizeY; 215 | 216 | if (checkSame(VECTOR, {dataX, dataY})) return; // TODO 217 | checkSize(sizeX * sizeY * 5, sizeX * sizeY * 3, sizeX * sizeY * 2); 218 | polar.resize(sizeT); 219 | bufY.resize(sizeT); 220 | const DATA &convX = dataX; 221 | DATA convY = Sampler::gen(bufY, 1, sizeX); 222 | for (int i = 0; i < sizeT; i++) bufY[i] = dataY->get(i) * ratio; 223 | 224 | double maxActual = extreme.second; 225 | double maxScaled = maxActual * (ratio > 1 ? ratio : 1 / ratio); 226 | 227 | VectorD2D pnt; 228 | for (int i = 0; i < sizeT; i++) { 229 | toPolar(convX->get(i), convY->get(i), pnt); 230 | QPair &pair = polar[i]; 231 | pair.first = pnt; 232 | pair.second = magnitude(dataX->get(i), dataY->get(i)); 233 | } 234 | int divs = sizeX > sizeY ? sizeX : sizeY; 235 | double toLenth = maxScaled == 0 ? 0 : 0.7 / maxScaled / divs; 236 | double toUnity = 1 / maxActual; 237 | float sizeL = 0.6 / (sizeX > sizeY ? sizeX + 1 : sizeY + 1); 238 | float sizeA = sizeL * cos(PI / 12); 239 | float marginX = 0.5 / dataX->sizeXO(); 240 | float marginY = 0.5 / dataX->sizeYO(); 241 | float diffX = dataX->sizeXI() == 1 ? 1 : (1.0 - 2 * marginX) / dataX->sizeXF(); 242 | float diffY = dataX->sizeYI() == 1 ? 1 : (1.0 - 2 * marginY) / dataX->sizeYF(); 243 | for (auto &i : polar) { 244 | i.first.first *= toLenth; 245 | i.second *= toUnity; 246 | } 247 | QVector2D line0; 248 | QVector2D line1; 249 | QVector2D line2; 250 | float offsetX = dataX->offsetX(); 251 | float offsetY = dataX->offsetY(); 252 | for (int i = 0; i < sizeY; i++) { 253 | for (int j = 0; j < sizeX; j++) { 254 | int idx = i * sizeX + j; 255 | float offX = marginX + diffX * (j + offsetX); 256 | float offY = marginY + diffY * (i + offsetY); 257 | VectorD2D &p = polar[idx].first; 258 | QVector3D base(offX, offY, polar[idx].second); 259 | toCatsn(p.first, p.second, line0); 260 | QVector3D top = base + line0; 261 | point[idx * 5] = base; 262 | point[idx * 5 + 1] = top; 263 | toCatsn(sizeA, p.second, line0); 264 | toCatsn(sizeL, p.second + angle1, line1); 265 | toCatsn(sizeL, p.second + angle2, line2); 266 | top = top + line0; 267 | point[idx * 5 + 2] = top; 268 | point[idx * 5 + 3] = top + line1; 269 | point[idx * 5 + 4] = top + line2; 270 | QVector3D c = Gradient::HEIGHT_MAP.getColor(polar[idx].second); 271 | for (int i = 0; i < 5; i++) color[idx * 5 + i] = c; 272 | } 273 | } 274 | for (size_t i = 0; i < normal.size(); i++) normal[i] = QVector3D(0, 0, 1); 275 | for (int i = 0; i < 8; i++) { 276 | int cntT = 0; 277 | int cntL = 0; 278 | function func = [&](int j) { 279 | int offset = j * 5; 280 | if (polar[j].first.first == 0) return; 281 | for (int j = 0; j < 3; j++) indexT[i][cntT++] = offset + j + 2; 282 | for (int j = 0; j < 2; j++) indexL[i][cntL++] = offset + j; 283 | }; 284 | indexFunc[i](func, sizeX, sizeY); 285 | indexT[i].resize(cntT); 286 | indexL[i].resize(cntL); 287 | } 288 | } 289 | 290 | bool Model::checkSame(Model::enumType type, std::vector &&data) { 291 | bool ret = true; 292 | if (type != this->type) 293 | ret = false; 294 | else if (data.size() != this->data.size()) 295 | ret = false; 296 | else 297 | for (size_t i = 0; i < data.size(); i++) 298 | if (data[i] != this->data[i]) ret = false; 299 | 300 | if (!ret) { 301 | this->type = type; 302 | this->data = std::move(data); 303 | } 304 | return ret; 305 | } 306 | 307 | void Model::checkSize(int point, int indexT, int indexL) { 308 | this->point.resize(point); 309 | color.resize(point); 310 | position.resize(point); 311 | normal.resize(point); 312 | 313 | for (auto &i : this->indexT) i.resize(indexT); 314 | for (auto &i : this->indexL) i.resize(indexL); 315 | } 316 | -------------------------------------------------------------------------------- /app/render/model.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEL_H 2 | #define MODEL_H 3 | 4 | #include "data/project.h" 5 | #include "gradient.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class Model { 12 | public: 13 | Model(); 14 | ~Model() = default; 15 | const std::vector &getIndexT(int dir) const; 16 | const std::vector &getIndexL(int dir) const; 17 | const std::vector &getPoint() const; 18 | const std::vector &getNormal() const; 19 | const std::vector &getColor() const; 20 | const std::vector &getPosition() const; 21 | bool setQuantity(SimQuantity &sq, float time, int step); 22 | 23 | private: 24 | enum enumType { LINE, HEIGHT, VECTOR }; 25 | typedef std::shared_ptr DATA; 26 | 27 | bool checkSame(Model::enumType type, std::vector &&data); 28 | void checkSize(int point, int indexT, int indexL); 29 | void genLine(DATA x, DATA y, VectorD2D extreme); 30 | void genHeight(DATA data, VectorD2D extreme); 31 | void genVector(DATA dataX, DATA dataY, VectorD2D extreme, 32 | float ratio = 1); // ratio = model x size / model y size 33 | 34 | static std::vector &, int, int)>> 35 | indexFunc; 36 | 37 | enumType type; 38 | std::vector data; 39 | std::vector point; 40 | std::vector normal; 41 | std::vector color; 42 | std::vector position; 43 | std::vector> indexT; 44 | std::vector> indexL; 45 | }; 46 | 47 | #endif // MODEL_H 48 | -------------------------------------------------------------------------------- /app/res/icons/document-export.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/res/icons/document-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/res/icons/plama.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 18 | 22 | 26 | 27 | 35 | 36 | 38 | 39 | 41 | image/svg+xml 42 | 44 | 45 | 46 | 47 | 48 | 51 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/res/icons/plot-gradient.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/res/icons/plot-shader.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/res/icons/plot-step.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/res/render/flat.fsh: -------------------------------------------------------------------------------- 1 | #version 130 2 | 3 | flat in vec4 vecColorF; 4 | out vec4 ret; 5 | 6 | void main() { 7 | ret = vecColorF; 8 | } 9 | -------------------------------------------------------------------------------- /app/res/render/flat.vsh: -------------------------------------------------------------------------------- 1 | #version 130 2 | 3 | in vec3 vecPos; 4 | in vec3 vecPnt; 5 | in vec3 vecNormal; 6 | in vec3 vecColor; 7 | flat out vec4 vecColorF; 8 | uniform mat4 matTrans; 9 | uniform mat4 matModel; 10 | uniform mat4 matNormal; 11 | uniform vec3 vecLight; 12 | uniform vec3 vecView; 13 | 14 | void main() { 15 | vec4 vecPntW = matModel * vec4(vecPnt, 1.0f); 16 | vec4 vecPosW = matModel * vec4(vecPos, 1.0f); 17 | vec4 vecNormalT = matNormal * vec4(vecNormal, 0.0f); 18 | vec4 vecNormalW = normalize(vec4(vecNormalT.xyz, 0.0f)); 19 | vec3 vecLightIn = normalize(vecLight - vecPosW.xyz); 20 | vec3 vecColorLight = vec3(1, 1, 1); 21 | vec3 vecViewIn = normalize(vecView - vecPosW.xyz); 22 | vec3 vecReflect = reflect(-vecLightIn, vecNormalW.xyz); 23 | float spec = pow(max(dot(vecViewIn, vecReflect), 0.0), 8); 24 | float base = 0.55 + max(0.3 * dot(vecNormalW.xyz, vecLightIn), 0.0f); 25 | vecColorF = vec4(base*vecColor + 0.3*spec*vecColorLight, 1.0f); 26 | gl_Position = matTrans * vecPntW; 27 | } 28 | -------------------------------------------------------------------------------- /app/res/render/plain.fsh: -------------------------------------------------------------------------------- 1 | #version 130 2 | 3 | flat in vec4 vecColorF; 4 | out vec4 ret; 5 | 6 | void main() { 7 | ret = vecColorF; 8 | } 9 | -------------------------------------------------------------------------------- /app/res/render/plain.vsh: -------------------------------------------------------------------------------- 1 | #version 130 2 | 3 | in vec3 vecPnt; 4 | in vec3 vecColor; 5 | flat out vec4 vecColorF; 6 | uniform mat4 matTrans; 7 | uniform mat4 matModel; 8 | 9 | void main() { 10 | vec4 vecPntW = matModel * vec4(vecPnt, 1.0f); 11 | gl_Position = matTrans * vecPntW; 12 | vecColorF = vec4(vecColor, 1.0f); 13 | } 14 | -------------------------------------------------------------------------------- /app/res/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | render/flat.vsh 4 | render/flat.fsh 5 | script/plugins.py 6 | render/plain.fsh 7 | render/plain.vsh 8 | icons/document-open.svg 9 | icons/document-export.svg 10 | icons/plot-shader.svg 11 | icons/plot-gradient.svg 12 | icons/plot-step.svg 13 | icons/plama.svg 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/util/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | 4 | #define TABLE_SIZE 256 5 | 6 | using namespace std; 7 | 8 | float PI = acos(-1); 9 | 10 | float *genTable() { 11 | static float data[TABLE_SIZE]; 12 | for (int i = 0; i < TABLE_SIZE; i++) data[i] = sin(PI * 2 * i / TABLE_SIZE); 13 | return data; 14 | } 15 | 16 | float *SINE_TABLE = genTable(); 17 | 18 | QPair unify(int number, int radix) { 19 | typedef QPair P; 20 | if (number >= 0) return P(number / radix, number % radix); 21 | int e = number % radix; 22 | return e == 0 ? P(number / radix, 0) : P(number / radix - 1, radix + e); 23 | } 24 | 25 | QVector3D toV3D(const QColor &c) { return QVector3D(c.redF(), c.greenF(), c.blueF()); } 26 | 27 | void toPolar(double x, double y, double &r, double &t) { 28 | static float PI_1O2 = PI / 2; 29 | static float PI_3O2 = PI * 3 / 2; 30 | 31 | r = magnitude(x, y); 32 | 33 | if (x == 0) 34 | t = y > 0 ? PI_1O2 : PI_3O2; 35 | else if (y == 0) 36 | t = x > 0 ? 0 : PI; 37 | else { 38 | float a = atan(y / x); 39 | if (a < 0) a += PI; 40 | t = y >= 0 ? a : a + PI; 41 | } 42 | } 43 | 44 | void toPolar(double x, double y, VectorD2D &ret) { 45 | double r = 0, t = 0; 46 | toPolar(x, y, r, t); 47 | ret.first = r; 48 | ret.second = t; 49 | } 50 | 51 | void toCatsn(double r, double t, VectorD2D &ret) { 52 | ret.first = r * fastCos(t); 53 | ret.second = r * fastSin(t); 54 | } 55 | 56 | // code from qt qmath.h 57 | float fastSin(float x) { 58 | int si = int(x * (0.5 * TABLE_SIZE / PI)); 59 | float d = x - si * (2.0 * PI / TABLE_SIZE); 60 | int ci = si + TABLE_SIZE / 4; 61 | si &= TABLE_SIZE - 1; 62 | ci &= TABLE_SIZE - 1; 63 | return SINE_TABLE[si] + (SINE_TABLE[ci] - 0.5 * SINE_TABLE[si] * d) * d; 64 | } 65 | 66 | float fastCos(float x) { 67 | int ci = int(x * (0.5 * TABLE_SIZE / PI)); 68 | float d = x - ci * (2.0 * PI / TABLE_SIZE); 69 | int si = ci + TABLE_SIZE / 4; 70 | si &= TABLE_SIZE - 1; 71 | ci &= TABLE_SIZE - 1; 72 | return SINE_TABLE[si] - (SINE_TABLE[ci] + 0.5 * SINE_TABLE[si] * d) * d; 73 | } 74 | 75 | double magnitude(double x, double y) { 76 | return x == 0 ? abs(y) : abs(x) * sqrt(1 + pow(y / x, 2)); 77 | } 78 | 79 | QIcon getIcon(const QString &name) { 80 | if (QIcon::hasThemeIcon(name)) 81 | return QIcon::fromTheme(name); 82 | else 83 | return QIcon(":/icons/" + name + ".svg"); 84 | } 85 | 86 | void toPolar(double x, double y, QVector2D &ret) { 87 | double r = 0, t = 0; 88 | toPolar(x, y, r, t); 89 | ret.setX(r); 90 | ret.setY(t); 91 | } 92 | 93 | void toCatsn(double r, double t, QVector2D &ret) { 94 | ret.setX(r * fastCos(t)); 95 | ret.setY(r * fastSin(t)); 96 | } 97 | 98 | class SamplerV : public Sampler { 99 | public: 100 | SamplerV(const vector &data, int step, int width) 101 | : Sampler(width, data.size() / width, step), data(data) {} 102 | double getRaw(int x, int y) const override { return data[y * this->sxo + x]; } 103 | unsigned long repr() const override { return (unsigned long)&data; } 104 | 105 | private: 106 | const std::vector &data; 107 | }; 108 | 109 | class SamplerVV : public Sampler { 110 | public: 111 | SamplerVV(const vector> &data, int step, int width) 112 | : Sampler(width, data.size() / width, step), data(data) {} 113 | double getRaw(int x, int y) const override { return data[y * this->sxo + x][0]; } 114 | unsigned long repr() const override { return (unsigned long)&data; } 115 | 116 | private: 117 | const std::vector> &data; 118 | }; 119 | 120 | Sampler::Sampler(int sizeX, int sizeY, int step) 121 | : step(step), sxo(sizeX), syo(sizeY), sxi(sxo / step), syi(syo / step), 122 | startX(sizeX % step / 2), startY(sizeY % step / 2), // 123 | sxf((sxo - 1) / (float)step), syf((syo - 1) / (float)step), 124 | ofsetX((step - 1) / (2.0 * step) + startX / (float)step), 125 | ofsetY((step - 1) / (2.0 * step) + startY / (float)step) {} 126 | 127 | float Sampler::sizeXF() const { return sxf; } 128 | float Sampler::sizeYF() const { return syf; } 129 | int Sampler::sizeXI() const { return sxi; } 130 | int Sampler::sizeYI() const { return syi; } 131 | int Sampler::sizeXO() const { return sxo; } 132 | int Sampler::sizeYO() const { return syo; } 133 | float Sampler::offsetX() const { return ofsetX; } 134 | float Sampler::offsetY() const { return ofsetY; } 135 | 136 | double Sampler::get(int x, int y) const { 137 | this->conv(x, y); 138 | y += x / sxi; 139 | x = x % sxi; 140 | double total = 0; 141 | int startX = x * step + this->startX; 142 | int startY = y * step + this->startY; 143 | int endX = startX + step; 144 | int endY = startY + step; 145 | 146 | for (int ix = startX; ix < endX; ix++) 147 | for (int iy = startY; iy < endY; iy++) // 148 | total += this->getRaw(ix, iy); 149 | 150 | return total / (step * step); 151 | } 152 | 153 | bool Sampler::operator==(const Sampler *a) const { 154 | return repr() == a->repr() && this->step == a->step; 155 | } 156 | 157 | shared_ptr Sampler::gen(const vector &data, int step, int width) { 158 | return std::make_shared(data, step, width == -1 ? data.size() : width); 159 | } 160 | 161 | shared_ptr Sampler::gen( 162 | const vector> &data, int step, int width) { 163 | return std::make_shared(data, step, width == -1 ? data.size() : width); 164 | } 165 | 166 | void Sampler::conv(int &x, int &y) const { 167 | if (x < 0) x += sxi; 168 | if (y < 0) y += syi; 169 | } 170 | 171 | QString format(double value) { 172 | if (value == 0) return "0"; 173 | double v = fabs(value); 174 | if (v < 0.001) 175 | return QString::number(value, 'e', 1); 176 | else if (v < 1000) 177 | return QString::number(value, 'g', 3); 178 | else 179 | return QString::number(value, 'e', 1); 180 | } 181 | -------------------------------------------------------------------------------- /app/util/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | extern float PI; 16 | 17 | typedef QPair VectorD2D; 18 | QPair unify(int number, int radix); 19 | QVector3D toV3D(const QColor &c); 20 | void toPolar(double x, double y, VectorD2D &ret); 21 | void toCatsn(double r, double t, VectorD2D &ret); 22 | void toPolar(double x, double y, QVector2D &ret); 23 | void toCatsn(double r, double t, QVector2D &ret); 24 | double magnitude(double x, double y); 25 | float fastSin(float x); 26 | float fastCos(float x); 27 | QIcon getIcon(const QString &name); 28 | QString format(double value); 29 | 30 | template class Trio { 31 | public: 32 | A a; 33 | B b; 34 | C c; 35 | Trio(const A &a, const B &b, const C &c) : a(a), b(b), c(c) {} 36 | Trio() = default; 37 | }; 38 | 39 | class Sampler { 40 | public: 41 | Sampler(int sizeX, int sizeY, int step); 42 | virtual ~Sampler() = default; 43 | virtual unsigned long repr() const = 0; 44 | float sizeXF() const; 45 | float sizeYF() const; 46 | int sizeXI() const; 47 | int sizeYI() const; 48 | int sizeXO() const; 49 | int sizeYO() const; 50 | float offsetX() const; 51 | float offsetY() const; 52 | double get(int x, int y = 0) const; 53 | bool operator==(const Sampler *a) const; 54 | 55 | static std::shared_ptr gen( 56 | const std::vector &data, int step, int width = -1); 57 | static std::shared_ptr gen( 58 | const std::vector> &data, int step, int width = -1); 59 | 60 | protected: 61 | int step, sxo, syo, sxi, syi, startX, startY; 62 | float sxf, syf, ofsetX, ofsetY; 63 | // s_o: original size 64 | // s_i: sampled integer size 65 | // s_f: sampled float size 66 | virtual double getRaw(int x, int y = 0) const = 0; 67 | void conv(int &x, int &y) const; 68 | }; 69 | 70 | #endif // UTIL_H 71 | -------------------------------------------------------------------------------- /doc/Plama.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Plama.ico -------------------------------------------------------------------------------- /doc/Report/fig/comp1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/comp1.jpg -------------------------------------------------------------------------------- /doc/Report/fig/comp2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/comp2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/comp3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/comp3.jpg -------------------------------------------------------------------------------- /doc/Report/fig/comp4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/comp4.pdf -------------------------------------------------------------------------------- /doc/Report/fig/comp5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/comp5.jpg -------------------------------------------------------------------------------- /doc/Report/fig/comp6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/comp6.pdf -------------------------------------------------------------------------------- /doc/Report/fig/datamodule.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/datamodule.pdf -------------------------------------------------------------------------------- /doc/Report/fig/datamodule.xml: -------------------------------------------------------------------------------- 1 | 7VnZbuMgFP0aP07lfXls0mUeZqRKHWk6j9QmNjPYRJg0Sb9+wICXEEdtkzSp2iiy4MBlOfeAL9jypuXqloJ58ZNkEFuuna0s78py3SCy+VMAawm4SSyBnKJMQk4H3KNnqEBlly9QButBRUYIZmg+BFNSVTBlAwxQSpbDajOCh73OQQ4N4D4F2ER/o4wVEo3dqMO/Q5QXumcnTGTJI0j/5ZQsKtWf5Xqz5ieLS6DbUhOtC5CRZQ/yri1vSglhMlWuphALajVt0u5mpLQdN4UVe5GBLy2eAF5APeRmYGytyWimA4WBbXmTZYEYvJ+DVJQuufc5VrAS85zDkzOE8ZRgQnm+IhUUEKnYDSgRFmK4BRSURNAzARjlFYcwnDFVTVty2uzmx/EM1EXTu2hejRZSBlejU3ZaIrk+ISkho2teRRt4inutTZ1fdp52Q4UVfS9rpwGlrrxtu2OYJxTJ2wmPDHphxqWnsoSyguSkAvi6QydDB/TIhivEHnrpP6LKRRSIbMUH9qBMmsygMLsUq4QjKQZ1jVIJ3iCsm/4LGVurhQkWjHCoG9wPQuba3yPOHfEKnzlZ0FRNXWmNAZpDVcuTkCBlpzMpxIChp+F63ccxrrEQuMmk+YdY6POR8lQuUjXfnPZcJa9lzVD8uLyDDXlHpryjLeoODyDu8Bjitgfidgfidobids9J3J4pbvdU4o6/dp2djvFP5RjP2HXu1ny+1QfbdPjb+mSbTvK16XTa9s/ojWqGlmPanuNFjqr6bOXtn/Cdqo9EPRqvAAMGV3wqbEgIhTV6Bo9NBcHfnKCKNSMJJlZwJSJwLsNaKtLpBeQpZwryMHwiGEL8VHSpCpgQ6aTmLkBV/qtR7Df/uNS7/gb1YWhQ72+h/hCxuuMY1PP1DE2dfhbuk3fk3ozHPxX3XnJC7s2o5DNtOQb177nlBCPU2yXJFtiMAM/RB2M3OSOOeM3lTUtQe3kTG75JjuWbwx5vz+KotBEVbl05xgl2j9hRmd4JTXZejYYLztNO1i3ICFcZ9W8zN9pxAvvC9qPQSfRzo13/Ig4ix3fVc9iLnKfRSyOLdq4vU8phb/lOfPDYcSZ6uYiMa7+Di6i9nm23bfttKop2isiN3yIi7iOw7lVTm/LoZOKNucTBziHvrs4Tsv836zn+6AHBXi+dU8YDicH8RwuDD0r98aJgnu0+u8k10n3a9K7/Aw== -------------------------------------------------------------------------------- /doc/Report/fig/datastruct.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/datastruct.pdf -------------------------------------------------------------------------------- /doc/Report/fig/datastruct.xml: -------------------------------------------------------------------------------- 1 | 7VjRbtowFP2avE7BJlAeVwbtwzZ1YtLaRze5JG4dO3IcIPv6ObETE0KmVhVIRfCA7JPr69xzjm8gHp6nuztJsuSHiIB5yI92Hv7mITSZzvR3BZQGwEFggFjSyEAjB6zoX7Cgb9GCRpB3ApUQTNGsC4aCcwhVByNSim03bC1Yd9eMxNADViFhffQPjVRi0Bs0dfg90Dhpdh5NbMHPJHyNpSi43c9DeF1/zOWUNLlsoXlCIrHdg/DCw3MphDKjdDcHVlHb0GbWLQeutvctgas3LbArclU2tUOkqbBTIVUiYsEJWzj0tq4Pqgy+niUqZXo40kPYUfVYwV9QYKdPzSWuZPlol9STpzqwjuPR10o0DYSM5DkNDbikrMn8AkqV1iekUEJD7t6+C5HZuLXgaklSyirj3RFJUlFJcWuqrEobJKphQhQytFHIWo/IGGwUbkXS3geRgq5Eh0hgRNFNNzuxLozbOKeEHlgxBoRBV2HeJcz0TMLYrTeEFTbpgxQvVRM61KurxjahClYZqUvY6q7ZVWiIH8JozCv+NR0gW8I2IBXs/k9Zn4xmQdNmbXcezex863rdyLdYstfnsP9x/mZXXw/7Gvd9PT5Xw/GvwrxLmOBMwuBew1nR9LcE+Kl/dX2ipjPpNh00PtJ00Imazs3V28PeHve9Pfmgt+ululpS7gVkgnKV72V+qADnkFbpgz8NTmOT0Sne3tqbTDC+jIOEDp7e6NjT+1QHKTjG4a+CcEVV+Xk5xOfkcHIhHAYHHJ6zoU8v4ywfPhTHJ+RQT917BdM+3bsbvPgH -------------------------------------------------------------------------------- /doc/Report/fig/diagram1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/diagram1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/diagram2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/diagram2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/diagram2.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | Qt SVG Document 26 | 27 | 28 | 29 | 53 | Qt SVG Document 55 | Generated with Qt 57 | 59 | 63 | 69 | 73 | 77 | 81 | 85 | 89 | 90 | 96 | 100 | 101 | 107 | 111 | 115 | 119 | 123 | 127 | 128 | 134 | 138 | 142 | 146 | 150 | 154 | 158 | 162 | 166 | 170 | 174 | 178 | 182 | 186 | 187 | 193 | 1 202 | 1.4 211 | 1.8 220 | 2.2 229 | 2.6 238 | 3 247 | 248 | 255 | 262 | t(s) 271 | 272 | 279 | 285 | 0 294 | 0.6 303 | 1.2 312 | 1.8 321 | 2.4 330 | 3 339 | 340 | 347 | 354 | h(m) 363 | 364 | 371 | 377 | 383 | 387 | 391 | 392 | 393 | 394 | -------------------------------------------------------------------------------- /doc/Report/fig/diagram3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/diagram3.pdf -------------------------------------------------------------------------------- /doc/Report/fig/dir.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/dir.pdf -------------------------------------------------------------------------------- /doc/Report/fig/echarts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/echarts.png -------------------------------------------------------------------------------- /doc/Report/fig/example1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/example1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/example2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/example2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/excel1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/excel1.png -------------------------------------------------------------------------------- /doc/Report/fig/excel2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/excel2.png -------------------------------------------------------------------------------- /doc/Report/fig/gantt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/gantt.pdf -------------------------------------------------------------------------------- /doc/Report/fig/grid.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/grid.pdf -------------------------------------------------------------------------------- /doc/Report/fig/grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 45 | 50 | 51 | 53 | 54 | 56 | image/svg+xml 57 | 59 | 60 | 61 | 62 | 63 | 68 | 74 | 80 | 86 | 92 | 98 | 104 | 110 | 116 | 122 | 125 | 131 | 137 | 143 | 149 | 155 | 161 | 162 | 166 | 172 | 178 | 184 | 190 | 196 | 202 | 203 | 207 | 213 | 219 | 225 | 231 | 232 | 238 | 244 | 251 | 257 | Scalar field 268 | Y component 279 | X component 290 | Unified grid 301 | 302 | 303 | -------------------------------------------------------------------------------- /doc/Report/fig/index1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/index1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/index2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/index2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/interface.png -------------------------------------------------------------------------------- /doc/Report/fig/interp1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/interp1.jpg -------------------------------------------------------------------------------- /doc/Report/fig/interp2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/interp2.jpg -------------------------------------------------------------------------------- /doc/Report/fig/light1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/light1.jpg -------------------------------------------------------------------------------- /doc/Report/fig/light2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/light2.jpg -------------------------------------------------------------------------------- /doc/Report/fig/matlab0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/matlab0.pdf -------------------------------------------------------------------------------- /doc/Report/fig/matlab1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/matlab1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/matlab2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/matlab2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/matrix.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/matrix.pdf -------------------------------------------------------------------------------- /doc/Report/fig/plasimo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/plasimo.png -------------------------------------------------------------------------------- /doc/Report/fig/sample1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/sample1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/sample2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/sample2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/sample2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 45 | 51 | 52 | 53 | 75 | 77 | 78 | 80 | image/svg+xml 81 | 83 | 84 | 85 | 86 | 87 | 92 | 96 | 103 | 110 | 117 | 124 | 131 | 138 | 145 | 152 | 159 | 166 | 173 | 180 | 181 | 186 | 191 | 198 | 205 | 212 | 219 | 227 | 235 | 243 | 251 | 259 | 267 | 275 | 283 | 291 | 299 | 307 | 315 | 322 | 330 | 338 | 346 | 347 | 348 | -------------------------------------------------------------------------------- /doc/Report/fig/sample3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/sample3.pdf -------------------------------------------------------------------------------- /doc/Report/fig/sample3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 44 | 50 | 51 | 52 | 74 | 76 | 77 | 79 | image/svg+xml 80 | 82 | 83 | 84 | 85 | 86 | 91 | 96 | 101 | 109 | 117 | 125 | 133 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /doc/Report/fig/signature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/signature.png -------------------------------------------------------------------------------- /doc/Report/fig/toplevel.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/toplevel.pdf -------------------------------------------------------------------------------- /doc/Report/fig/toplevel.xml: -------------------------------------------------------------------------------- 1 | 7Vhdk5owFP01PLaDCaA+rp/dmfalttPtY4QIaQNhQvBjf31vIIiR1bbTXe2O64OTnNx83HMOl6iDx+l2LkmefBIR5Q5yo62DJw5CQX8I3xrY1QD2/RqIJYtqqNcCC/ZIDegatGQRLaxAJQRXLLfBUGQZDZWFESnFxg5bCW7vmpOYdoBFSHgX/cYildToAPVb/ANlcdLs3AtMwksS/oylKDOzn4PwqvrUwylp1jKJFgmJxOYAwlMHj6UQqm6l2zHlmtqGtnre7MTo/tySZupPJpiECrVrUqcRMGG6QqpExCIjfNqioyo9qhdwoZeolEOzB026ZerhoP1dh7zv+7qbKbl7MFOqjjUY3WnRAAk5KQoW1uCM8WbpH1SpnfEJKZUAqD3cRyFyE7cSmZqRlHFtvDmRJBVailGdps7tJFEGKkQpQxOFjPWIjKmJwnuRwPtUpBRSgRBJOVFsba9OjAvjfVyrBDSMGE8LY7ZeE16aRSdEEQcFHA4yWkpoxbqViqgEVY5VtDXaJEzRRU6qvDbwxNq6nSdtTaWi2/O0dQlpJvjG6KYQoL7pb9rHqoGSgycqcP+dwuAlvO1a3kaWt3u2t9F/7W3c9Ta6kLcHb0Xn74TxLiQM7hSd+df7V1dzsHu9mjN8qzlnrO1d733qdaz9GRih8tW527viG7W5nh+wCJ6Ci/oxWZCeshmRtGCPZFkFaAJzwTJVHcUfOf4EEG3DonaknkA4izPtYOAFZMIjzRqDK/qdGVDapKMCNGBZ/KVy7DvvZblH3hH3QdDh3nuCe/Qc3PdO3AhvlPrhBak/dRm/Derx8IrUd68k9yn8+r6ZkoMHvy85wfOQD932j4dq7ODPHTz9BQ== -------------------------------------------------------------------------------- /doc/Report/fig/unit1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/unit1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/unit2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/unit2.pdf -------------------------------------------------------------------------------- /doc/Report/fig/vec1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/vec1.pdf -------------------------------------------------------------------------------- /doc/Report/fig/vec2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/fig/vec2.pdf -------------------------------------------------------------------------------- /doc/Report/final-report_juntong-liu_201219267.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/final-report_juntong-liu_201219267.pdf -------------------------------------------------------------------------------- /doc/Report/reference.bib: -------------------------------------------------------------------------------- 1 | @misc{ref:plasimo, 2 | author = {{The Plasimo Team}}, 3 | title = {Plasimo home page}, 4 | year = 2017, 5 | url = {http://plasimo.phys.tue.nl}, 6 | note = {(Accessed: 11-10-2017)} 7 | } 8 | 9 | @misc{ref:echarts, 10 | author = {{ECharts}}, 11 | title = {{NPM} Dependencies}, 12 | year = 2018, 13 | url = {https://ecomfe.github.io/echarts-examples/public/editor.html?c=graph-npm}, 14 | note = {(Accessed: 05-04-2018)} 15 | } 16 | 17 | @misc{ref:datastudio, 18 | author = {{Google}}, 19 | title = {Google Data Studio}, 20 | year = 2018, 21 | url = {https://cloud.google.com/data-studio/}, 22 | note = {(Accessed: 05-04-2018)} 23 | } 24 | 25 | @misc{ref:qt, 26 | author = {{The Qt Company}}, 27 | title = {Qt - cross-platform software development for embedded \& desktop}, 28 | year = 2017, 29 | url = {https://www.qt.io}, 30 | note = {(Accessed: 11-10-2017)} 31 | } 32 | 33 | @misc{ref:opengl, 34 | author = {{Khronos Group}}, 35 | title = {OpenGL - The Industry Standard for High Performance Graphics}, 36 | year = 2017, 37 | url = {https://www.opengl.org}, 38 | note = {(Accessed: 11-10-2017)} 39 | } 40 | 41 | @misc{ref:mathgl, 42 | author = {{Alexey Balakin}}, 43 | title = {MathGL}, 44 | year = 2018, 45 | url = {http://mathgl.sourceforge.net/doc_en/Main.html}, 46 | note = {(Accessed: 13-04-2017)} 47 | } 48 | 49 | @book{ref:cleancode, 50 | author = {Martin, Robert C.}, 51 | title = {Clean Code: A Handbook of Agile Software Craftsmanship}, 52 | year = {2008}, 53 | isbn = {0132350882, 9780132350884}, 54 | edition = {1}, 55 | publisher = {Prentice Hall PTR}, 56 | address = {Upper Saddle River, NJ, USA}, 57 | } 58 | 59 | @misc{ref:qtdv, 60 | author = {{The Qt Company}}, 61 | title = {Qt Data Visualization}, 62 | year = 2018, 63 | url = {http://doc.qt.io/qt-5/qtdatavisualization-index.html}, 64 | note = {(Accessed: 13-04-2017)} 65 | } 66 | 67 | @misc{ref:d3d, 68 | author = {{Microsoft}}, 69 | title = {{Direct3D}}, 70 | year = 2018, 71 | url = {https://msdn.microsoft.com/en-us/library/windows/desktop/hh309466(v=vs.85).aspx}, 72 | note = {(Accessed: 13-04-2017)} 73 | } 74 | 75 | @misc{ref:qtgui, 76 | author = {{The Qt Company}}, 77 | title = {Qt {GUI}}, 78 | year = 2017, 79 | url = {https://doc.qt.io/qt-5/qtgui-index.html}, 80 | note = {(Accessed: 11-10-2017)} 81 | } 82 | 83 | @misc{ref:ffmpeg, 84 | author = {{FFmpeg}}, 85 | title = {{FFmpeg}}, 86 | year = 2017, 87 | url = {https://www.ffmpeg.org}, 88 | note = {(Accessed: 11-10-2017)} 89 | } 90 | 91 | @misc{ref:octave, 92 | author = {John W. Eaton}, 93 | title = {{GNU Octave}}, 94 | year = 2017, 95 | url = {https://www.gnu.org/software/octave}, 96 | note = {(Accessed: 12-10-2017)} 97 | } 98 | 99 | @misc{ref:qucs, 100 | author = {{Qucs Team}}, 101 | title = {Qucs project: Quite Universal Circuit Simulator}, 102 | year = 2018, 103 | url = {http://qucs.sourceforge.net/}, 104 | note = {(Accessed: 13-04-2017)} 105 | } 106 | -------------------------------------------------------------------------------- /doc/Report/res/header.tex: -------------------------------------------------------------------------------- 1 | \documentclass[12pt, a4paper]{article} 2 | \usepackage{graphicx, fullpage, listings} 3 | \usepackage{pdfpages, color} 4 | \usepackage[titletoc, page]{appendix} 5 | \usepackage{tocloft} 6 | \usepackage{ifthen, calc} 7 | \usepackage{subfig, wrapfig, caption} 8 | \usepackage{lipsum} 9 | \usepackage[separate-uncertainty=true, multi-part-units=single, output-complex-root = j, complex-root-position = before-number]{siunitx} 10 | \usepackage{amsmath} 11 | \usepackage[hyphens]{url} 12 | \usepackage[siunitx, american]{circuitikz} 13 | \usepackage[hidelinks]{hyperref} 14 | \usepackage{cprotect} 15 | \usepackage{suffix} 16 | \usepackage{enumitem} 17 | \usepackage[hang,flushmargin]{footmisc} 18 | \usepackage{lmodern} 19 | \usepackage{float} 20 | 21 | % COMMANDS 22 | 23 | \newfloat{lstfloat}{tbp}{lop} 24 | \floatname{lstfloat}{Listing} 25 | \def\lstfloatautorefname{Listing} 26 | 27 | \newcommand\cell[2]{\parbox{#1\textwidth}{\vspace{3pt}#2\vspace{3pt}}} 28 | 29 | \newcommand\makereference[1]{ % 30 | \bibliographystyle{res/myieee} 31 | \bibliography{#1} 32 | \addcontentsline{toc}{section}{References} 33 | } 34 | 35 | % \eq[label]{equation} 36 | \newcommand\eq[2][]{ % 37 | \ifthenelse{\equal{#1}{}}{ % 38 | \begin{equation*}\begin{aligned} #2 \end{aligned}\end{equation*} 39 | }{ % 40 | \begin{equation}\begin{aligned} #2 \end{aligned}\label{#1}\end{equation} 41 | } 42 | } 43 | 44 | \newcommand{\MatLab}{\textsc{Matlab}} 45 | 46 | % VALUES 47 | \graphicspath{{fig/}} 48 | \setlength\cftbeforesecskip{3pt} 49 | \setlength{\parskip}{4.5pt} 50 | \interfootnotelinepenalty=500 51 | \hfuzz=\maxdimen 52 | \tolerance=10000 53 | \hbadness=10000 54 | \setlist[itemize]{topsep=0.5pt} 55 | 56 | 57 | % LISTING 58 | 59 | \lstdefinelanguage{ahdl}{ 60 | morekeywords={ 61 | AND, ASSERT, BEGIN, BIDIR, BiTS, BURIED, 62 | CASE, CLIQUE, CONNECTED_PINS, CONSTANT, 63 | DEFAULTS, DEFINE, DESIGN, DEVICE, DIV, 64 | ELSE, ELSEIF, END, FOR, FUNCTION, 65 | GENERATE, GND, HELP_ID, 66 | IF, INCLUDE, INPUT, IS, LOG2, 67 | MACHINE, MOD, NAND, NODE, NOR, NOT, 68 | OF, OPTIONS, OR, OTHERS, OUTPUT, 69 | PARAMETERS, REPORT, RETURNS, 70 | SEGMENTS, SEVERITY, STATES, SUBDESIGN, 71 | TABLE, THEN, TITLE, TO, TRI_STATE_NODE, 72 | VARIABLE, VCC, WHEN, WITH, XNOR, XOR, 73 | CARRY, CASCADE, CEIL, DFFE, DFF, 74 | EXP, FLOOR, GLOBAL, JEFFE, JKFF, 75 | LATCH, LCELL, MCELL, MEMORY, OPNDRN, 76 | SOFT, SRFFE, SRFF, TFFE, TFF, TRI, 77 | WIRE, X 78 | }, 79 | sensitive=false, 80 | morecomment=[l]{--}, 81 | morecomment=[s]{\%}{\%}, 82 | tabsize = 4 83 | } 84 | 85 | \lstdefinelanguage{xml}{ 86 | basicstyle=\ttfamily\footnotesize, 87 | morestring=[b]", 88 | moredelim=[s][\bfseries\color{mygreen}]{<}{\ }, 89 | moredelim=[s][\bfseries\color{mygreen}]{}, 90 | moredelim=[l][\bfseries\color{mygreen}]{/>}, 91 | moredelim=[l][\bfseries\color{mygreen}]{>}, 92 | morecomment=[s]{}, 93 | morecomment=[s]{}, 94 | commentstyle=\color{mygrey}, 95 | stringstyle=\color{myorange}, 96 | %identifierstyle=\color{mygreen} 97 | } 98 | 99 | \newcommand\lstinputlistingnobreak[2][]{ 100 | \begin{figure}[!ht] 101 | \vspace{-0.5cm} 102 | \lstinputlisting[#1]{#2} 103 | \end{figure} 104 | } 105 | 106 | \lstnewenvironment{lstlistingnobreak}[1][]{ % 107 | \figure[!ht]\vspace{-0.5cm} 108 | \lstset{xrightmargin=35pt}\lstset{#1} 109 | }{ % 110 | \endfigure 111 | } 112 | 113 | \lstset{ 114 | frame=single,basicstyle=\ttfamily,breaklines=true 115 | } 116 | 117 | \definecolor{myyellow}{rgb}{1,1,0.8} 118 | \definecolor{mygray}{rgb}{0.5,0.5,0.4} 119 | \definecolor{mygreen}{rgb}{0,0.7,0.5} 120 | \definecolor{myorange}{rgb}{1.0,0.4,0} 121 | \definecolor{mylilas}{rgb}{0.8,0.3,1.0} 122 | 123 | \lstdefinestyle{mybase} { 124 | breaklines=true, 125 | showstringspaces=false, 126 | basicstyle=\scriptsize\tt, 127 | frame=single, 128 | xleftmargin=20pt, 129 | xrightmargin=20pt, 130 | numbersep=9pt, 131 | numberstyle={\color{black} \footnotesize \sf}, 132 | stringstyle=\color{myorange}, 133 | keywordstyle=\color{mygreen}, 134 | commentstyle=\color{mygray}, 135 | tabsize=4 136 | } 137 | 138 | \lstdefinestyle{myahdl} { 139 | style=mybase, 140 | language = ahdl, 141 | keywordstyle=\color{mylilas}, 142 | commentstyle=\color{mygreen} 143 | } 144 | 145 | \lstdefinestyle{mymatlabcode} { 146 | style=mybase, 147 | language=Matlab, 148 | stringstyle=\color{mylilas}, 149 | commentstyle=\color{mygreen}, 150 | emph=[1]{for,end,break,function,while,if,else},emphstyle=[1]\color{blue}, 151 | } 152 | 153 | \lstdefinestyle{mymatlabconsole} { 154 | style=mybase, 155 | morecomment=[l][\color{red}]{Error}, 156 | } 157 | 158 | \lstdefinestyle{myahdl} { 159 | style=mybase, 160 | language = ahdl, 161 | keywordstyle=\color{mylilas}, 162 | commentstyle=\color{mygreen}, 163 | numberstyle={\color{black} \footnotesize \sf} 164 | } 165 | 166 | 167 | % TITLE 168 | 169 | \title{ 170 | \includegraphics[width=0.4\textwidth]{res/univcrest.pdf} 171 | \\[4pt]\reporttitle} 172 | \author{ % 173 | \begin{minipage}{0.4\textwidth} 174 | \begin{flushleft} 175 | \projectinfoleft 176 | \end{flushleft} 177 | \end{minipage} 178 | \begin{minipage}{0.4\textwidth} 179 | \begin{flushright} 180 | \projectinforight 181 | \end{flushright} 182 | \end{minipage} 183 | } 184 | \date{\small{\today}} 185 | -------------------------------------------------------------------------------- /doc/Report/res/titlepage.tex: -------------------------------------------------------------------------------- 1 | 2 | \begin{titlepage} 3 | \maketitle 4 | \thispagestyle{empty} 5 | \addtocontents{toc}{\protect\thispagestyle{empty}} 6 | 7 | \begin{center} 8 | \textbf{Declaration of academic integrity} 9 | \end{center} 10 | \begin{small} 11 | \noindent I confirm that I have read and understood the University's Academic Integrity Policy. 12 | 13 | \noindent I confirm that I have acted honestly, ethically and professionally in conduct leading to assessment for the programme of study. 14 | 15 | \noindent I confirm that I have not copied material from another source nor committed plagiarism nor fabricated, falsified or embellished data when completing the attached piece of work. 16 | 17 | \noindent I confirm that I have not copied material from another source, nor colluded with any other student in the preparation and production of this work. 18 | \begin{flushright} 19 | \begin{tabular}{ m{0.1\linewidth} m{0.25\linewidth} } 20 | \hfuzz=5pt 21 | Signature: & \studentname \\ 22 | Date: & \today \\ 23 | \end{tabular} 24 | \end{flushright} 25 | 26 | \end{small} 27 | 28 | \begin{center} \textbf{Abstract} \end{center} 29 | \begin{small} 30 | \theabstract 31 | \end{small} 32 | 33 | \begin{center} 34 | \begin{minipage}{\linewidth} 35 | \tableofcontents 36 | \end{minipage} 37 | \end{center} 38 | \end{titlepage} 39 | -------------------------------------------------------------------------------- /doc/Report/res/univcrest.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/Report/res/univcrest.pdf -------------------------------------------------------------------------------- /doc/demo.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/demo.7z -------------------------------------------------------------------------------- /doc/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlamaDev/Plama/b38bee559037feb4b5d3ef3054f5ccd8987fd5df/doc/demo.png -------------------------------------------------------------------------------- /doc/dummy.py: -------------------------------------------------------------------------------- 1 | class Loader: 2 | @staticmethod 3 | def name(): 4 | return 'Dummy' # plugin name 5 | 6 | @staticmethod 7 | def load(): 8 | return [{ 9 | 'abbr': 'Rea-1', # abbreviation of node name 10 | 'name': 'Reaction A + B <=> C', # full node name 11 | 'children': [], # child nodes 12 | 'quantities': [{ # quantities in this node 13 | 'name': 'example-2D1D', # name of quantity 14 | 'times': [1, 2, 3], # times of quantity 15 | 'dimData': 1, # dimension amout of quantity 16 | 'sizeData': [3, 3], # size for one set of data 17 | 'sizeModel': [[0, 1], [0, 1]], # size of actual model 18 | 'labels': ['t(s)', 'Φ(Wm-2)', 'x(m)', 'y(m)'], # axis 19 | 'data': lambda: [ # data should be a function for lazy loading 20 | [0, 1, 0, 0, 0, 0, 0, 0, 0], # 3x3 data at time 1 21 | [0, 0, 1, 0, 0, 0, 0, 0, 0], # 3x3 data at time 2 22 | [0, 0, 0, 0, 2, 0, 0, 0, 0] # 3x3 data at time 3 23 | ] 24 | }, { 25 | 'name': 'example-0D1D', # functional data example 26 | 'times': [1, 2, 3], 27 | 'dimData': 1, 28 | 'sizeData': [], 29 | 'sizeModel': [], 30 | 'labels': ['t(s)', 'h(m)'], 31 | 'data': lambda: [ 32 | [0], [3], [2] 33 | ] 34 | }, { 35 | 'name': 'example-2D2D', # 2-dimensional data example (usually fields) 36 | 'times': [1], 37 | 'dimData': 2, # dimension = 2 38 | 'sizeData': [3, 2], 39 | 'sizeModel': [[2, 20], [4, 5]], 40 | 'labels': ['t(s)', 'h(m)', 'x(m)', 'y(m)'], 41 | 'data': lambda: [ 42 | [0, 1, 0, 0, 0, 0], # 3x2 data at time 1, dimension 1 43 | [0, 0, 1, 0, 0, 0] # 3x2 data at time 1, dimension 2 44 | ] 45 | }, { 46 | 'name': 'example-err', 47 | 'times': [1, 2, 3], 48 | 'dimData': 1, 49 | 'sizeData': [], 50 | 'sizeModel': [], 51 | 'labels': ['t(s)', 'h(m)'], 52 | 'data': lambda: [[1], [2]] 53 | }] 54 | }] 55 | 56 | @staticmethod 57 | def args(): 58 | return [] # 59 | 60 | plugin = Loader() 61 | -------------------------------------------------------------------------------- /doc/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 18 | 22 | 26 | 27 | 35 | 36 | 38 | 39 | 41 | image/svg+xml 42 | 44 | 45 | 46 | 47 | 48 | 51 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /doc/plama.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 53 | 62 | 65 | 69 | 70 | 72 | 76 | 80 | 81 | 89 | 99 | 105 | 108 | 112 | 113 | 114 | 116 | 120 | 124 | 128 | 129 | 134 | 138 | 143 | 144 | 146 | 150 | 151 | 155 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /doc/title.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 45 | 47 | 49 | 53 | 57 | 58 | 66 | 75 | 84 | 93 | 102 | 111 | 120 | 121 | 123 | 124 | 126 | image/svg+xml 127 | 129 | 130 | 131 | 132 | 133 | 137 | 142 | 143 | 148 | 153 | 158 | 163 | 168 | 173 | 174 | 175 | --------------------------------------------------------------------------------