├── docs
├── .gitignore
├── README.md
└── _config.yml
├── exit.png
├── icon.png
├── open.png
├── opend.png
├── opent.png
├── save.png
├── swap.png
├── icon_res.rc
├── openobj.png
├── rolling.jpg
├── algorithm.pdf
├── installer
├── packages
│ ├── com.kapandaria.stereograma
│ │ ├── data
│ │ │ └── .gitignore
│ │ └── meta
│ │ │ └── package.xml
│ ├── com.kapandaria.stereograma_models
│ │ ├── data
│ │ │ └── .gitignore
│ │ └── meta
│ │ │ └── package.xml
│ ├── com.kapandaria.stereograma_depthmaps_textures
│ │ ├── data
│ │ │ └── .gitignore
│ │ └── meta
│ │ │ └── package.xml
│ ├── com.kapandaria.stereograma_desktop
│ │ └── meta
│ │ │ ├── package.xml
│ │ │ └── installscript.qs
│ └── com.kapandaria.stereograma_menu
│ │ └── meta
│ │ ├── package.xml
│ │ └── installscript.qs
└── config
│ └── config.xml
├── production
├── anaglyph_result
│ └── README
├── stereograms
│ └── README
├── depthmaps
│ ├── Cow.png
│ ├── Mur.png
│ ├── Pot.png
│ ├── Tor1.png
│ ├── bull.png
│ ├── fish.png
│ ├── goat.png
│ ├── afrik.png
│ ├── dragon.png
│ ├── guitar.png
│ ├── hippo.png
│ ├── luger.png
│ ├── monkey.png
│ ├── Chopper.png
│ ├── dinopet.png
│ ├── dolphins.png
│ ├── elephant.png
│ ├── kangaroo.png
│ ├── molecule.png
│ ├── spirals.png
│ └── blender
│ │ ├── curve.png
│ │ ├── logo.blend
│ │ ├── logo.png
│ │ ├── mobius.png
│ │ ├── star.blend
│ │ ├── star.png
│ │ ├── twist.png
│ │ ├── curve.blend
│ │ ├── mobius.blend
│ │ ├── twist.blend
│ │ ├── metaballs.blend
│ │ ├── metaballs.png
│ │ ├── strange_cube.png
│ │ └── strange_cube.blend
├── eyehelpers
│ ├── eye.png
│ ├── sight.png
│ ├── star.png
│ ├── circle.png
│ ├── cube_dual.png
│ └── magen_david.png
├── textures
│ ├── tx_000.jpg
│ ├── tx_001.jpg
│ ├── tx_002.jpg
│ ├── tx_003.jpg
│ ├── tx_004.jpg
│ ├── tx_005.jpg
│ ├── tx_006.jpg
│ ├── tx_007.jpg
│ ├── tx_008.jpg
│ ├── tx_009.jpg
│ ├── tx_010.jpg
│ ├── tx_011.jpg
│ ├── tx_012.jpg
│ ├── tx_013.jpg
│ ├── tx_014.jpg
│ ├── tx_015.jpg
│ ├── tx_016.jpg
│ ├── tx_017.jpg
│ ├── tx_018.jpg
│ ├── tx_019.jpg
│ ├── tx_020.jpg
│ ├── tx_021.jpg
│ ├── tx_022.jpg
│ ├── tx_023.jpg
│ └── tx_024.jpg
├── compose
│ ├── compose00.png
│ ├── compose01.png
│ ├── compose02.png
│ ├── compose03.png
│ ├── compose04.png
│ ├── compose05.png
│ ├── compose06.png
│ ├── compose07.png
│ ├── compose08.png
│ ├── compose09.png
│ ├── compose10.png
│ ├── compose11.png
│ ├── compose12.png
│ └── compose13.png
├── anaglyph
│ ├── bonsai_left.jpg
│ └── bonsai_right.jpg
└── models
│ ├── pyramid.obj
│ └── cube.obj
├── stereograma.ico
├── .gitmodules
├── .gitignore
├── parse.h
├── ClickableLabel.cpp
├── trirender.h
├── rsc.qrc
├── stringtype.cpp
├── stringtype.h
├── main.cpp
├── anaglyphmaker.h
├── imagefiledialog.h
├── ClickableLabel.h
├── presetsketch.h
├── imageviewer.h
├── basicimagewidget.h
├── stereomaker.h
├── model3d.h
├── FormulaGen.h
├── imageviewer.cpp
├── preset.cpp
├── presetedit.h
├── imagecontainerwidget.h
├── modeldepthviewer.h
├── imagefiledialog.cpp
├── README.md
├── mainwindow.h
├── glmodelview.h
├── stereograma.pro
├── preset.h
├── basicimagewidget.cpp
├── stringtype.ui
├── presetedit.cpp
├── RPly
├── rplyfile.h
└── rply.h
├── modeldepthviewer.cpp
├── anaglyphmaker.cpp
├── imageviewer.ui
├── presetsketch.cpp
├── stereograma.svg
├── imagecontainerwidget.cpp
├── presetedit.ui
├── FormulaGen.cpp
├── FormulaGen.ui
├── anaglyphmaker.ui
├── mainwindow.cpp
├── stereomaker.cpp
├── model3d.cpp
├── glmodelview.cpp
├── modeldepthviewer.ui
├── trirender.cpp
└── parse.cpp
/docs/.gitignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | test
2 |
--------------------------------------------------------------------------------
/exit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/exit.png
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/icon.png
--------------------------------------------------------------------------------
/open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/open.png
--------------------------------------------------------------------------------
/opend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/opend.png
--------------------------------------------------------------------------------
/opent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/opent.png
--------------------------------------------------------------------------------
/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/save.png
--------------------------------------------------------------------------------
/swap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/swap.png
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-leap-day
2 | show_downloads: true
3 |
--------------------------------------------------------------------------------
/icon_res.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON DISCARDABLE "stereograma.ico"
--------------------------------------------------------------------------------
/openobj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/openobj.png
--------------------------------------------------------------------------------
/rolling.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/rolling.jpg
--------------------------------------------------------------------------------
/algorithm.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/algorithm.pdf
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/production/anaglyph_result/README:
--------------------------------------------------------------------------------
1 | this is the default output folder for anaglyphs
2 |
--------------------------------------------------------------------------------
/stereograma.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/stereograma.ico
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_models/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/production/stereograms/README:
--------------------------------------------------------------------------------
1 | this is the default output folder for generated stereograms
2 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_depthmaps_textures/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "exprtk"]
2 | path = exprtk
3 | url = https://github.com/ArashPartow/exprtk.git
4 |
--------------------------------------------------------------------------------
/production/depthmaps/Cow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/Cow.png
--------------------------------------------------------------------------------
/production/depthmaps/Mur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/Mur.png
--------------------------------------------------------------------------------
/production/depthmaps/Pot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/Pot.png
--------------------------------------------------------------------------------
/production/depthmaps/Tor1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/Tor1.png
--------------------------------------------------------------------------------
/production/depthmaps/bull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/bull.png
--------------------------------------------------------------------------------
/production/depthmaps/fish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/fish.png
--------------------------------------------------------------------------------
/production/depthmaps/goat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/goat.png
--------------------------------------------------------------------------------
/production/eyehelpers/eye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/eyehelpers/eye.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | moc_*.cpp
3 | moc_predefs.h
4 | ui_*.h
5 | qrc_*.cpp
6 | Makefile
7 | *.pro.user.*
8 | *.user
9 |
--------------------------------------------------------------------------------
/production/depthmaps/afrik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/afrik.png
--------------------------------------------------------------------------------
/production/depthmaps/dragon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/dragon.png
--------------------------------------------------------------------------------
/production/depthmaps/guitar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/guitar.png
--------------------------------------------------------------------------------
/production/depthmaps/hippo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/hippo.png
--------------------------------------------------------------------------------
/production/depthmaps/luger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/luger.png
--------------------------------------------------------------------------------
/production/depthmaps/monkey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/monkey.png
--------------------------------------------------------------------------------
/production/eyehelpers/sight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/eyehelpers/sight.png
--------------------------------------------------------------------------------
/production/eyehelpers/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/eyehelpers/star.png
--------------------------------------------------------------------------------
/production/textures/tx_000.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_000.jpg
--------------------------------------------------------------------------------
/production/textures/tx_001.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_001.jpg
--------------------------------------------------------------------------------
/production/textures/tx_002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_002.jpg
--------------------------------------------------------------------------------
/production/textures/tx_003.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_003.jpg
--------------------------------------------------------------------------------
/production/textures/tx_004.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_004.jpg
--------------------------------------------------------------------------------
/production/textures/tx_005.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_005.jpg
--------------------------------------------------------------------------------
/production/textures/tx_006.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_006.jpg
--------------------------------------------------------------------------------
/production/textures/tx_007.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_007.jpg
--------------------------------------------------------------------------------
/production/textures/tx_008.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_008.jpg
--------------------------------------------------------------------------------
/production/textures/tx_009.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_009.jpg
--------------------------------------------------------------------------------
/production/textures/tx_010.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_010.jpg
--------------------------------------------------------------------------------
/production/textures/tx_011.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_011.jpg
--------------------------------------------------------------------------------
/production/textures/tx_012.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_012.jpg
--------------------------------------------------------------------------------
/production/textures/tx_013.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_013.jpg
--------------------------------------------------------------------------------
/production/textures/tx_014.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_014.jpg
--------------------------------------------------------------------------------
/production/textures/tx_015.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_015.jpg
--------------------------------------------------------------------------------
/production/textures/tx_016.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_016.jpg
--------------------------------------------------------------------------------
/production/textures/tx_017.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_017.jpg
--------------------------------------------------------------------------------
/production/textures/tx_018.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_018.jpg
--------------------------------------------------------------------------------
/production/textures/tx_019.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_019.jpg
--------------------------------------------------------------------------------
/production/textures/tx_020.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_020.jpg
--------------------------------------------------------------------------------
/production/textures/tx_021.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_021.jpg
--------------------------------------------------------------------------------
/production/textures/tx_022.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_022.jpg
--------------------------------------------------------------------------------
/production/textures/tx_023.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_023.jpg
--------------------------------------------------------------------------------
/production/textures/tx_024.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/textures/tx_024.jpg
--------------------------------------------------------------------------------
/production/compose/compose00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose00.png
--------------------------------------------------------------------------------
/production/compose/compose01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose01.png
--------------------------------------------------------------------------------
/production/compose/compose02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose02.png
--------------------------------------------------------------------------------
/production/compose/compose03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose03.png
--------------------------------------------------------------------------------
/production/compose/compose04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose04.png
--------------------------------------------------------------------------------
/production/compose/compose05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose05.png
--------------------------------------------------------------------------------
/production/compose/compose06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose06.png
--------------------------------------------------------------------------------
/production/compose/compose07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose07.png
--------------------------------------------------------------------------------
/production/compose/compose08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose08.png
--------------------------------------------------------------------------------
/production/compose/compose09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose09.png
--------------------------------------------------------------------------------
/production/compose/compose10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose10.png
--------------------------------------------------------------------------------
/production/compose/compose11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose11.png
--------------------------------------------------------------------------------
/production/compose/compose12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose12.png
--------------------------------------------------------------------------------
/production/compose/compose13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/compose/compose13.png
--------------------------------------------------------------------------------
/production/depthmaps/Chopper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/Chopper.png
--------------------------------------------------------------------------------
/production/depthmaps/dinopet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/dinopet.png
--------------------------------------------------------------------------------
/production/depthmaps/dolphins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/dolphins.png
--------------------------------------------------------------------------------
/production/depthmaps/elephant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/elephant.png
--------------------------------------------------------------------------------
/production/depthmaps/kangaroo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/kangaroo.png
--------------------------------------------------------------------------------
/production/depthmaps/molecule.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/molecule.png
--------------------------------------------------------------------------------
/production/depthmaps/spirals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/spirals.png
--------------------------------------------------------------------------------
/production/eyehelpers/circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/eyehelpers/circle.png
--------------------------------------------------------------------------------
/production/anaglyph/bonsai_left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/anaglyph/bonsai_left.jpg
--------------------------------------------------------------------------------
/production/anaglyph/bonsai_right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/anaglyph/bonsai_right.jpg
--------------------------------------------------------------------------------
/production/eyehelpers/cube_dual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/eyehelpers/cube_dual.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/curve.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/logo.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/logo.blend
--------------------------------------------------------------------------------
/production/depthmaps/blender/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/logo.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/mobius.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/mobius.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/star.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/star.blend
--------------------------------------------------------------------------------
/production/depthmaps/blender/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/star.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/twist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/twist.png
--------------------------------------------------------------------------------
/production/eyehelpers/magen_david.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/eyehelpers/magen_david.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/curve.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/curve.blend
--------------------------------------------------------------------------------
/production/depthmaps/blender/mobius.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/mobius.blend
--------------------------------------------------------------------------------
/production/depthmaps/blender/twist.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/twist.blend
--------------------------------------------------------------------------------
/production/depthmaps/blender/metaballs.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/metaballs.blend
--------------------------------------------------------------------------------
/production/depthmaps/blender/metaballs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/metaballs.png
--------------------------------------------------------------------------------
/parse.h:
--------------------------------------------------------------------------------
1 |
2 | void parse(const char* buffer);
3 | #ifdef USE_FLOAT
4 | float parseXY(const char* buffer,float x,float y,bool *ok);
5 | #endif
6 |
--------------------------------------------------------------------------------
/production/depthmaps/blender/strange_cube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/strange_cube.png
--------------------------------------------------------------------------------
/production/depthmaps/blender/strange_cube.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnudles/stereograma/HEAD/production/depthmaps/blender/strange_cube.blend
--------------------------------------------------------------------------------
/production/models/pyramid.obj:
--------------------------------------------------------------------------------
1 | # OBJ file created by ply_to_obj.c
2 | #
3 | g Object001
4 |
5 | v 0 0 0
6 | v 1 0 0
7 | v 1 1 0
8 | v 0 1 0
9 | v 0.5 0.5 1.6
10 |
11 | f 5 2 3
12 | f 4 5 3
13 | f 6 3 2
14 | f 5 6 2
15 | f 4 6 5
16 | f 6 4 3
17 |
--------------------------------------------------------------------------------
/ClickableLabel.cpp:
--------------------------------------------------------------------------------
1 | #include "ClickableLabel.h"
2 |
3 | ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f)
4 | : QLabel(parent) {
5 |
6 | }
7 |
8 | ClickableLabel::~ClickableLabel() {}
9 |
10 | void ClickableLabel::mousePressEvent(QMouseEvent* event) {
11 | emit clicked();
12 | }
13 |
--------------------------------------------------------------------------------
/trirender.h:
--------------------------------------------------------------------------------
1 | #ifndef TRIRENDER_H
2 | #define TRIRENDER_H
3 |
4 | void trirender(unsigned char *buffer, int w, int h, const float *points, int np, const unsigned int *triangles, int nt, float xrot, float yrot, float zrot, float zoom, float contrast, float xoff, float yoff, float scale);
5 |
6 | #endif // TRIRENDER_H
7 |
--------------------------------------------------------------------------------
/installer/config/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Stereograma
4 | 2.6.0
5 | Stereograma Installer
6 | Kapandaria
7 | Stereograma
8 | @HomeDir@/Stereograma
9 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_models/meta/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3D Models
4 | Install Sample 3D Models
5 | 2.6.0
6 | 2020-11-12
7 | true
8 |
9 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_depthmaps_textures/meta/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Depth maps and textures
4 | Install Additional resources
5 | 2.6.0
6 | 2020-11-12
7 | true
8 |
9 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_desktop/meta/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Desktop shortcut
4 | Install Desktop shortcut
5 | 2.6.0
6 | 2020-11-12
7 | true
8 |
9 |
10 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_menu/meta/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Start Menu shortcut
4 | Install Start Menu shortcut
5 | 2.6.0
6 | 2020-11-12
7 | true
8 |
9 |
10 |
--------------------------------------------------------------------------------
/rsc.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | stereograma.svg
4 | open.png
5 | opend.png
6 | openobj.png
7 | opent.png
8 | save.png
9 | exit.png
10 | swap.png
11 | rolling.jpg
12 |
13 |
14 |
--------------------------------------------------------------------------------
/stringtype.cpp:
--------------------------------------------------------------------------------
1 | #include "stringtype.h"
2 | #include "ui_stringtype.h"
3 |
4 | StringType::StringType(const QString & title,QWidget *parent) :
5 | QDialog(parent),
6 | ui(new Ui::StringType)
7 | {
8 | ui->setupUi(this);
9 | setWindowTitle(title);
10 | }
11 |
12 | StringType::~StringType()
13 | {
14 | delete ui;
15 | }
16 |
17 | QString StringType::getString()
18 | {
19 | return ui->lineEdit->text();
20 | }
21 |
--------------------------------------------------------------------------------
/stringtype.h:
--------------------------------------------------------------------------------
1 | #ifndef STRINGTYPE_H
2 | #define STRINGTYPE_H
3 |
4 | #include
5 |
6 | namespace Ui {
7 | class StringType;
8 | }
9 |
10 | class StringType : public QDialog
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit StringType(const QString &title, QWidget *parent = 0);
16 | ~StringType();
17 | QString getString();
18 |
19 | private:
20 | Ui::StringType *ui;
21 | };
22 |
23 | #endif // STRINGTYPE_H
24 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "mainwindow.h"
3 | #include
4 |
5 | #include "parse.h"
6 | int main(int argc, char *argv[])
7 | {
8 | QApplication a(argc, argv);
9 | a.setWindowIcon(QIcon(":/images/stereograma.svg"));
10 | QCoreApplication::setOrganizationName("Kapandaria");
11 | QCoreApplication::setApplicationName("Stereograma");
12 | MainWindow w;
13 | w.show();
14 |
15 | return a.exec();
16 | }
17 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma/meta/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Stereograma Binaries
4 | Install Stereograma binaries (Software)
5 | 2.6.0
6 | 2020-11-12
7 |
8 |
9 |
10 | true
11 |
12 |
--------------------------------------------------------------------------------
/anaglyphmaker.h:
--------------------------------------------------------------------------------
1 | #ifndef ANAGLYPHMAKER_H
2 | #define ANAGLYPHMAKER_H
3 |
4 | #include
5 |
6 | namespace Ui {
7 | class AnaglyphMaker;
8 | }
9 |
10 | class AnaglyphMaker : public QMainWindow
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit AnaglyphMaker(QWidget *parent = 0);
16 | ~AnaglyphMaker();
17 |
18 | private slots:
19 | void on_mergeButton_clicked();
20 |
21 | private:
22 | Ui::AnaglyphMaker *ui;
23 | };
24 |
25 | #endif // ANAGLYPHMAKER_H
26 |
--------------------------------------------------------------------------------
/imagefiledialog.h:
--------------------------------------------------------------------------------
1 | #ifndef IMAGEFILEDIALOG_H
2 | #define IMAGEFILEDIALOG_H
3 | #include
4 | #include
5 |
6 | class ImageFileDialog : public QFileDialog
7 | {
8 | Q_OBJECT
9 | public:
10 | ImageFileDialog(QWidget *parent):QFileDialog(parent){setOption(QFileDialog::DontUseNativeDialog);}
11 | void init();
12 | void deinit();
13 | private:
14 | QLabel *_preview;
15 | private slots:
16 | void fileChanged(const QString &file);
17 | };
18 |
19 | #endif // IMAGEFILEDIALOG_H
20 |
--------------------------------------------------------------------------------
/production/models/cube.obj:
--------------------------------------------------------------------------------
1 | # Blender v2.69 (sub 0) OBJ File: ''
2 | # www.blender.org
3 | mtllib cube.mtl
4 | o Cube
5 | v 1.000000 -1.000000 -1.000000
6 | v 1.000000 -1.000000 1.000000
7 | v -1.000000 -1.000000 1.000000
8 | v -1.000000 -1.000000 -1.000000
9 | v 1.000000 1.000000 -0.999999
10 | v 0.999999 1.000000 1.000001
11 | v -1.000000 1.000000 1.000000
12 | v -1.000000 1.000000 -1.000000
13 | usemtl Material
14 | s off
15 | f 1 2 3 4
16 | f 5 8 7 6
17 | f 1 5 6 2
18 | f 2 6 7 3
19 | f 3 7 8 4
20 | f 5 1 4 8
21 |
--------------------------------------------------------------------------------
/ClickableLabel.h:
--------------------------------------------------------------------------------
1 | #ifndef CLICKABLELABEL_H
2 | #define CLICKABLELABEL_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | class ClickableLabel : public QLabel {
9 | Q_OBJECT
10 |
11 | public:
12 | explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
13 | ~ClickableLabel();
14 |
15 | signals:
16 | void clicked();
17 |
18 | protected:
19 | void mousePressEvent(QMouseEvent* event);
20 |
21 | };
22 |
23 | #endif // CLICKABLELABEL_H
24 |
--------------------------------------------------------------------------------
/presetsketch.h:
--------------------------------------------------------------------------------
1 | #ifndef PRESETSKETCH_H
2 | #define PRESETSKETCH_H
3 |
4 | #include
5 | #include
6 | #include "preset.h"
7 |
8 | class PresetSketch : public QWidget
9 | {
10 | Q_OBJECT
11 | public:
12 | explicit PresetSketch(QWidget *parent = 0);
13 | void setPreset(Preset * preset);
14 | signals:
15 |
16 | public slots:
17 | void presetUpdated();
18 | protected:
19 | void paintEvent(QPaintEvent *);
20 |
21 | private:
22 | float def_width;
23 | float def_height;
24 | float eye_size;
25 | Preset *m_preset;
26 | QVector m_heights;
27 |
28 | };
29 |
30 | #endif // PRESETSKETCH_H
31 |
--------------------------------------------------------------------------------
/imageviewer.h:
--------------------------------------------------------------------------------
1 | #ifndef IMAGEVIEWER_H
2 | #define IMAGEVIEWER_H
3 |
4 | #include
5 | #include
6 | #include "basicimagewidget.h"
7 |
8 | namespace Ui {
9 | class ImageViewer;
10 | }
11 |
12 | class ImageViewer : public QMainWindow, public BasicImageWidget
13 | {
14 | Q_OBJECT
15 |
16 | public:
17 | explicit ImageViewer(QWidget *parent = 0);
18 | ~ImageViewer();
19 | void setImage(const QImage & image);
20 |
21 | private slots:
22 | void on_actionSave_As_triggered();
23 |
24 | void on_actionInvert_triggered();
25 |
26 | private:
27 | void mouseDoubleClickEvent(QMouseEvent * event);
28 | Ui::ImageViewer *ui;
29 | };
30 |
31 | #endif // IMAGEVIEWER_H
32 |
--------------------------------------------------------------------------------
/basicimagewidget.h:
--------------------------------------------------------------------------------
1 | #ifndef BASICIMAGEWIDGET_H
2 | #define BASICIMAGEWIDGET_H
3 | #include
4 | #include
5 |
6 | class BasicImageWidget
7 | {
8 | public:
9 | BasicImageWidget();
10 | void saveAsImage();
11 | void setFolderSettings(const QString &fsetting);
12 | void setFolderSettings(const char *fsetting);
13 | void setSaveTitle(const QString &stitle);
14 | void setSaveTitle(const char *stitle);
15 | void setBasicImageParent(QWidget *p);
16 | const QImage & getImage() {return imdata;}
17 | const QImage * getImagePtr() {return &imdata;}
18 | protected:
19 | QImage imdata;
20 | QString folderSettings;
21 | QString saveTitle;
22 | QWidget *m_parent;
23 | };
24 |
25 | #endif // BASICIMAGEWIDGET_H
26 |
--------------------------------------------------------------------------------
/stereomaker.h:
--------------------------------------------------------------------------------
1 | #ifndef STEREOMAKER_H
2 | #define STEREOMAKER_H
3 |
4 | #include
5 | #include
6 | #include "preset.h"
7 |
8 | void scaleLine(uchar* big,const uchar *original,int sizeoriginal);
9 | class StereoMaker
10 | {
11 | public:
12 | StereoMaker();
13 | ~StereoMaker();
14 | QImage render(const QImage & dmap,const QImage & ptrn,Preset *psettings,QProgressBar * qpbar,const QImage * eye_helper_right,const QImage * eye_helper_left,bool show_helper, bool helpers_margin);
15 | void composeDepth(QImage & depth,QImage & compose, float composeHeight);
16 | static const QVector & getGrayScale();
17 | private:
18 | static QVector grayscale;
19 | int *depthsep;
20 | };
21 |
22 | #endif // STEREOMAKER_H
23 |
--------------------------------------------------------------------------------
/model3d.h:
--------------------------------------------------------------------------------
1 | #ifndef MODEL3D_H
2 | #define MODEL3D_H
3 |
4 | #include
5 | #include
6 |
7 |
8 | class Model3D
9 | {
10 | public:
11 | Model3D();
12 | ~Model3D();
13 | void LoadObj(const QString & filename);
14 | void LoadPly(const QString & filename);
15 | void DrawGL(bool color);
16 | unsigned int numPoints(){return m_nPoints;}
17 | const float * pointsData(){return m_points;}
18 | unsigned int numTriangles(){return m_nTriangles;}
19 | const unsigned int * trianglesData(){return m_triangles;}
20 | private:
21 | void normalize();
22 | float *m_points;
23 | unsigned char *m_colors;
24 | unsigned int *m_triangles;
25 | unsigned int m_nPoints,m_nTriangles;
26 | };
27 |
28 | #endif // MODEL3D_H
29 |
--------------------------------------------------------------------------------
/FormulaGen.h:
--------------------------------------------------------------------------------
1 | #ifndef FORMULAGEN_H
2 | #define FORMULAGEN_H
3 |
4 | #include
5 | #include "basicimagewidget.h"
6 | namespace Ui {
7 | class FormulaGen;
8 | }
9 | class QListWidgetItem;
10 | class FormulaGen : public QMainWindow, public BasicImageWidget
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit FormulaGen(QWidget *parent = 0);
16 | ~FormulaGen();
17 | int getOutputImageWidth();
18 | int getOutputImageHeight();
19 |
20 | private slots:
21 | void on_generatePb_clicked();
22 |
23 | void on_actionSave_Image_triggered();
24 |
25 | void on_actionPush_Image_triggered();
26 |
27 | void on_actionPush_Image_as_Compose_Pattern_triggered();
28 |
29 | void on_listWidget_itemActivated(QListWidgetItem *item);
30 |
31 | private:
32 | Ui::FormulaGen *ui;
33 | QStringList formulaList;
34 | };
35 |
36 | #endif // FORMULAGEN_H
37 |
--------------------------------------------------------------------------------
/imageviewer.cpp:
--------------------------------------------------------------------------------
1 | #include "imageviewer.h"
2 | #include "ui_imageviewer.h"
3 | #include
4 | #include
5 |
6 | ImageViewer::ImageViewer(QWidget *parent) :
7 | QMainWindow(parent),
8 | ui(new Ui::ImageViewer)
9 | {
10 | ui->setupUi(this);
11 | setBasicImageParent(this);
12 | }
13 |
14 | ImageViewer::~ImageViewer()
15 | {
16 | delete ui;
17 | }
18 |
19 | void ImageViewer::setImage(const QImage & image)
20 | {
21 | imdata= image;
22 | ui->imageViewArea->setPixmap(QPixmap::fromImage(imdata));
23 | }
24 |
25 | void ImageViewer::on_actionSave_As_triggered()
26 | {
27 | saveAsImage();
28 | }
29 | void ImageViewer::mouseDoubleClickEvent(QMouseEvent * )
30 | {
31 | on_actionSave_As_triggered();
32 | }
33 |
34 | void ImageViewer::on_actionInvert_triggered()
35 | {
36 | imdata.invertPixels();
37 | ui->imageViewArea->setPixmap(QPixmap::fromImage(imdata));
38 | }
39 |
--------------------------------------------------------------------------------
/preset.cpp:
--------------------------------------------------------------------------------
1 | #include "preset.h"
2 |
3 | Preset::Preset(const QString & name)
4 | {
5 | m_preset_name=name;
6 | m_eye_seperation=2.5;
7 | m_observer_distance=20;
8 | m_minimum_depth=5;
9 | m_maximum_depth=9;
10 | m_dpi = 150;
11 | m_isParallel=true;
12 | m_result_width=2048;
13 | m_result_height=1536;
14 | }
15 |
16 | Preset::Preset(QDataStream &qdata)
17 | {
18 | qdata>>m_preset_name;
19 | qdata>>m_eye_seperation;
20 | qdata>>m_observer_distance;
21 | qdata>>m_minimum_depth;
22 | qdata>>m_maximum_depth;
23 | qdata>>m_dpi;
24 | qdata>>m_result_width;
25 | qdata>>m_result_height;
26 | qdata>>m_isParallel;
27 | }
28 |
29 | void Preset::toStream(QDataStream &qdata)
30 | {
31 | qdata<
5 | #include "preset.h"
6 | namespace Ui {
7 | class PresetEdit;
8 | }
9 |
10 | class PresetEdit : public QWidget
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit PresetEdit(QWidget *parent = 0);
16 | ~PresetEdit();
17 | void setPreset(Preset* preset);
18 | signals:
19 | void onEdited();
20 | private slots:
21 | void on_crossEyedCheckBox_stateChanged(int state);
22 |
23 | void on_dpiSpinBox_valueChanged(int dpi);
24 |
25 | void on_minimumDepthDoubleSpinBox_valueChanged(double mindepth);
26 |
27 | void on_maximumDepthDoubleSpinBox_valueChanged(double maxdepth);
28 |
29 | void on_eyeSeperationDoubleSpinBox_valueChanged(double eyesep);
30 |
31 | void on_observerDistanceInDoubleSpinBox_valueChanged(double obsdist);
32 |
33 | void on_imageHeightSpinBox_valueChanged(int height);
34 |
35 | void on_imageWidthSpinBox_valueChanged(int width);
36 |
37 | private:
38 | Ui::PresetEdit *ui;
39 | Preset *m_preset;
40 | };
41 |
42 | #endif // PRESETEDIT_H
43 |
--------------------------------------------------------------------------------
/imagecontainerwidget.h:
--------------------------------------------------------------------------------
1 | #ifndef IMAGEWIDGET_H
2 | #define IMAGEWIDGET_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "imageviewer.h"
9 | #include "basicimagewidget.h"
10 |
11 | class ImageContainerWidget : public QLabel, public BasicImageWidget
12 | {
13 | Q_OBJECT
14 | public:
15 | ImageContainerWidget(QWidget *parent = 0);
16 | void openDialog();
17 | void setImage(const QImage &image);
18 | private slots:
19 | void downloadFinished(QNetworkReply* reply);
20 | void showContextMenu(const QPoint&);
21 | private:
22 |
23 | void setImage(const QString &fileName);
24 |
25 | const QString & getText();
26 | void mySetPixmap();
27 | void saveDialog();
28 | void dragEnterEvent(QDragEnterEvent *event);
29 | void dropEvent(QDropEvent *event);
30 | void mouseDoubleClickEvent(QMouseEvent * event);
31 |
32 | QAction *_saveAsAction;
33 | QAction *_unloadAction;
34 | QAction *_loadAction;
35 | QAction *_viewAction;
36 | ImageViewer *m_viewer;
37 | QMenu myMenu;
38 | QString replaceText;
39 | QNetworkAccessManager netManager;
40 | };
41 |
42 |
43 |
44 | #endif // IMAGEWIDGET_H
45 |
--------------------------------------------------------------------------------
/modeldepthviewer.h:
--------------------------------------------------------------------------------
1 | #ifndef MODELDEPTHVIEWER_H
2 | #define MODELDEPTHVIEWER_H
3 |
4 | #include
5 | #include "model3d.h"
6 |
7 | namespace Ui {
8 | class ModelDepthViewer;
9 | }
10 |
11 | class ModelDepthViewer : public QMainWindow
12 | {
13 | Q_OBJECT
14 |
15 | public:
16 | explicit ModelDepthViewer(QWidget *parent = 0);
17 | int getOutputImageWidth();
18 | int getOutputImageHeight();
19 | ~ModelDepthViewer();
20 | void setModel(Model3D * model);
21 |
22 | private slots:
23 |
24 | void on_hSliderRotZ_valueChanged(int value);
25 |
26 | void on_hSliderRotY_valueChanged(int value);
27 |
28 | void on_hSliderRotX_valueChanged(int value);
29 |
30 | void on_actionSave_Image_triggered();
31 |
32 | void on_zoomSlider_valueChanged(int value);
33 |
34 | void on_scaleSlider_valueChanged(int value);
35 |
36 | void on_contrastSlider_valueChanged(int value);
37 |
38 | void on_actionPush_Image_triggered();
39 |
40 | void on_moveXSlider_valueChanged(int value);
41 |
42 | void on_moveYSlider_valueChanged(int value);
43 |
44 | void on_widthSpin_editingFinished();
45 |
46 | void on_heightSpin_editingFinished();
47 |
48 | private:
49 | Ui::ModelDepthViewer *ui;
50 | };
51 |
52 | #endif // MODELDEPTHVIEWER_H
53 |
--------------------------------------------------------------------------------
/imagefiledialog.cpp:
--------------------------------------------------------------------------------
1 | #include "imagefiledialog.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 |
8 | void ImageFileDialog::init()
9 | {
10 | _preview = 0;
11 | QSplitter *splitter;
12 | splitter = ((QFileDialog*)this)->findChild("splitter");
13 | if (splitter == 0)
14 | {
15 | return;
16 | }
17 |
18 | _preview = new QLabel();
19 | QRect geomerty = _preview->geometry();
20 | geomerty.setWidth(160);
21 |
22 | _preview->setGeometry(geomerty);
23 | splitter->addWidget(_preview);
24 | connect(this, SIGNAL(currentChanged(QString)),
25 | this, SLOT(fileChanged(QString)));
26 |
27 | }
28 | void ImageFileDialog::deinit()
29 | {
30 | if (_preview != 0)
31 | {
32 | delete _preview;
33 | _preview=0;
34 | }
35 | }
36 | void ImageFileDialog::fileChanged(const QString &file)
37 | {
38 | if (_preview == 0)
39 | {
40 | return;
41 | }
42 | QImage img=QImage(file);
43 | if (img.isNull())
44 | {
45 | _preview->setPixmap(QPixmap());
46 | }
47 | else
48 | {
49 | QSize size = _preview->size();
50 | QImage smallimage=img.convertToFormat(QImage::Format_ARGB32).scaled(size, Qt::KeepAspectRatio);
51 | QPixmap pix=QPixmap::fromImage(smallimage);
52 | _preview->setPixmap(pix);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Stereograma
2 | This is a **FREE** open source cross-platform [**stereogram maker**/**stereogram creator**/**stereogram generator**/**stereogram renderer**] written in C++ using Qt. It aims to be fast, accurate, easy to use and multifunctional piece of software, as it uses the **best** algorithm (by W.A. Steer PhD) for generating auto-stereograms (see [algorithm.pdf](algorithm.pdf)). It can even load 3D models in the .obj and .ply file formats. It also comes with some depth maps and textures so you can start to play from the first moment. One cool feature which is very unique is that it includes an interactive diagram that shows the depths of the resulted image, according to the rendering parameters.
3 |
4 | There is also an interface for combining two pictures taken from different angles into anaglyph.
5 |
6 | ### Where to download?
7 |
8 | visit that link: https://kapandaria.wordpress.com/stereograma/
9 |
10 | ### How to build:
11 |
12 | Since it was developed with QtCreator, you can generate a makefile from the .pro file with qmake, or just compile it from within the IDE.
13 |
14 | ## Support me!
15 |
16 | I make many open source projects, and also contribute to the open source community. This project is a great example for that.
17 | If you liked this piece of software, and you want to give back, you don't have to open your wallet, just give a try to my mobile puzzle games:
18 |
19 | https://play.google.com/store/apps/details?id=com.github.gnudles.rollingmarbles
20 |
21 |
--------------------------------------------------------------------------------
/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include "preset.h"
6 |
7 | #define SETTINGS_FILE "settings.bin"
8 |
9 | namespace Ui {
10 | class MainWindow;
11 | }
12 |
13 | class MainWindow : public QMainWindow
14 | {
15 | Q_OBJECT
16 |
17 | public:
18 | explicit MainWindow(QWidget *parent = 0);
19 | ~MainWindow();
20 | void setDepthImage(const QImage & image);
21 | void setComposePattern(const QImage & image);
22 |
23 |
24 | private slots:
25 | void on_renderButton_clicked();
26 | void on_action_obj_triggered();
27 |
28 | void on_action_ply_triggered();
29 |
30 | void on_actionLoad_Texture_triggered();
31 |
32 | void on_actionLoad_Depth_Map_triggered();
33 |
34 | void on_actionCreate_Anaglyph_triggered();
35 |
36 | void on_actionAdd_preset_triggered();
37 |
38 | void on_presetSelect_currentIndexChanged(int index);
39 |
40 | void on_actionSave_Presets_triggered();
41 |
42 | void on_actionReset_triggered();
43 |
44 | void on_actionRename_Preset_triggered();
45 |
46 | void on_actionRemove_preset_triggered();
47 |
48 | void on_actionGenerate_Depth_Map_triggered();
49 |
50 | void on_rolling_clicked();
51 |
52 | void on_show_helpers_toggled(bool checked);
53 |
54 | private:
55 | void loadPresets();
56 | void savePresets();
57 | Ui::MainWindow *ui;
58 | Preset *cur_preset;
59 | QList m_presets;
60 | };
61 |
62 | #endif // MAINWINDOW_H
63 |
--------------------------------------------------------------------------------
/glmodelview.h:
--------------------------------------------------------------------------------
1 | #ifndef GLMODELVIEW_H
2 | #define GLMODELVIEW_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include "basicimagewidget.h"
8 |
9 | class GlModelView : public QOpenGLWidget,public BasicImageWidget
10 | {
11 | Q_OBJECT
12 | public:
13 | explicit GlModelView(QWidget *parent = 0);
14 | ~GlModelView();
15 | void setViewport(int width,int height);
16 | void setModel(Model3D * model);
17 | void setRotationX(float rot){m_rotx=rot;}
18 | void setRotationY(float rot){m_roty=rot;}
19 | void setRotationZ(float rot){m_rotz=rot;}
20 | void setXOffset(float offset){m_xoffset=offset;}
21 | void setYOffset(float offset){m_yoffset=offset;}
22 | void setZoom(float zoom);
23 | void setScale(float scale);
24 | void setContrast(float contrast);
25 | void setParams(float xoff,float yoff,float zoom,float contrast,float m_rotx,float m_roty,float m_rotz,float scale);
26 | const QImage *snapShot();
27 | protected:
28 | void setPerspective();
29 | void initializeGL();
30 |
31 | void paintGL();
32 | void resizeGL( int w, int h );
33 | /*void mousePressEvent(QMouseEvent* event);
34 | void mouseMoveEvent(QMouseEvent* event);
35 | void mouseReleaseEvent(QMouseEvent* event);*/
36 |
37 | protected slots:
38 |
39 | signals:
40 |
41 | public slots:
42 | private:
43 | Model3D *m_model;
44 | float m_rotx,m_roty,m_rotz;
45 | float m_xoffset,m_yoffset;
46 | float m_zoom;
47 | float m_contrast;
48 | float m_scale;
49 | bool m_noShaders;
50 | bool m_antialias;
51 | int m_new_width;
52 | int m_new_height;
53 | };
54 |
55 | #endif // GLMODELVIEW_H
56 |
--------------------------------------------------------------------------------
/stereograma.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2011-07-24T20:40:23
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui network openglwidgets
8 |
9 | TARGET = stereograma
10 | TEMPLATE = app
11 |
12 | linux:LIBS += -lGLU
13 | win32:LIBS += -lGLU32 -lOpengl32
14 | win32:RC_FILE = icon_res.rc
15 | win32:QMAKE_CXXFLAGS += -Wa,-mbig-obj
16 | DEFINES+= USE_FLOAT
17 | #QMAKE_CXXFLAGS += -fsanitize=address
18 | #QMAKE_LFLAGS += -fsanitize=address
19 |
20 | SOURCES += main.cpp\
21 | ClickableLabel.cpp \
22 | mainwindow.cpp \
23 | imagecontainerwidget.cpp \
24 | imageviewer.cpp \
25 | model3d.cpp \
26 | imagefiledialog.cpp \
27 | stereomaker.cpp \
28 | glmodelview.cpp \
29 | presetsketch.cpp \
30 | preset.cpp \
31 | modeldepthviewer.cpp \
32 | basicimagewidget.cpp \
33 | presetedit.cpp \
34 | anaglyphmaker.cpp \
35 | stringtype.cpp \
36 | trirender.cpp \
37 | RPly/rply.c \
38 | parse.cpp \
39 | FormulaGen.cpp
40 |
41 | HEADERS += mainwindow.h \
42 | ClickableLabel.h \
43 | exprtk/exprtk.hpp \
44 | imagecontainerwidget.h \
45 | imageviewer.h \
46 | model3d.h \
47 | imagefiledialog.h \
48 | stereomaker.h \
49 | glmodelview.h \
50 | presetsketch.h \
51 | preset.h \
52 | modeldepthviewer.h \
53 | basicimagewidget.h \
54 | presetedit.h \
55 | anaglyphmaker.h \
56 | stringtype.h \
57 | trirender.h \
58 | RPly/rply.h \
59 | RPly/rplyfile.h \
60 | parse.h \
61 | FormulaGen.h
62 |
63 | FORMS += mainwindow.ui \
64 | imageviewer.ui \
65 | modeldepthviewer.ui \
66 | presetedit.ui \
67 | anaglyphmaker.ui \
68 | stringtype.ui \
69 | FormulaGen.ui
70 |
71 | RESOURCES += \
72 | rsc.qrc
73 |
74 | OTHER_FILES += \
75 | old_render.txt
76 |
--------------------------------------------------------------------------------
/preset.h:
--------------------------------------------------------------------------------
1 | #ifndef PRESET_H
2 | #define PRESET_H
3 |
4 | #include
5 | #include
6 | class Preset
7 | {
8 | public:
9 | Preset(const QString &name);
10 | Preset(QDataStream & qdata);
11 | void toStream(QDataStream & qdata);
12 | inline QString getName() { return m_preset_name;}
13 | inline void setName(const QString & str) { m_preset_name=str;}
14 | inline float getEyeSeperation() {return m_eye_seperation;}
15 | inline float getObserverDistance() {return m_observer_distance;}
16 | inline float getMinimumDepth() {return m_minimum_depth;}
17 | inline float getMaximumDepth() {return m_maximum_depth;}
18 | inline int getDotsPerInch() {return m_dpi;}
19 | inline int getResultWidth() {return m_result_width;}
20 | inline int getResultHeight() {return m_result_height;}
21 | inline bool getIsParallel() {return m_isParallel;}
22 | inline void setEyeSeperation(float eye_seperation) { m_eye_seperation=eye_seperation;}
23 | inline void setObserverDistance(float observer_distance) { m_observer_distance=observer_distance;}
24 | inline void setMinimumDepth(float minimum_depth) { m_minimum_depth=minimum_depth;}
25 | inline void setMaximumDepth(float maximum_depth) { m_maximum_depth=maximum_depth;}
26 | inline void setDotsPerInch(int dpi) { m_dpi=dpi;}
27 | inline void setIsParallel(bool isParallel) { m_isParallel=isParallel;}
28 | inline void setResultWidth(int width) {m_result_width=width;}
29 | inline void setResultHeight(int height) {m_result_height=height;}
30 | private:
31 | QString m_preset_name;
32 | float m_eye_seperation;
33 | float m_observer_distance;
34 | float m_minimum_depth;
35 | float m_maximum_depth;
36 | int m_dpi;
37 | bool m_isParallel;
38 | bool m_show_helpers;
39 | bool m_use_image_resolution;
40 | int m_result_width;
41 | int m_result_height;
42 |
43 | };
44 |
45 | #endif // PRESET_H
46 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_desktop/meta/installscript.qs:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2017 The Qt Company Ltd.
4 | ** Contact: https://www.qt.io/licensing/
5 | **
6 | ** This file is part of the FOO module of the Qt Toolkit.
7 | **
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 | ** Commercial License Usage
10 | ** Licensees holding valid commercial Qt licenses may use this file in
11 | ** accordance with the commercial license agreement provided with the
12 | ** Software or, alternatively, in accordance with the terms contained in
13 | ** a written agreement between you and The Qt Company. For licensing terms
14 | ** and conditions see https://www.qt.io/terms-conditions. For further
15 | ** information use the contact form at https://www.qt.io/contact-us.
16 | **
17 | ** GNU General Public License Usage
18 | ** Alternatively, this file may be used under the terms of the GNU
19 | ** General Public License version 3 as published by the Free Software
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 | ** included in the packaging of this file. Please review the following
22 | ** information to ensure the GNU General Public License requirements will
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 | **
25 | ** $QT_END_LICENSE$
26 | **
27 | ****************************************************************************/
28 |
29 | function Component()
30 | {
31 | // default constructor
32 | }
33 |
34 | Component.prototype.createOperations = function()
35 | {
36 | component.createOperations();
37 |
38 | if (systemInfo.productType === "windows") {
39 | component.addOperation("CreateShortcut",
40 | "@TargetDir@/Stereograma.exe",// target
41 | "@DesktopDir@/Stereograma.lnk",// link-path
42 | "workingDirectory=@TargetDir@",// working-dir
43 | "iconPath=@TargetDir@/Stereograma.exe", "iconId=0",// icon
44 | "description=Start Stereograma");// description
45 |
46 | }
47 | }
--------------------------------------------------------------------------------
/basicimagewidget.cpp:
--------------------------------------------------------------------------------
1 | #include "basicimagewidget.h"
2 | #include "imagefiledialog.h"
3 | #include
4 | #include
5 | #include
6 |
7 | #if QT_VERSION >= QT_VERSION_CHECK(5,15,1)
8 | #define WEBP_FILTER " *.webp *.WEBP"
9 | #else
10 | #define WEBP_FILTER ""
11 | #endif
12 |
13 |
14 |
15 |
16 | BasicImageWidget::BasicImageWidget()
17 | {
18 | m_parent=0;
19 | }
20 |
21 | void BasicImageWidget::saveAsImage()
22 | {
23 | if (!imdata.isNull())
24 | {
25 | QSettings settings;
26 | QString cdir=settings.value(folderSettings,folderSettings).toString();
27 | ImageFileDialog dlg(m_parent);
28 |
29 | dlg.init();
30 | dlg.setFileMode( QFileDialog::AnyFile);
31 | dlg.setAcceptMode(QFileDialog::AcceptSave);
32 | dlg.setDirectory(cdir);
33 | dlg.setNameFilter("Images (*.png *.xpm *.jpg *.jpeg *.bmp *.tiff *.tif *.PNG *.XPM *.JPG *.JPEG *.BMP *.TIF *.TIFF" WEBP_FILTER ")");
34 | dlg.setWindowTitle("Save "+saveTitle);
35 | QString fileName;
36 | imdata=imdata.convertToFormat(QImage::Format_ARGB32);
37 | if (dlg.exec())
38 | {
39 | fileName = dlg.selectedFiles().first();
40 | settings.setValue(folderSettings, QFileInfo(fileName).absoluteDir().absolutePath());
41 | if (!imdata.save(fileName))
42 | {//probably no file type was supplied...
43 | fileName.append(".png");
44 | imdata.save(fileName);
45 | }
46 | }
47 | dlg.deinit();
48 | }
49 | }
50 |
51 | void BasicImageWidget::setFolderSettings(const QString & fsetting)
52 | {
53 | folderSettings=fsetting;
54 | }
55 | void BasicImageWidget::setFolderSettings(const char * fsetting)
56 | {
57 | folderSettings=fsetting;
58 | }
59 |
60 | void BasicImageWidget::setSaveTitle(const QString& stitle)
61 | {
62 | saveTitle=stitle;
63 | }
64 |
65 | void BasicImageWidget::setSaveTitle(const char * stitle)
66 | {
67 | saveTitle=stitle;
68 | }
69 |
70 | void BasicImageWidget::setBasicImageParent(QWidget *p)
71 | {
72 | m_parent=p;
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/installer/packages/com.kapandaria.stereograma_menu/meta/installscript.qs:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2017 The Qt Company Ltd.
4 | ** Contact: https://www.qt.io/licensing/
5 | **
6 | ** This file is part of the FOO module of the Qt Toolkit.
7 | **
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 | ** Commercial License Usage
10 | ** Licensees holding valid commercial Qt licenses may use this file in
11 | ** accordance with the commercial license agreement provided with the
12 | ** Software or, alternatively, in accordance with the terms contained in
13 | ** a written agreement between you and The Qt Company. For licensing terms
14 | ** and conditions see https://www.qt.io/terms-conditions. For further
15 | ** information use the contact form at https://www.qt.io/contact-us.
16 | **
17 | ** GNU General Public License Usage
18 | ** Alternatively, this file may be used under the terms of the GNU
19 | ** General Public License version 3 as published by the Free Software
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 | ** included in the packaging of this file. Please review the following
22 | ** information to ensure the GNU General Public License requirements will
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 | **
25 | ** $QT_END_LICENSE$
26 | **
27 | ****************************************************************************/
28 |
29 | function Component()
30 | {
31 | // default constructor
32 | }
33 |
34 | Component.prototype.createOperations = function()
35 | {
36 | component.createOperations();
37 |
38 | if (systemInfo.productType === "windows") {
39 | component.addOperation("CreateShortcut", "@TargetDir@/Stereograma.exe", "@StartMenuDir@/Stereograma.lnk",
40 | "workingDirectory=@TargetDir@", "iconPath=@TargetDir@/Stereograma.exe",
41 | "iconId=0", "description=Open Stereograma");
42 | component.addOperation("CreateShortcut", "@TargetDir@/maintenancetool.exe", "@StartMenuDir@/Uninstall_Stereograma.lnk",
43 | "workingDirectory=@TargetDir@", "iconPath=@TargetDir@/maintenancetool.exe",
44 | "iconId=0", "description=Uninstall Stereograma");
45 |
46 | }
47 | }
--------------------------------------------------------------------------------
/stringtype.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | StringType
4 |
5 |
6 |
7 | 0
8 | 0
9 | 322
10 | 81
11 |
12 |
13 |
14 |
15 | 400
16 | 100
17 |
18 |
19 |
20 | Dialog
21 |
22 |
23 | -
24 |
25 |
26 | -
27 |
28 |
29 | Qt::Vertical
30 |
31 |
32 |
33 | 20
34 | 40
35 |
36 |
37 |
38 |
39 | -
40 |
41 |
42 | Qt::Horizontal
43 |
44 |
45 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | buttonBox
55 | accepted()
56 | StringType
57 | accept()
58 |
59 |
60 | 248
61 | 254
62 |
63 |
64 | 157
65 | 274
66 |
67 |
68 |
69 |
70 | buttonBox
71 | rejected()
72 | StringType
73 | reject()
74 |
75 |
76 | 316
77 | 260
78 |
79 |
80 | 286
81 | 274
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/presetedit.cpp:
--------------------------------------------------------------------------------
1 | #include "presetedit.h"
2 | #include "ui_presetedit.h"
3 |
4 | PresetEdit::PresetEdit(QWidget *parent) :
5 | QWidget(parent),
6 | ui(new Ui::PresetEdit)
7 | {
8 | ui->setupUi(this);
9 | m_preset=0;
10 | }
11 |
12 | PresetEdit::~PresetEdit()
13 | {
14 | delete ui;
15 | }
16 |
17 | void PresetEdit::setPreset(Preset *preset)
18 | {
19 | m_preset=preset;
20 | ui->crossEyedCheckBox->setChecked(!preset->getIsParallel());
21 | ui->dpiSpinBox->setValue(preset->getDotsPerInch());
22 | ui->maximumDepthDoubleSpinBox->setValue(preset->getMaximumDepth());
23 | ui->minimumDepthDoubleSpinBox->setValue(preset->getMinimumDepth());
24 | ui->eyeSeperationDoubleSpinBox->setValue(preset->getEyeSeperation());
25 | ui->imageHeightSpinBox->setValue(preset->getResultHeight());
26 | ui->imageWidthSpinBox->setValue(preset->getResultWidth());
27 | ui->observerDistanceInDoubleSpinBox->setValue(preset->getObserverDistance());
28 | }
29 |
30 | void PresetEdit::on_crossEyedCheckBox_stateChanged(int state)
31 | {
32 | m_preset->setIsParallel(!state);
33 | emit(onEdited());
34 | }
35 |
36 | void PresetEdit::on_dpiSpinBox_valueChanged(int dpi)
37 | {
38 | m_preset->setDotsPerInch(dpi);
39 | emit(onEdited());
40 | }
41 |
42 | void PresetEdit::on_minimumDepthDoubleSpinBox_valueChanged(double mindepth)
43 | {
44 | m_preset->setMinimumDepth(mindepth);
45 | emit(onEdited());
46 | }
47 |
48 | void PresetEdit::on_maximumDepthDoubleSpinBox_valueChanged(double maxdepth)
49 | {
50 | ui->minimumDepthDoubleSpinBox->setMaximum(maxdepth-1);
51 | m_preset->setMaximumDepth(maxdepth);
52 | emit(onEdited());
53 | }
54 |
55 | void PresetEdit::on_eyeSeperationDoubleSpinBox_valueChanged(double eyesep)
56 | {
57 | m_preset->setEyeSeperation(eyesep);
58 | emit(onEdited());
59 | }
60 |
61 | void PresetEdit::on_observerDistanceInDoubleSpinBox_valueChanged(double obsdist)
62 | {
63 | m_preset->setObserverDistance(obsdist);
64 | emit(onEdited());
65 | }
66 |
67 | void PresetEdit::on_imageHeightSpinBox_valueChanged(int height)
68 | {
69 | m_preset->setResultHeight(height);
70 | emit(onEdited());
71 | }
72 |
73 | void PresetEdit::on_imageWidthSpinBox_valueChanged(int width)
74 | {
75 | m_preset->setResultWidth(width);
76 | emit(onEdited());
77 | }
78 |
--------------------------------------------------------------------------------
/RPly/rplyfile.h:
--------------------------------------------------------------------------------
1 | #ifndef RPLY_FILE_H
2 | #define RPLY_FILE_H
3 | /* ----------------------------------------------------------------------
4 | * RPly library, read/write PLY files
5 | * Diego Nehab, IMPA
6 | * http://www.impa.br/~diego/software/rply
7 | *
8 | * This library is distributed under the MIT License. See notice
9 | * at the end of this file.
10 | * ---------------------------------------------------------------------- */
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 | /* ----------------------------------------------------------------------
17 | * Opens a PLY file for reading (fails if file is not a PLY file)
18 | *
19 | * file_pointer: FILE * to file open for reading
20 | * error_cb: error callback function
21 | * idata,pdata: contextual information available to users
22 | *
23 | * Returns 1 if successful, 0 otherwise
24 | * ---------------------------------------------------------------------- */
25 | p_ply ply_open_from_file(FILE *file_pointer, p_ply_error_cb error_cb,
26 | long idata, void *pdata);
27 |
28 | /* ----------------------------------------------------------------------
29 | * Creates new PLY file
30 | *
31 | * file_pointer: FILE * to a file open for writing
32 | * storage_mode: file format mode
33 | * error_cb: error callback function
34 | * idata,pdata: contextual information available to users
35 | *
36 | * Returns handle to PLY file if successfull, NULL otherwise
37 | * ---------------------------------------------------------------------- */
38 | p_ply ply_create_to_file(FILE *file_pointer, e_ply_storage_mode storage_mode,
39 | p_ply_error_cb error_cb, long idata, void *pdata);
40 |
41 | #ifdef __cplusplus
42 | }
43 | #endif
44 |
45 | #endif /* RPLY_FILE_H */
46 |
47 | /* ----------------------------------------------------------------------
48 | * Copyright (C) 2003-2015 Diego Nehab. All rights reserved.
49 | *
50 | * Permission is hereby granted, free of charge, to any person obtaining
51 | * a copy of this software and associated documentation files (the
52 | * "Software"), to deal in the Software without restriction, including
53 | * without limitation the rights to use, copy, modify, merge, publish,
54 | * distribute, sublicense, and/or sell copies of the Software, and to
55 | * permit persons to whom the Software is furnished to do so, subject to
56 | * the following conditions:
57 | *
58 | * The above copyright notice and this permission notice shall be
59 | * included in all copies or substantial portions of the Software.
60 | *
61 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
62 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
63 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
64 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
65 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
66 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
67 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68 | * ---------------------------------------------------------------------- */
69 |
--------------------------------------------------------------------------------
/modeldepthviewer.cpp:
--------------------------------------------------------------------------------
1 | #include "modeldepthviewer.h"
2 | #include "ui_modeldepthviewer.h"
3 | #include
4 | #include
5 | #include "stereomaker.h"
6 | #include "mainwindow.h"
7 |
8 | ModelDepthViewer::ModelDepthViewer(QWidget *parent) :
9 | QMainWindow(parent),
10 | ui(new Ui::ModelDepthViewer)
11 | {
12 | ui->setupUi(this);
13 | ui->modelview->setSaveTitle("Rendered Depth Image");
14 | ui->modelview->setFolderSettings("depthmaps");
15 | ui->modelview->setBasicImageParent(this);
16 | }
17 |
18 | int ModelDepthViewer::getOutputImageWidth()
19 | {
20 | return ui->widthSpin->value();
21 | }
22 |
23 | int ModelDepthViewer::getOutputImageHeight()
24 | {
25 | return ui->heightSpin->value();
26 | }
27 | void ModelDepthViewer::setModel(Model3D *model)
28 | {
29 | ui->modelview->setModel(model);
30 | ui->modelview->setParams(ui->moveXSlider->value()/8.0,ui->moveYSlider->value()/8.0,
31 | ui->zoomSlider->value(),ui->contrastSlider->value(),
32 | ui->hSliderRotX->value(),ui->hSliderRotY->value(),ui->hSliderRotZ->value(),ui->scaleSlider->value());
33 | ui->modelview->repaint();
34 | }
35 |
36 | ModelDepthViewer::~ModelDepthViewer()
37 | {
38 | delete ui;
39 | }
40 |
41 |
42 | void ModelDepthViewer::on_hSliderRotZ_valueChanged(int value)
43 | {
44 | ui->modelview->setRotationZ(value);
45 | ui->modelview->repaint();
46 | }
47 |
48 | void ModelDepthViewer::on_hSliderRotX_valueChanged(int value)
49 | {
50 | ui->modelview->setRotationX(value);
51 | ui->modelview->repaint();
52 | }
53 |
54 | void ModelDepthViewer::on_hSliderRotY_valueChanged(int value)
55 | {
56 | ui->modelview->setRotationY(value);
57 | ui->modelview->repaint();
58 | }
59 |
60 | void ModelDepthViewer::on_actionSave_Image_triggered()
61 | {
62 | ui->modelview->snapShot();
63 | ui->modelview->saveAsImage();
64 | }
65 |
66 | void ModelDepthViewer::on_zoomSlider_valueChanged(int value)
67 | {
68 | ui->modelview->setZoom(value);
69 | ui->modelview->repaint();
70 | }
71 | void ModelDepthViewer::on_scaleSlider_valueChanged(int value)
72 | {
73 | ui->modelview->setScale(value);
74 | ui->modelview->repaint();
75 | }
76 |
77 | void ModelDepthViewer::on_contrastSlider_valueChanged(int value)
78 | {
79 | ui->modelview->setContrast(value);
80 | ui->modelview->repaint();
81 | }
82 |
83 | void ModelDepthViewer::on_actionPush_Image_triggered()
84 | {
85 | const QImage * im=ui->modelview->snapShot();
86 | if (im!=0)
87 | ((MainWindow*)parentWidget())->setDepthImage(*im);
88 |
89 | }
90 |
91 | void ModelDepthViewer::on_moveXSlider_valueChanged(int value)
92 | {
93 | ui->modelview->setXOffset(value/8.0);
94 | ui->modelview->repaint();
95 | }
96 |
97 | void ModelDepthViewer::on_moveYSlider_valueChanged(int value)
98 | {
99 | ui->modelview->setYOffset(value/8.0);
100 | ui->modelview->repaint();
101 | }
102 |
103 | void ModelDepthViewer::on_widthSpin_editingFinished()
104 | {
105 | ui->modelview->setViewport(getOutputImageWidth(),getOutputImageHeight());
106 | ui->modelview->repaint();
107 | }
108 |
109 | void ModelDepthViewer::on_heightSpin_editingFinished()
110 | {
111 | ui->modelview->setViewport(getOutputImageWidth(),getOutputImageHeight());
112 | ui->modelview->repaint();
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/anaglyphmaker.cpp:
--------------------------------------------------------------------------------
1 | #include "anaglyphmaker.h"
2 | #include "imageviewer.h"
3 | #include "ui_anaglyphmaker.h"
4 | #include
5 |
6 | AnaglyphMaker::AnaglyphMaker(QWidget *parent) :
7 | QMainWindow(parent),
8 | ui(new Ui::AnaglyphMaker)
9 | {
10 | ui->setupUi(this);
11 | ui->rightView->setBasicImageParent(this);
12 | ui->rightView->setFolderSettings("anaglyph");
13 | ui->rightView->setSaveTitle("Right Image");
14 | ui->leftView->setBasicImageParent(this);
15 | ui->leftView->setFolderSettings("anaglyph");
16 | ui->leftView->setSaveTitle("Left Image");
17 | }
18 |
19 | AnaglyphMaker::~AnaglyphMaker()
20 | {
21 | delete ui;
22 | }
23 |
24 | void AnaglyphMaker::on_mergeButton_clicked()
25 | {
26 | if (ui->leftView->getImage().isNull() || ui->rightView->getImage().isNull())
27 | {
28 | QMessageBox::warning(this,"Error","Please load images");
29 | return;
30 | }
31 | if ((ui->leftView->getImage().width() != ui->rightView->getImage().width())
32 | || (ui->leftView->getImage().height() != ui->rightView->getImage().height()))
33 | {
34 | QMessageBox::warning(this,"Error","Images are not at the same size.");
35 | return;
36 | }
37 | int width = ui->leftView->getImage().width();
38 | int height = ui->leftView->getImage().height();
39 |
40 | const QImage * refLeft=ui->leftView->getImagePtr();
41 | const QImage * refRight=ui->rightView->getImagePtr();
42 | if (ui->swapButton->isChecked())
43 | {
44 | const QImage *temp=refLeft;
45 | refLeft=refRight;
46 | refRight=temp;
47 | }
48 | QImage imLeft,imRight;
49 | if (ui->leftView->getImage().depth()!=32)
50 | imLeft=refLeft->convertToFormat(QImage::Format_ARGB32);
51 | else
52 | imLeft=*refLeft;
53 |
54 | if (ui->rightView->getImage().depth()!=32)
55 | imRight=refRight->convertToFormat(QImage::Format_ARGB32);
56 | else
57 | imRight=*refRight;
58 |
59 | QImage result(width,height,QImage::Format_ARGB32);
60 | unsigned int *resptr;
61 | unsigned int *endptr;
62 | const unsigned int *leftptr;
63 | const unsigned int *rightptr;
64 | unsigned int rightalpha,leftalpha;
65 | unsigned int alpha;
66 | unsigned int r,g,b;
67 | for (int i=0;i>24;
76 | leftalpha=((*leftptr)&0xff000000)>>24;
77 | r=((*leftptr)&0x00ff0000)>>16;
78 | g=((*rightptr)&0x0000ff00)>>8;
79 | b=((*rightptr)&0x000000ff);
80 | alpha = leftalpha+rightalpha-rightalpha*leftalpha/255;
81 | if (alpha==0)
82 | {
83 | *resptr=0;
84 | resptr++;
85 | rightptr++;
86 | leftptr++;
87 | }
88 | else
89 | {
90 | r=(unsigned char)((leftalpha*r)/(alpha));
91 |
92 | g=(unsigned char)((rightalpha*g)/(alpha));
93 |
94 | b=(unsigned char)((rightalpha*b)/(alpha));
95 | *resptr=(alpha<<24)|(r<<16)|(g<<8)|b;
96 | resptr++;
97 | rightptr++;
98 | leftptr++;
99 | }
100 | }
101 | }
102 | ImageViewer * imview=new ImageViewer(this);
103 | imview->setWindowTitle("Result");
104 | imview->setFolderSettings("anaglyph_result");
105 | imview->setSaveTitle("Anaglyph");
106 | imview->setImage(result);
107 | imview->show();
108 | }
109 |
--------------------------------------------------------------------------------
/imageviewer.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ImageViewer
4 |
5 |
6 |
7 | 0
8 | 0
9 | 800
10 | 600
11 |
12 |
13 |
14 | Image Viewer
15 |
16 |
17 |
18 | -
19 |
20 |
21 | true
22 |
23 |
24 |
25 |
26 | 0
27 | 0
28 | 780
29 | 527
30 |
31 |
32 |
33 |
-
34 |
35 |
36 |
37 | 0
38 | 0
39 |
40 |
41 |
42 |
43 |
44 |
45 | Qt::AlignCenter
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
80 |
81 |
82 |
83 |
84 | :/images/save.png:/images/save.png
85 |
86 |
87 | Save As...
88 |
89 |
90 | true
91 |
92 |
93 |
94 |
95 |
96 | :/images/exit.png:/images/exit.png
97 |
98 |
99 | Close
100 |
101 |
102 | true
103 |
104 |
105 |
106 |
107 | Invert
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | actionExit
117 | triggered()
118 | ImageViewer
119 | close()
120 |
121 |
122 | -1
123 | -1
124 |
125 |
126 | 399
127 | 299
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/presetsketch.cpp:
--------------------------------------------------------------------------------
1 | #include "presetsketch.h"
2 |
3 | PresetSketch::PresetSketch(QWidget *parent) :
4 | QWidget(parent)
5 | {
6 | def_width=16;
7 | def_height=50;
8 | eye_size=1;
9 | m_preset=0;
10 | m_heights.append(QPointF(-1,0));
11 | m_heights.append(QPointF(-0.8,0.2));
12 | m_heights.append(QPointF(-0.8,0.2));
13 | m_heights.append(QPointF(-0.5,0.6));
14 | m_heights.append(QPointF(-0.5,0.6));
15 | m_heights.append(QPointF(-0.3,0.4));
16 | m_heights.append(QPointF(-0.3,0.4));
17 | m_heights.append(QPointF(-0.0,0.8));
18 | m_heights.append(QPointF(-0.0,0.8));
19 | m_heights.append(QPointF(0.1,0.64));
20 | m_heights.append(QPointF(0.1,0.64));
21 | m_heights.append(QPointF(0.2,0.5));
22 | m_heights.append(QPointF(0.2,0.5));
23 | m_heights.append(QPointF(0.5,0.7));
24 | m_heights.append(QPointF(0.5,0.7));
25 | m_heights.append(QPointF(0.8,0.3));
26 | m_heights.append(QPointF(0.8,0.3));
27 | m_heights.append(QPointF(1.0,0.1));
28 | }
29 |
30 | void PresetSketch::setPreset(Preset *preset)
31 | {
32 | m_preset=preset;
33 | repaint();
34 | }
35 |
36 | float min(float x,float y)
37 | {
38 | if(x>y)
39 | return y;
40 | return x;
41 | }
42 | float max(float x,float y)
43 | {
44 | if(x>y)
45 | return x;
46 | return y;
47 | }
48 |
49 |
50 | void PresetSketch::paintEvent(QPaintEvent *)
51 | {
52 |
53 | if (!m_preset)
54 | {
55 | return;
56 | }
57 | QPainter painter(this);
58 | painter.setRenderHint(QPainter::Antialiasing);
59 | float scale_factor=min(this->width()/def_width,this->height()/def_height);
60 | float shiftx=0,shifty=0;
61 | if (this->width()/def_width > this->height()/def_height)
62 | {
63 | shiftx=(this->width()-scale_factor*def_width)/2;
64 | }
65 | else
66 | {
67 | shifty=(this->height()-scale_factor*def_height)/2;
68 | }
69 |
70 | float eyesep=m_preset->getEyeSeperation();
71 | float lefteyex=def_width/2-eyesep/2;
72 | float obs_dist=m_preset->getObserverDistance();
73 | //two eyes
74 | painter.drawEllipse(shiftx+scale_factor*(lefteyex-eye_size/2),shifty+scale_factor*1,scale_factor*eye_size,scale_factor*eye_size);
75 | painter.drawEllipse(shiftx+scale_factor*(lefteyex-eye_size/2+eyesep),shifty+scale_factor*1,scale_factor*eye_size,scale_factor*eye_size);
76 | //screen
77 | float screen_width= m_preset->getResultWidth()/(float)m_preset->getDotsPerInch();
78 | painter.drawLine(shiftx+scale_factor*(def_width/2-screen_width/2),shifty+scale_factor*(1+eye_size/2+obs_dist),shiftx+scale_factor*(def_width/2+screen_width/2),shifty+scale_factor*(1+eye_size/2+obs_dist));
79 | float max_depth=m_preset->getMaximumDepth();
80 | float min_depth=m_preset->getMinimumDepth();
81 | bool cross=!m_preset->getIsParallel();
82 | QVector h_proccessed;
83 | QPointF i;
84 | QPoint spoint;
85 | if(!cross)
86 | {
87 | float pxscale=(screen_width-eyesep)*(obs_dist+min_depth)/(2*obs_dist)+(eyesep/2);
88 | foreach (i, m_heights)
89 | {
90 | h_proccessed.append(QPoint (shiftx+scale_factor*(i.x()*pxscale+def_width/2),shifty+scale_factor*(-i.y()*(max_depth-min_depth)+1+eye_size/2+obs_dist+max_depth)));
91 | }
92 |
93 | }
94 | else
95 | {
96 | float in_far=obs_dist+max_depth;
97 | float in_near=obs_dist+min_depth;
98 | float screen_sep_near=(eyesep*min_depth)/in_near;
99 | float screen_sep_far=(eyesep*max_depth)/in_far;
100 | float out_far=(obs_dist*eyesep)/(eyesep+screen_sep_near);
101 | float out_near=(obs_dist*eyesep)/(eyesep+screen_sep_far);
102 | float pxscale=(screen_width+eyesep)*(out_near)/(2*obs_dist)-(eyesep/2);
103 | foreach (i, m_heights)
104 | {
105 | h_proccessed.append(QPoint (shiftx+scale_factor*(i.x()*pxscale+def_width/2),shifty+scale_factor*(-i.y()*(out_far-out_near)+1+eye_size/2+out_far)));
106 | }
107 | }
108 | painter.drawLines(h_proccessed);
109 |
110 | spoint=h_proccessed.at(3);
111 | if(!cross)
112 | {
113 | painter.drawLine(shiftx+scale_factor*(def_width/2-eyesep/2),shifty+scale_factor*(1+eye_size/2),spoint.x(),spoint.y());
114 | painter.drawLine(shiftx+scale_factor*(def_width/2+eyesep/2),shifty+scale_factor*(1+eye_size/2),spoint.x(),spoint.y());
115 | }
116 | else
117 | {
118 | float eyeleftx=shiftx+scale_factor*(def_width/2-eyesep/2);
119 | float eyerightx=shiftx+scale_factor*(def_width/2+eyesep/2);
120 | float eyey=shifty+scale_factor*(1+eye_size/2);
121 | float screeny=shifty+scale_factor*(1+eye_size/2+obs_dist);
122 | float leyes=(-eyeleftx+spoint.x())*(screeny-spoint.y())/(spoint.y()-eyey)+spoint.x();
123 | float reyes=(-eyerightx+spoint.x())*(screeny-spoint.y())/(spoint.y()-eyey)+spoint.x();
124 | painter.drawLine(eyeleftx,eyey,leyes,screeny);
125 | painter.drawLine(eyerightx,eyey,reyes,screeny);
126 | }
127 | }
128 |
129 | void PresetSketch::presetUpdated()
130 | {
131 | repaint();
132 | }
133 |
--------------------------------------------------------------------------------
/stereograma.svg:
--------------------------------------------------------------------------------
1 |
2 |
79 |
--------------------------------------------------------------------------------
/imagecontainerwidget.cpp:
--------------------------------------------------------------------------------
1 | #include "imagecontainerwidget.h"
2 | #include
3 | #include
4 | #include
5 | #include "imagefiledialog.h"
6 | #include
7 | #include
8 |
9 | #include
10 | #if QT_VERSION >= QT_VERSION_CHECK(5,15,1)
11 | #define WEBP_FILTER " *.webp *.WEBP"
12 | #else
13 | #define WEBP_FILTER ""
14 | #endif
15 |
16 |
17 | ImageContainerWidget::ImageContainerWidget(QWidget *parent) :
18 | QLabel(parent)
19 | {
20 |
21 | connect(&netManager, SIGNAL(finished(QNetworkReply*)),
22 | SLOT(downloadFinished(QNetworkReply*)));
23 | connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
24 | SLOT(showContextMenu(const QPoint&)));
25 | _loadAction=myMenu.addAction("Load");
26 | _saveAsAction=myMenu.addAction("Save As...");
27 | _viewAction=myMenu.addAction("View");
28 | _unloadAction=myMenu.addAction("Unload");
29 | m_viewer=new ImageViewer(this);
30 | setAcceptDrops(true);
31 | }
32 | const QString & ImageContainerWidget::getText()
33 | {
34 | if (replaceText.isNull())
35 | {
36 | replaceText=text();
37 | }
38 | return replaceText;
39 | }
40 |
41 |
42 | void ImageContainerWidget::mySetPixmap()
43 | {
44 | if (replaceText.isNull())
45 | {
46 | replaceText=text();
47 | }
48 | if (imdata.isNull())
49 | {
50 | setAlignment(Qt::AlignLeft | Qt::AlignTop);
51 | setText(replaceText);
52 | }
53 | else
54 | {
55 | setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
56 | setScaledContents(false);
57 | QSize size = QSize(width(),height());
58 | QImage smallimage=imdata.convertToFormat(QImage::Format_ARGB32).scaled(size, Qt::KeepAspectRatio);
59 | setPixmap(QPixmap::fromImage(smallimage));
60 |
61 | }
62 | }
63 | void ImageContainerWidget::setImage(const QString &fileName)
64 | {
65 | if(!imdata.load(fileName))
66 | QMessageBox::warning(this,"Error","Unrecognized image format");
67 | mySetPixmap();
68 | }
69 |
70 | void ImageContainerWidget::setImage(const QImage &image)
71 | {
72 | imdata=image;
73 | mySetPixmap();
74 | }
75 |
76 | void ImageContainerWidget::downloadFinished(QNetworkReply* reply)
77 | {
78 | if (!reply->error())
79 | {
80 | if(!imdata.load((QIODevice*)reply,0))
81 | QMessageBox::warning(this,"Error","Unrecognized image format");
82 | mySetPixmap();
83 | }
84 | else
85 | {
86 | QMessageBox::warning(this,"Error","Could not download the file");
87 | }
88 | reply->deleteLater();
89 | }
90 | void ImageContainerWidget::showContextMenu(const QPoint& pos)
91 | {
92 | QPoint globalPos = mapToGlobal(pos);
93 | QAction* selectedItem = myMenu.exec(globalPos);
94 | if (selectedItem == _saveAsAction)
95 | {
96 | saveDialog();
97 | }
98 | else if (selectedItem == _unloadAction)
99 | {
100 | imdata= QImage();
101 | mySetPixmap();
102 | }
103 | else if(selectedItem== _loadAction)
104 | {
105 | openDialog();
106 | }
107 | else if(selectedItem== _viewAction)
108 | {
109 | m_viewer->setFolderSettings(folderSettings);
110 | m_viewer->setSaveTitle(saveTitle);
111 | m_viewer->setImage(imdata);
112 | m_viewer->show();
113 | }
114 | }
115 |
116 |
117 |
118 | void ImageContainerWidget::saveDialog()
119 | {
120 | saveAsImage();
121 | }
122 |
123 | void ImageContainerWidget::openDialog()
124 | {
125 | QSettings settings;
126 | QString cdir=settings.value(folderSettings,folderSettings).toString();
127 |
128 | ImageFileDialog dlg(this);
129 |
130 | dlg.init();
131 | dlg.setFileMode( QFileDialog::ExistingFile);
132 | dlg.setAcceptMode(QFileDialog::AcceptOpen);
133 | dlg.setDirectory(cdir);
134 | dlg.setNameFilter(tr("Images (*.png *.xpm *.jpg *.jpeg *.bmp *.gif *.tiff *.tif *.PNG *.XPM *.JPG *.JPEG *.BMP *.GIF *.TIF *.TIFF" WEBP_FILTER ")"));
135 | dlg.setWindowTitle("Open "+getText());
136 | QString fileName;
137 |
138 | if (dlg.exec())
139 | {
140 | fileName = dlg.selectedFiles().first();
141 | settings.setValue(folderSettings, QFileInfo(fileName).absoluteDir().absolutePath());
142 | setImage(fileName);
143 | }
144 | dlg.deinit();
145 |
146 | }
147 |
148 | void ImageContainerWidget::mouseDoubleClickEvent(QMouseEvent * )
149 | {
150 | openDialog();
151 | }
152 | void ImageContainerWidget::dragEnterEvent(QDragEnterEvent *event)
153 | {
154 | if (event->mimeData()->hasFormat("text/uri-list"))
155 | event->acceptProposedAction();
156 | }
157 | void ImageContainerWidget::dropEvent(QDropEvent *event)
158 | {
159 | QList urls = event->mimeData()->urls();
160 | if (urls.isEmpty())
161 | return;
162 | QString fileName = urls.first().toLocalFile();
163 | if (fileName.isEmpty())
164 | {
165 | QNetworkRequest request(urls.first());
166 | netManager.get(request);
167 | }
168 | else
169 | {
170 | setImage(fileName);
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/presetedit.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | PresetEdit
4 |
5 |
6 |
7 | 0
8 | 0
9 | 244
10 | 298
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
20 | Cross eyed
21 |
22 |
23 |
24 | -
25 |
26 |
27 |
28 |
29 |
30 |
31 | -
32 |
33 |
34 | Eye seperation (in)
35 |
36 |
37 |
38 | -
39 |
40 |
41 | 1.500000000000000
42 |
43 |
44 | 3.000000000000000
45 |
46 |
47 | 0.100000000000000
48 |
49 |
50 | 2.500000000000000
51 |
52 |
53 |
54 | -
55 |
56 |
57 | Observer distance (in)
58 |
59 |
60 |
61 | -
62 |
63 |
64 | 16.000000000000000
65 |
66 |
67 | 26.000000000000000
68 |
69 |
70 | 0.500000000000000
71 |
72 |
73 | 22.000000000000000
74 |
75 |
76 |
77 | -
78 |
79 |
80 | Maximum depth (in)
81 |
82 |
83 |
84 | -
85 |
86 |
87 | 6.000000000000000
88 |
89 |
90 | 22.000000000000000
91 |
92 |
93 | 0.250000000000000
94 |
95 |
96 | 8.000000000000000
97 |
98 |
99 |
100 | -
101 |
102 |
103 | Minimum depth (in)
104 |
105 |
106 |
107 | -
108 |
109 |
110 | 3.000000000000000
111 |
112 |
113 | 8.000000000000000
114 |
115 |
116 | 0.250000000000000
117 |
118 |
119 |
120 | -
121 |
122 |
123 | Image width (pixels)
124 |
125 |
126 |
127 | -
128 |
129 |
130 | 320
131 |
132 |
133 | 4096
134 |
135 |
136 | 4
137 |
138 |
139 | 2048
140 |
141 |
142 |
143 | -
144 |
145 |
146 | Image height (pixels)
147 |
148 |
149 |
150 | -
151 |
152 |
153 | 240
154 |
155 |
156 | 4096
157 |
158 |
159 | 4
160 |
161 |
162 | 1536
163 |
164 |
165 |
166 | -
167 |
168 |
169 | dots per inch
170 |
171 |
172 |
173 | -
174 |
175 |
176 | 50
177 |
178 |
179 | 600
180 |
181 |
182 | 150
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/FormulaGen.cpp:
--------------------------------------------------------------------------------
1 | #include "FormulaGen.h"
2 | #include "ui_FormulaGen.h"
3 | #include "exprtk/exprtk.hpp"
4 | #include "stereomaker.h"
5 | #include "mainwindow.h"
6 | #include
7 | #include
8 | #include
9 |
10 | typedef exprtk::symbol_table symbol_table_t;
11 | typedef exprtk::expression expression_t;
12 | typedef exprtk::parser parser_t;
13 |
14 | FormulaGen::FormulaGen(QWidget *parent) :
15 | QMainWindow(parent),
16 | ui(new Ui::FormulaGen)
17 | {
18 | ui->setupUi(this);
19 | setBasicImageParent(this);
20 | setSaveTitle("Formula Depth Image");
21 | setFolderSettings("depthmaps");
22 | QSettings settings;
23 | //settings.remove("formula");
24 | formulaList=settings.value("formula",QStringList()<<"0.5+0.5*sin( 100*(((x-0.5)*w/h)^2+(y-0.5)^2)^0.5)"<<
25 | "var f :=sin(x*2*pi)*0.3;\n"
26 | "var multip := 3.333;\n"
27 | "(f>abs((y-0.5)))*(0.5+0.5*multip*sqrt(f*f-(y-0.5)*(y-0.5)))+(-f>abs((y-0.5)))*(0.5-0.5*multip*sqrt(f*f-(y-0.5)*(y-0.5)))"<<
28 | "var x0 := (x*w/h-0.8)*4;\n"
29 | "var y0 := (y-0.5)*4;\n"
30 | "var tx := x0;\n"
31 | "var ty := y0;\n"
32 | "var temp := 0;\n"
33 | "for(var i :=0; i <=8;i+=1)\n"
34 | "{\n"
35 | "temp := tx*tx-ty*ty+x0;\n"
36 | "ty := 2*tx*ty+y0;\n"
37 | "tx := temp;\n"
38 | "}\n"
39 | "(tx*tx+ty*ty)*0.1").toStringList();
40 | ui->listWidget->addItems(formulaList);
41 | ui->formulaPText->setPlainText(formulaList.last());
42 | }
43 |
44 | FormulaGen::~FormulaGen()
45 | {
46 | delete ui;
47 | }
48 |
49 | int FormulaGen::getOutputImageWidth()
50 | {
51 | return ui->widthSpin->value();
52 | }
53 |
54 | int FormulaGen::getOutputImageHeight()
55 | {
56 | return ui->heightSpin->value();
57 | }
58 |
59 | void FormulaGen::on_generatePb_clicked()
60 | {
61 | ui->errorTable->clearContents();
62 | ui->errorTable->setRowCount(0);
63 | int w=getOutputImageWidth();
64 | int h=getOutputImageHeight();
65 | QString formule_str=ui->formulaPText->toPlainText();
66 | QByteArray formula_ba=formule_str.toLatin1();
67 | const char* formula_buf=formula_ba.constData();
68 | imdata=QImage(w,h,QImage::Format_RGB32);
69 |
70 | float x_s, y_s;
71 | float f_w=w, f_h=h;
72 |
73 | symbol_table_t symbol_table;
74 | symbol_table.add_pi();
75 | symbol_table.add_constant("e", M_E);
76 | symbol_table.add_variable("x", x_s);
77 | symbol_table.add_variable("y", y_s);
78 | symbol_table.add_variable("w", f_w);
79 | symbol_table.add_variable("h", f_h);
80 | expression_t expression;
81 |
82 | expression.register_symbol_table(symbol_table);
83 | parser_t::settings_store sstore;
84 | sstore.disable_all_logic_ops();
85 | //sstore.disable_all_assignment_ops();
86 | sstore.disable_all_control_structures();
87 | sstore.enable_control_structure(parser_t::settings_store::e_ctrl_for_loop);
88 | parser_t parser(sstore);
89 |
90 | bool compile_valid=parser.compile(formula_buf, expression);
91 | if (compile_valid)
92 | {
93 | int val;
94 | for (int x=0;x255)
105 | val=255;
106 | imdata.setPixel(x,y,0xff000000|(val<<16)|(val<<8)|val);
107 | }
108 | }
109 | //imdata=imdata.convertToFormat(QImage::Format_Indexed8,StereoMaker::getGrayScale());
110 | ui->imageViewArea->setPixmap(QPixmap::fromImage(imdata));
111 | if (!formulaList.contains(formule_str))
112 | {
113 | formulaList<listWidget->addItem(formule_str);
117 | }
118 |
119 |
120 | }
121 | else {
122 | ui->errorTable->setRowCount(parser.error_count());
123 | ui->errorTable->setColumnCount(3);
124 | QTextCursor cursor = ui->formulaPText->textCursor();
125 |
126 |
127 |
128 | for (std::size_t i = 0; i < parser.error_count(); ++i)
129 | {
130 | typedef exprtk::parser_error::type error_t;
131 |
132 | error_t error = parser.get_error(i);
133 |
134 | /*printf("Error[%02d] Position: %02d Type: [%14s] Msg: %s\n",
135 | (int)i,
136 | (int)error.token.position,
137 | exprtk::parser_error::to_str(error.mode).c_str(),
138 | error.diagnostic.c_str());*/
139 | cursor.setPosition(error.token.position);
140 | ui->errorTable->setItem(i,0,new QTableWidgetItem(QString::number(error.token.position)+QString(" [%1,%2]").arg(cursor.blockNumber()+1).arg(cursor.positionInBlock())));
141 | ui->errorTable->setItem(i,1,new QTableWidgetItem(tr(exprtk::parser_error::to_str(error.mode).c_str())));
142 | ui->errorTable->setItem(i,2,new QTableWidgetItem(tr(error.diagnostic.c_str())));
143 |
144 | }
145 | cursor.setPosition(parser.get_error(0).token.position);
146 | cursor.movePosition(QTextCursor::Right,QTextCursor::KeepAnchor);
147 | ui->formulaPText->setTextCursor(cursor);
148 |
149 |
150 |
151 | }
152 | }
153 |
154 | void FormulaGen::on_actionSave_Image_triggered()
155 | {
156 | saveAsImage();
157 | }
158 |
159 | void FormulaGen::on_actionPush_Image_triggered()
160 | {
161 | ((MainWindow*)parentWidget())->setDepthImage(imdata);
162 | }
163 |
164 | void FormulaGen::on_actionPush_Image_as_Compose_Pattern_triggered()
165 | {
166 | ((MainWindow*)parentWidget())->setComposePattern(imdata);
167 | }
168 |
169 | void FormulaGen::on_listWidget_itemActivated(QListWidgetItem *item)
170 | {
171 | ui->formulaPText->setPlainText(item->text());
172 | }
173 |
--------------------------------------------------------------------------------
/FormulaGen.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | FormulaGen
4 |
5 |
6 |
7 | 0
8 | 0
9 | 596
10 | 701
11 |
12 |
13 |
14 | Formula
15 |
16 |
17 |
18 | -
19 |
20 |
-
21 |
22 |
-
23 |
24 |
25 |
26 | 0
27 | 0
28 |
29 |
30 |
31 | <html><head/><body><p>x=[0..1]</p><p>y=[0..1]</p><p>w=Width</p><p>h=Height</p><p><span style=" font-weight:600;">output</span> => [0..1]</p><p>see <a href="https://github.com/ArashPartow/exprtk"><span style=" text-decoration: underline; color:#0000ff;">ExprTk manual</span></a></p><p>for function list.</p></body></html>
32 |
33 |
34 | Qt::RichText
35 |
36 |
37 | true
38 |
39 |
40 |
41 | -
42 |
43 |
-
44 |
45 |
46 | Width
47 |
48 |
49 |
50 | -
51 |
52 |
53 |
54 | 90
55 | 16777215
56 |
57 |
58 |
59 | 64
60 |
61 |
62 | 4096
63 |
64 |
65 | 2048
66 |
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
-
74 |
75 |
76 | Height
77 |
78 |
79 |
80 | -
81 |
82 |
83 |
84 | 90
85 | 16777215
86 |
87 |
88 |
89 | 64
90 |
91 |
92 | 4096
93 |
94 |
95 | 1536
96 |
97 |
98 |
99 |
100 |
101 | -
102 |
103 |
104 | Generate
105 |
106 |
107 |
108 |
109 |
110 | -
111 |
112 |
113 |
114 | 0
115 | 0
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | -
124 |
125 |
-
126 |
127 |
128 | History
129 |
130 |
131 |
132 | -
133 |
134 |
135 | true
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | -
144 |
145 |
146 | errors:
147 |
148 |
149 |
150 | -
151 |
152 |
153 | QAbstractItemView::NoEditTriggers
154 |
155 |
156 | QAbstractItemView::SingleSelection
157 |
158 |
159 | QAbstractItemView::SelectRows
160 |
161 |
162 | false
163 |
164 |
165 | true
166 |
167 |
168 |
169 | Position
170 |
171 |
172 |
173 |
174 | Type
175 |
176 |
177 |
178 |
179 | Msg
180 |
181 |
182 |
183 |
184 | -
185 |
186 |
187 |
188 | 0
189 | 0
190 |
191 |
192 |
193 |
194 | 360
195 | 240
196 |
197 |
198 |
199 | QFrame::Panel
200 |
201 |
202 | QFrame::Raised
203 |
204 |
205 |
206 |
207 |
208 | true
209 |
210 |
211 | Qt::AlignCenter
212 |
213 |
214 |
215 |
216 |
217 |
236 |
237 |
238 |
239 |
240 | :/images/save.png:/images/save.png
241 |
242 |
243 | Save Image...
244 |
245 |
246 | true
247 |
248 |
249 |
250 |
251 | Push Image as Depth Map
252 |
253 |
254 |
255 |
256 | Push Image as Compose Pattern
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
--------------------------------------------------------------------------------
/anaglyphmaker.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | AnaglyphMaker
4 |
5 |
6 |
7 | 0
8 | 0
9 | 558
10 | 407
11 |
12 |
13 |
14 | Make an Anaglyph
15 |
16 |
17 |
18 | -
19 |
20 |
-
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 0
29 | 153
30 | 255
31 |
32 |
33 |
34 |
35 |
36 |
37 | 0
38 | 153
39 | 255
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | 0
49 | 153
50 | 255
51 |
52 |
53 |
54 |
55 |
56 |
57 | 0
58 | 153
59 | 255
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 159
69 | 158
70 | 158
71 |
72 |
73 |
74 |
75 |
76 |
77 | 0
78 | 153
79 | 255
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | Qt::CustomContextMenu
88 |
89 |
90 | QFrame::Box
91 |
92 |
93 | QFrame::Sunken
94 |
95 |
96 | Left
97 |
98 |
99 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
100 |
101 |
102 |
103 | -
104 |
105 |
106 |
107 | 0
108 | 0
109 |
110 |
111 |
112 | swap between left and right
113 |
114 |
115 | swap left and right
116 |
117 |
118 |
119 |
120 |
121 |
122 | :/images/swap.png:/images/swap.png
123 |
124 |
125 |
126 | 24
127 | 24
128 |
129 |
130 |
131 | true
132 |
133 |
134 | false
135 |
136 |
137 |
138 | -
139 |
140 |
141 |
142 | 0
143 | 0
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | 255
153 | 255
154 | 255
155 |
156 |
157 |
158 |
159 |
160 |
161 | 255
162 | 255
163 | 255
164 |
165 |
166 |
167 |
168 |
169 |
170 | 255
171 | 255
172 | 255
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | 255
182 | 255
183 | 255
184 |
185 |
186 |
187 |
188 |
189 |
190 | 255
191 | 255
192 | 255
193 |
194 |
195 |
196 |
197 |
198 |
199 | 255
200 | 255
201 | 255
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | 159
211 | 158
212 | 158
213 |
214 |
215 |
216 |
217 |
218 |
219 | 159
220 | 158
221 | 158
222 |
223 |
224 |
225 |
226 |
227 |
228 | 255
229 | 255
230 | 255
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 | Qt::CustomContextMenu
239 |
240 |
241 | QFrame::Box
242 |
243 |
244 | QFrame::Sunken
245 |
246 |
247 | Right
248 |
249 |
250 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
251 |
252 |
253 |
254 |
255 |
256 | -
257 |
258 |
259 | Merge
260 |
261 |
262 |
263 |
264 |
265 |
275 |
276 |
277 |
278 |
279 | ImageContainerWidget
280 | QLabel
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
--------------------------------------------------------------------------------
/mainwindow.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 | #include "ui_mainwindow.h"
3 | #include "stereomaker.h"
4 |
5 | #include "imageviewer.h"
6 | #include "modeldepthviewer.h"
7 | #include "anaglyphmaker.h"
8 | #include "FormulaGen.h"
9 | #include "stringtype.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | MainWindow::MainWindow(QWidget *parent) :
19 | QMainWindow(parent),
20 | ui(new Ui::MainWindow)
21 | {
22 | ui->setupUi(this);
23 | ui->presetSelect->addItem(QString("Default"));
24 | loadPresets();
25 | ui->depthImage->setBasicImageParent(this);
26 | ui->depthImage->setFolderSettings("depthmaps");
27 | ui->depthImage->setSaveTitle("Depth Map");
28 | ui->composeImage->setBasicImageParent(this);
29 | ui->composeImage->setFolderSettings("compose");
30 | ui->composeImage->setSaveTitle("Depth Compose");
31 | ui->textureImage->setBasicImageParent(this);
32 | ui->textureImage->setFolderSettings("textures");
33 | ui->textureImage->setSaveTitle("Texture");
34 | QObject::connect(ui->presetEdit,SIGNAL(onEdited()),ui->presetSketcher,SLOT(presetUpdated()));
35 | }
36 |
37 | MainWindow::~MainWindow()
38 | {
39 | delete ui;
40 | Preset *temp;
41 | foreach (temp,m_presets)
42 | delete temp;
43 | }
44 |
45 | void MainWindow::setDepthImage(const QImage &image)
46 | {
47 | ui->depthImage->setImage(image);
48 | }
49 | void MainWindow::setComposePattern(const QImage &image)
50 | {
51 | ui->composeImage->setImage(image);
52 | }
53 |
54 |
55 | void MainWindow::on_renderButton_clicked()
56 | {
57 |
58 | StereoMaker smaker;
59 | if (ui->depthImage->getImage().isNull() || ui->textureImage->getImage().isNull())
60 | {
61 | QMessageBox::warning(this,"Error","Please first load both texture and depth images");
62 | }
63 | else
64 | {
65 | QImage depth_image=ui->depthImage->getImage().convertToFormat(QImage::Format_Indexed8,smaker.getGrayScale());
66 | depth_image=depth_image.scaled(cur_preset->getResultWidth(),cur_preset->getResultHeight());
67 | if (!ui->composeImage->getImage().isNull())
68 | {
69 | float compose_height = ui->composeLevel->value()/100.0;
70 | float compose_scale = ui->composeScale->value()/128.0;
71 | QImage compose_image=ui->composeImage->getImage();
72 | if (compose_scale!=1)
73 | {
74 | //compose_image = compose_image.scaledToWidth((int)(compose_image.width()*compose_scale),Qt::FastTransformation);
75 | compose_image = compose_image.scaled((int)(compose_image.width()*compose_scale),(int)(compose_image.height()*compose_scale),Qt::KeepAspectRatio,Qt::SmoothTransformation);
76 | }
77 | compose_image=compose_image.convertToFormat(QImage::Format_Indexed8,smaker.getGrayScale());
78 | smaker.composeDepth(depth_image,compose_image,compose_height);
79 | }
80 | ImageViewer * imview=new ImageViewer(this);
81 | imview->setWindowTitle("Result");
82 | imview->setFolderSettings("stereograms");
83 | imview->setSaveTitle("Stereogram");
84 | if (!cur_preset->getIsParallel())
85 | depth_image.invertPixels();
86 | const QImage *eye_helper_left=0;
87 | const QImage *eye_helper_right=0;
88 | bool show_helpers = ui->show_helpers->isChecked();
89 | bool margin_helpers = show_helpers && ui->margin_helpers->isChecked();
90 | QImage eye_helper_image_left=ui->helpers_image->getImage();
91 | QImage eye_helper_image_right;
92 | if (show_helpers)
93 | {
94 | if(!eye_helper_image_left.isNull())
95 | {
96 | if (ui->dual_helpers->isChecked())
97 | {
98 | int half_width=eye_helper_image_left.width()/2;
99 | int height=eye_helper_image_left.height();
100 | eye_helper_image_right=eye_helper_image_left.copy(half_width,0,half_width,height);
101 | eye_helper_image_left=eye_helper_image_left.copy(0,0,half_width,height);
102 |
103 | if (cur_preset->getIsParallel())
104 | {
105 | eye_helper_left=&eye_helper_image_left;
106 | eye_helper_right=&eye_helper_image_right;
107 | }
108 | else
109 | {
110 | eye_helper_right=&eye_helper_image_left;
111 | eye_helper_left=&eye_helper_image_right;
112 | }
113 | }
114 | else
115 | {
116 | eye_helper_left=&eye_helper_image_left;
117 | eye_helper_right=&eye_helper_image_left;
118 | }
119 | }
120 |
121 | }
122 | QImage result =smaker.render(depth_image, ui->textureImage->getImage(),cur_preset,ui->parallelProgress,eye_helper_right,eye_helper_left,show_helpers,margin_helpers);
123 | imview->setImage(result);
124 | imview->show();
125 | }
126 | }
127 |
128 |
129 | void MainWindow::on_action_obj_triggered()
130 | {
131 | QSettings settings;
132 | QString setting_name="objdir";
133 | QString cdir=settings.value(setting_name,"models/").toString();
134 |
135 | QString fileName = QFileDialog::getOpenFileName(parentWidget(), "Load Obj file", cdir, tr("OBJ File (*.obj *.OBJ)"));
136 | Model3D *m3d;
137 | if(fileName!="")
138 | {
139 | settings.setValue(setting_name, QFileInfo(fileName).absoluteDir().absolutePath());
140 | m3d = new Model3D();
141 | m3d->LoadObj(fileName);
142 | ModelDepthViewer * modelviewer=new ModelDepthViewer(this);
143 | modelviewer->setModel(m3d);
144 | modelviewer->show();
145 | }
146 |
147 | }
148 |
149 |
150 | void MainWindow::on_action_ply_triggered()
151 | {
152 | QSettings settings;
153 | QString setting_name="objdir";
154 | QString cdir=settings.value(setting_name,"models/").toString();
155 | QString fileName = QFileDialog::getOpenFileName(parentWidget(), "Load Ply file", cdir, tr("PLY File (*.ply *.PLY)"));
156 | Model3D *m3d;
157 | if(fileName!="")
158 | {
159 | settings.setValue(setting_name, QFileInfo(fileName).absoluteDir().absolutePath());
160 | m3d = new Model3D();
161 | m3d->LoadPly(fileName);
162 | ModelDepthViewer * modelviewer=new ModelDepthViewer(this);
163 | modelviewer->setModel(m3d);
164 | modelviewer->show();
165 | }
166 | }
167 |
168 | void MainWindow::on_actionLoad_Texture_triggered()
169 | {
170 | ui->textureImage->openDialog();
171 | }
172 |
173 | void MainWindow::on_actionLoad_Depth_Map_triggered()
174 | {
175 | ui->depthImage->openDialog();
176 | }
177 |
178 | void MainWindow::on_actionCreate_Anaglyph_triggered()
179 | {
180 | AnaglyphMaker * anaglyphWindow=new AnaglyphMaker();
181 | anaglyphWindow->show();
182 | }
183 |
184 | void MainWindow::loadPresets()
185 | {
186 | cur_preset=new Preset(QString("Default"));
187 | m_presets.append(cur_preset);
188 | ui->presetEdit->setPreset(cur_preset);
189 | ui->presetSketcher->setPreset(cur_preset);
190 | QFile file(SETTINGS_FILE);
191 | if (!file.open(QIODevice::ReadOnly))
192 | return;
193 | QDataStream in(&file);
194 | int size;
195 | in>>size;
196 | Preset * temp_preset;
197 | for(;size>0;size--)
198 | {
199 | temp_preset=new Preset(in);
200 | m_presets.append(temp_preset);
201 | ui->presetSelect->addItem(temp_preset->getName());
202 | }
203 | file.close();
204 | }
205 |
206 | void MainWindow::savePresets()
207 | {
208 | QFile file(SETTINGS_FILE);
209 | if (!file.open(QIODevice::WriteOnly))
210 | return;
211 | QDataStream out(&file);
212 | int size=m_presets.size()-1;
213 | out<toStream(out);
218 | }
219 | file.close();
220 | }
221 | void MainWindow::on_actionAdd_preset_triggered()
222 | {
223 | StringType stdialog("Select Preset Name",this);
224 | if (stdialog.exec()==QDialog::Accepted)
225 | {
226 | Preset * temp_preset=new Preset(stdialog.getString());
227 | m_presets.append(temp_preset);
228 | ui->presetSelect->addItem(temp_preset->getName());
229 | }
230 | }
231 |
232 | void MainWindow::on_presetSelect_currentIndexChanged(int index)
233 | {
234 | if(indexpresetEdit->setPreset(cur_preset);
238 | ui->presetSketcher->setPreset(cur_preset);
239 | }
240 | }
241 |
242 |
243 | void MainWindow::on_actionSave_Presets_triggered()
244 | {
245 | savePresets();
246 | }
247 |
248 | void MainWindow::on_actionReset_triggered()
249 | {
250 | ui->presetSketcher->setPreset(0);
251 | Preset *temp;
252 | foreach (temp,m_presets)
253 | delete temp;
254 | m_presets.clear();
255 | int size=ui->presetSelect->count()-1;
256 | for(;size>0;size--)
257 | {
258 | ui->presetSelect->removeItem(size);
259 | }
260 |
261 | loadPresets();
262 | }
263 |
264 | void MainWindow::on_actionRename_Preset_triggered()
265 | {
266 | int index=ui->presetSelect->currentIndex();
267 | if(index>0)
268 | {
269 | StringType stdialog("Rename Preset",this);
270 | if (stdialog.exec()==QDialog::Accepted)
271 | {
272 | QString input_string=stdialog.getString();
273 | ui->presetSelect->setItemText(index,input_string);
274 | m_presets.at(index)->setName(input_string);
275 | }
276 | }
277 | }
278 |
279 | void MainWindow::on_actionRemove_preset_triggered()
280 | {
281 | int index=ui->presetSelect->currentIndex();
282 | if(index>0)
283 | {
284 | m_presets.removeAt(index);
285 | ui->presetSelect->removeItem(index);
286 | }
287 | }
288 |
289 | void MainWindow::on_actionGenerate_Depth_Map_triggered()
290 | {
291 | FormulaGen * formulaWindow=new FormulaGen(this);
292 | formulaWindow->show();
293 | }
294 |
295 | void MainWindow::on_rolling_clicked()
296 | {
297 | QDesktopServices::openUrl(QUrl("https://play.google.com/store/apps/details?id=com.github.gnudles.rollingmarbles"));
298 | }
299 |
300 | void MainWindow::on_show_helpers_toggled(bool checked)
301 | {
302 |
303 | ui->helpers_image->setDisabled(!checked);
304 | ui->dual_helpers->setDisabled(!checked);
305 | ui->margin_helpers->setDisabled(!checked);
306 | }
307 |
--------------------------------------------------------------------------------
/stereomaker.cpp:
--------------------------------------------------------------------------------
1 | //algorithm was taken from http://www.techmind.org/stereo/stech.html
2 | #include "stereomaker.h"
3 | #include
4 | #include
5 |
6 |
7 | QVector StereoMaker::grayscale;
8 |
9 | StereoMaker::StereoMaker()
10 | {
11 | depthsep= new int [256];
12 | }
13 |
14 | StereoMaker::~StereoMaker()
15 | {
16 | delete [] depthsep;
17 | }
18 |
19 | void StereoMaker::composeDepth(QImage & depth,QImage & compose,float compose_height)
20 | {
21 | int dw=depth.width(),dh=depth.height(),cw=compose.width(),ch=compose.height();
22 | int x,y,cy=0;
23 | uchar * cptr;
24 | uchar * dptr;
25 | uchar * dchunk;
26 | uchar * dchunkend;
27 | uchar * ccptr;
28 | for(y=0;y *dchunk)
42 | *dchunk=value;
43 | dchunk++;
44 | ccptr++;
45 | }
46 | }
47 | if (x *dchunk)
56 | *dchunk=value;
57 | dchunk++;
58 | ccptr++;
59 | }
60 | }
61 | cy++;
62 | if (cy==ch)
63 | cy=0;
64 | }
65 |
66 | }
67 |
68 | const QVector & StereoMaker::getGrayScale()
69 | {
70 | if (StereoMaker::grayscale.isEmpty())
71 | {
72 | int colorsetter;
73 | for (colorsetter = 0 ; colorsetter < 256 ; colorsetter++)
74 | StereoMaker::grayscale.append(qRgb(colorsetter,colorsetter,colorsetter));
75 | }
76 | return StereoMaker::grayscale;
77 | }
78 | void scaleLine(uchar* big,const uchar* original,int sizeoriginal)
79 | {
80 | *big=*original;
81 | big++;
82 | sizeoriginal--;
83 | while(sizeoriginal>0)
84 | {
85 | sizeoriginal--;
86 | *big=((*original)*3+(*(original+1)))/4;
87 | big++;
88 | *big=((*original)+3*(*(original+1)))/4;
89 | original++;
90 | big++;
91 | }
92 | *big=*original;
93 | }
94 |
95 | QImage StereoMaker::render(const QImage & map, const QImage & ptrn, Preset *psettings, QProgressBar * qpbar, const QImage * eye_helper_right, const QImage * eye_helper_left, bool show_helper, bool helpers_margin)
96 | {
97 | qpbar->setMinimum(0);
98 | qpbar->setMaximum(10);
99 | qpbar->setValue(0);
100 | int width = map.width();
101 | int height = map.height();
102 |
103 | int oversam = 6;
104 | int vwidth = oversam*width*2;
105 |
106 | int x, left;
107 | int y, right;
108 | int *lookL = new int [vwidth];
109 | int *lookR = new int [vwidth];
110 |
111 | int dpi = psettings->getDotsPerInch();
112 | int yShift=dpi/16;
113 | int obsDist;
114 | obsDist=dpi*psettings->getObserverDistance();
115 | int eyeSep;
116 | eyeSep=dpi*psettings->getEyeSeperation();
117 | int veyeSep=eyeSep*oversam*2;
118 |
119 | int maxdepth=dpi*psettings->getMaximumDepth();
120 | int vmaxsep=(int)(((long)oversam*eyeSep*maxdepth*2)/(maxdepth+obsDist));
121 | int maxsep=vmaxsep/(oversam*2); // pattern must be at
122 | // least this wide
123 |
124 |
125 | QImage pattern=ptrn.scaled(vmaxsep/oversam+1,(ptrn.height()*(maxsep+1))/ptrn.width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
126 | if (pattern.depth()!=32)
127 | pattern=pattern.convertToFormat(QImage::Format_ARGB32);
128 | int rh=0;
129 | QImage::Format out_format = pattern.format();
130 | if (show_helper && helpers_margin)
131 | {
132 | if (eye_helper_left==0)
133 | rh=15*psettings->getDotsPerInch()/72;
134 | else
135 | {
136 | rh=eye_helper_left->height();
137 | }
138 | rh=rh*3/2;
139 | out_format=QImage::Format_ARGB32;
140 | }
141 |
142 | QImage result(width,height+rh,out_format);
143 | QImage CurResultLine(vwidth,1,pattern.format());
144 | QImage CurResultScaledLine;//scaled down
145 |
146 | int s=vwidth/2-vmaxsep/2;
147 | int poffset=vmaxsep-(s % vmaxsep);
148 | int pattern_height=pattern.height();
149 |
150 |
151 | int featureZ,sep=0;
152 | bool visual;
153 | int lastlinked;
154 | int progbarval=0;
155 | int maxheight=dpi*(psettings->getMaximumDepth()-psettings->getMinimumDepth());
156 | //benchmark
157 | QElapsedTimer t_time;
158 | t_time.start();
159 | unsigned int **patternptr= new unsigned int *[pattern_height];
160 | for (int i=pattern_height-1;i>=0;i--)
161 | {
162 | patternptr[i]=(unsigned int*)pattern.scanLine(i);
163 | }
164 |
165 | for(int depth_index=0;depth_index<256;depth_index++)
166 | {
167 | featureZ=maxdepth-depth_index*maxheight/256;
168 | depthsep[depth_index]=(int)((veyeSep*featureZ)/(featureZ+obsDist));
169 | }
170 |
171 | uint *dataptr,*lineptr;
172 | uchar * mapptr=(uchar *)malloc(map.width()*2);
173 | for (y=0;y=0) && (rightright) // deeper than current
204 | {
205 | lookL[lookR[left]]=lookR[left]; // break old links
206 | lookR[left]=left;
207 | }
208 | else visual=false;
209 | }
210 | if (visual)
211 | {
212 | lookL[right]=left;
213 | lookR[left]=right;
214 | } // make link
215 | }
216 | }
217 |
218 |
219 |
220 | lastlinked=-10; // dummy initial value
221 |
222 | lineptr=(uint*)CurResultLine.scanLine(0);
223 | dataptr=lineptr+s;
224 | for (x=s; x=0; x--,dataptr--)
245 | {
246 | if (lookR[x]==x)
247 | {
248 | if (lastlinked==(x+1))
249 | *dataptr=*(dataptr+1);
250 | else
251 | {
252 | *dataptr=patternptr[(y+((s-x)/vmaxsep+1)*yShift+pattern_height) % pattern_height][((x+poffset) % vmaxsep)/oversam];
253 | }
254 | }
255 | else
256 | {
257 | *dataptr=*(lineptr+lookR[x]);
258 | lastlinked=x; // keep track of the last pixel to be constrained
259 | }
260 | }
261 |
262 |
263 | CurResultScaledLine = CurResultLine.scaled(width, 1, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
264 | memcpy(result.scanLine(y+rh),CurResultScaledLine.scanLine(0),result.bytesPerLine());
265 | if (progbarval!=10*y/(height-1))
266 | {
267 | progbarval=10*y/(height-1);
268 | qpbar->setValue(progbarval);
269 | }
270 | }
271 | qDebug("Time elapsed: %lld ms", t_time.elapsed());
272 | delete [] lookL;
273 | delete [] lookR;
274 | free(mapptr);
275 | delete [] patternptr;
276 | if (show_helper)
277 | {
278 | QPainter painter(&result);
279 | int rw;
280 | if (eye_helper_left==0)
281 | rw=15*psettings->getDotsPerInch()/72;
282 | else
283 | rw=eye_helper_left->width();
284 | int rect_sep;
285 | if(!psettings->getIsParallel())
286 | {
287 | int mindepth=dpi*psettings->getMinimumDepth();
288 |
289 | rect_sep=(int)(((long)eyeSep*mindepth)/(mindepth+obsDist));
290 | }
291 | else
292 | rect_sep=maxsep;
293 | if (rh == 0)
294 | {
295 | rh = 30;
296 | }
297 | if (eye_helper_left != 0 && eye_helper_right != 0)
298 | {
299 | painter.drawImage(QPoint(result.width()/2-rect_sep/2-rw/2,rh/6),*eye_helper_left);
300 | painter.drawImage(QPoint(result.width()/2+rect_sep/2-rw/2,rh/6),*eye_helper_right);
301 | }
302 | else
303 | {
304 | painter.setPen(QPen(QColor(255,255,255,128)));
305 | painter.drawRect( result.width()/2-rect_sep/2-rw/2, rh/6, rw, rw );
306 | painter.drawRect( result.width()/2+rect_sep/2-rw/2, rh/6, rw, rw );
307 | painter.setPen(QPen(QColor(0,0,0,128)));
308 | painter.drawRect( result.width()/2-rect_sep/2-rw/2+1, rh/6+1, rw-2, rw-2 );
309 | painter.drawRect( result.width()/2+rect_sep/2-rw/2+1, rh/6+1, rw-2, rw-2 );
310 |
311 | painter.fillRect( result.width()/2-rect_sep/2-rw/2+2, rh/6+2, rw-3, rw-3 ,QColor(255,255,255,60));
312 | painter.fillRect( result.width()/2+rect_sep/2-rw/2+2, rh/6+2, rw-3, rw-3 ,QColor(255,255,255,60));
313 | }
314 | }
315 | return result;
316 | }
317 |
--------------------------------------------------------------------------------
/model3d.cpp:
--------------------------------------------------------------------------------
1 | #include "model3d.h"
2 | #if defined(__APPLE__)
3 | #define GL_SILENCE_DEPRECATION
4 | #include
5 | #include
6 | #else
7 | #include
8 | #endif
9 | #include
10 | #include
11 | #include
12 | #include "RPly/rply.h"
13 |
14 | Model3D::Model3D()
15 | {
16 | m_triangles=0;
17 | m_points=0;
18 | m_colors=0;
19 | m_nPoints=0;
20 | m_nTriangles=0;
21 | }
22 |
23 | Model3D::~Model3D()
24 | {
25 | if (m_triangles)
26 | delete [] m_triangles;
27 | if (m_points)
28 | delete [] m_points;
29 | if (m_colors)
30 | delete [] m_colors;
31 | }
32 |
33 | typedef struct
34 | {
35 | unsigned int a;
36 | unsigned int b;
37 | unsigned int c;
38 | } triple;
39 |
40 | void Model3D::LoadObj(const QString & filename)
41 | {
42 | QByteArray _filename=filename.toUtf8();
43 | FILE *fp=fopen(_filename.data(),"r");
44 | if (fp==0)
45 | return;
46 | QVector points;
47 | QVector triangles;
48 | float minX=INT_MAX,maxX=INT_MIN,minY=INT_MAX,maxY=INT_MIN,minZ=INT_MAX,maxZ=INT_MIN;
49 | //if (fp)
50 | {
51 | char buffer[100];
52 | float vtx[3];
53 | unsigned int extraface1,extraface2,extraface3;
54 | int nf;
55 | triple tf, tf_orig;
56 | unsigned int dummy;
57 | while(fgets(buffer,100,fp))
58 | {
59 | if(buffer[0]=='v' && buffer[1]!='n' && buffer[1]!='t')
60 | {
61 | sscanf(buffer+1,"%f %f %f",vtx,vtx+1,vtx+2);
62 | points.append(QVector3D(vtx[0],vtx[1],vtx[2]));
63 | if (vtx[0]maxX)
66 | maxX=vtx[0];
67 | if (vtx[1]maxY)
70 | maxY=vtx[1];
71 | if (vtx[2]maxZ)
74 | maxZ=vtx[2];
75 | }
76 | else if (buffer[0]=='f')
77 | {
78 |
79 | nf=sscanf(buffer+1,"%u %u %u %u %u %u",&tf.a,&tf.b,&tf.c,&extraface1,&extraface2,&extraface3);
80 | if (nf<3)
81 | {
82 | nf=sscanf(buffer+1,"%u/%u %u/%u %u/%u %u/%u %u/%u %u/%u",&tf.a,&dummy,&tf.b,&dummy,&tf.c,&dummy,&extraface1,&dummy,&extraface2,&dummy,&extraface3,&dummy);
83 | nf/=2;
84 | if (nf<3)
85 | {
86 | nf=sscanf(buffer+1,"%u//%u %u//%u %u//%u %u//%u %u//%u %u//%u",&tf.a,&dummy,&tf.b,&dummy,&tf.c,&dummy,&extraface1,&dummy,&extraface2,&dummy,&extraface3,&dummy);
87 | nf/=2;
88 | if (nf<3)
89 | {
90 | nf=sscanf(buffer+1,"%u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u",&tf.a,&dummy,&dummy,&tf.b,&dummy,&dummy,&tf.c,&dummy,&dummy,&extraface1,&dummy,&dummy,&extraface2,&dummy,&dummy,&extraface3,&dummy,&dummy);
91 | nf/=3;
92 | }
93 | }
94 | }
95 | if (nf>=3)
96 | {
97 | triangles.append(tf);
98 | if (nf>=4)
99 | {
100 | tf_orig = tf;
101 | if (nf == 4) //TODO: this is a dummy polygon to triangles conversion. If somebody cares...
102 | {
103 | tf.b=extraface1;
104 | triangles.append(tf);
105 | }
106 | if (nf == 5)
107 | {
108 | tf.a=tf_orig.c;
109 | tf.b=extraface1;
110 | tf.c=extraface2;
111 | triangles.append(tf);
112 | tf.a=extraface2;
113 | tf.b=tf_orig.a;
114 | tf.c=tf_orig.c;
115 | triangles.append(tf);
116 | }
117 | if (nf == 6)
118 | {
119 | tf.a=tf_orig.c;
120 | tf.b=extraface1;
121 | tf.c=extraface2;
122 | triangles.append(tf);
123 | tf.a=extraface2;
124 | tf.b=tf_orig.a;
125 | tf.c=tf_orig.c;
126 | triangles.append(tf);
127 | tf.a=extraface2;
128 | tf.b=tf_orig.a;
129 | tf.c=extraface3;
130 | triangles.append(tf);
131 | }
132 | }
133 | }
134 | }
135 | }
136 | fclose(fp);
137 | }
138 | float xh=(maxX-minX)/2;
139 | float yh=(maxY-minY)/2;
140 | float zh=(maxZ-minZ)/2;
141 | float xshift = maxX-xh;
142 | float yshift = maxY-yh;
143 | float zshift = maxZ-zh;
144 | float scale = 120.0/sqrt(xh*xh+yh*yh+zh*zh+1);
145 |
146 | m_nPoints=points.size();
147 | m_nTriangles=triangles.size();
148 | if (m_triangles)
149 | delete [] m_triangles;
150 | if (m_points)
151 | delete [] m_points;
152 | m_points=new float[m_nPoints*3];
153 | m_colors=new unsigned char[m_nPoints*3];
154 | unsigned char *colorsptr=m_colors;
155 | float *pointsptr=m_points;
156 | m_triangles=new unsigned int [m_nTriangles*3];
157 | unsigned int *trianglesptr=m_triangles;
158 |
159 |
160 | for (unsigned int i=0;i=0)
208 | {
209 | **trianglesptr=(unsigned int)ply_get_argument_value(argument);
210 | ++*trianglesptr;
211 | }
212 |
213 | return 1;
214 | }
215 | void Model3D::LoadPly(const QString &filename)
216 | {
217 |
218 | QByteArray _filename=filename.toUtf8();
219 | p_ply ply = ply_open(_filename.constData(), NULL, 0, NULL);
220 | if (!ply) return;
221 | if (!ply_read_header(ply)) return;
222 | m_nPoints = ply_set_read_cb(ply, "vertex", "x", 0, NULL, 0);
223 | m_nTriangles = ply_set_read_cb(ply, "face", "vertex_indices", 0, NULL, 0);
224 | if (m_triangles)
225 | delete [] m_triangles;
226 | if (m_points)
227 | delete [] m_points;
228 | m_points=new float[m_nPoints*3];
229 | m_colors=new unsigned char[m_nPoints*3];
230 | float* pointsptr=m_points;
231 | m_triangles=new unsigned int [m_nTriangles*3];
232 | unsigned int* trianglesptr=m_triangles;
233 | ply_set_read_cb(ply, "face", "vertex_indices", face_cb, (void*)&trianglesptr, 0);
234 | ply_set_read_cb(ply, "vertex", "x", vertex_cb, (void*)&pointsptr, 0);
235 | ply_set_read_cb(ply, "vertex", "y", vertex_cb, (void*)&pointsptr, 0);
236 | ply_set_read_cb(ply, "vertex", "z", vertex_cb, (void*)&pointsptr, 0);
237 | //printf("%ld\n%ld\n", nvertices, ntriangles);
238 | if (!ply_read(ply)) return;
239 | ply_close(ply);
240 | normalize();
241 | return;
242 |
243 | }
244 |
245 | void Model3D::normalize()
246 | {
247 | float minX=INT_MAX,maxX=INT_MIN,minY=INT_MAX,maxY=INT_MIN,minZ=INT_MAX,maxZ=INT_MIN;
248 | float* pointsptr=m_points;
249 | for (int i=m_nPoints;i>0;--i)
250 | {
251 | if (*pointsptrmaxX)
254 | maxX=*pointsptr;
255 | ++pointsptr;
256 | if (*pointsptrmaxY)
259 | maxY=*pointsptr;
260 | ++pointsptr;
261 | if (*pointsptrmaxZ)
264 | maxZ=*pointsptr;
265 | ++pointsptr;
266 | }
267 | float xh=(maxX-minX)/2;
268 | float yh=(maxY-minY)/2;
269 | float zh=(maxZ-minZ)/2;
270 | float xshift = maxX-xh;
271 | float yshift = maxY-yh;
272 | float zshift = maxZ-zh;
273 | float scale = 120.0/sqrt(xh*xh+yh*yh+zh*zh+1);
274 | pointsptr=m_points;
275 | unsigned char *colorsptr=m_colors;
276 | for (int i=m_nPoints;i>0;--i)
277 | {
278 | *pointsptr = (float)(*pointsptr-xshift)*scale;
279 | *colorsptr=(-*pointsptr+135.0);
280 | pointsptr++;
281 | colorsptr++;
282 | *pointsptr = (float)(*pointsptr-yshift)*scale;
283 | *colorsptr=(*pointsptr+135.0-*(pointsptr-1)/8);
284 | pointsptr++;
285 | colorsptr++;
286 | *pointsptr = (float)(*pointsptr-zshift)*scale;
287 | *colorsptr=(-*pointsptr+135.0-*(pointsptr-2)/8);
288 | pointsptr++;
289 | colorsptr++;
290 | }
291 | }
292 |
293 | void Model3D::DrawGL(bool color)
294 | {
295 | if (color) glEnableClientState(GL_COLOR_ARRAY);
296 | glEnableClientState(GL_VERTEX_ARRAY);
297 | glVertexPointer(3, GL_FLOAT, 0, m_points);
298 | if (color) glColorPointer(3, GL_UNSIGNED_BYTE, 0, m_colors);
299 | glDrawElements(GL_TRIANGLES, m_nTriangles*3, GL_UNSIGNED_INT, m_triangles);
300 | glDisableClientState(GL_VERTEX_ARRAY);
301 | if (color) glDisableClientState(GL_COLOR_ARRAY);
302 | }
303 |
--------------------------------------------------------------------------------
/glmodelview.cpp:
--------------------------------------------------------------------------------
1 | #include "glmodelview.h"
2 | #include "stereomaker.h"
3 | #if defined(__APPLE__)
4 | #define GL_SILENCE_DEPRECATION
5 | #include
6 | #include
7 | #else
8 | #include
9 | #include
10 | #endif
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include "modeldepthviewer.h"
20 | #include "trirender.h"
21 |
22 | GlModelView::GlModelView(QWidget *parent) :
23 | QOpenGLWidget(parent),m_zoom(500),m_contrast(100)
24 | {
25 | m_antialias=true;
26 | m_noShaders=false;
27 | m_new_width=1024;
28 | m_new_height=768;
29 | BasicImageWidget::setBasicImageParent(parent);
30 | QSurfaceFormat glf = QSurfaceFormat::defaultFormat();
31 | glf.setSamples(4);
32 | setFormat(glf);
33 | }
34 |
35 | void GlModelView::initializeGL()
36 | {
37 | if (!(context()) || !context()->isValid())
38 | {
39 | QMessageBox::warning(this,"No OpenGL Driver","Depth Map generation is still available");
40 | }
41 |
42 | if (QOpenGLShader::hasOpenGLShaders(QOpenGLShader::Vertex,context()) )
43 | {
44 | QString declarations= "//uniform mat4 gl_ModelViewMatrix; uniform mat4 gl_ProjectionMatrix; attribute vec4 gl_Vertex;\n";
45 | QString codev= "void main() {gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"\
46 | "float zmax=-1.0;"\
47 | "float zmin=1.0;"\
48 | "float scale=(zmax-zmin);float offs=-zmin;float z=(gl_Position.z/gl_Position.w); gl_FrontColor = vec4((z+offs)/scale,(z+offs)/scale,(z+offs)/scale,1.0); } ";
49 | QOpenGLShader shaderv(QOpenGLShader::Vertex);
50 | bool compile_success=shaderv.compileSourceCode(declarations+codev);
51 | if (!compile_success)
52 | {
53 | compile_success=shaderv.compileSourceCode(codev);
54 | }
55 | if (compile_success)
56 | {
57 | QOpenGLShaderProgram program(context());
58 | program.addShader(&shaderv);
59 | program.link();
60 | program.bind();
61 | }
62 | else
63 | m_noShaders=true;
64 | }
65 | else
66 | m_noShaders=true;
67 |
68 | glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // This Will Clear The Background Color To Black
69 | glEnable(GL_DEPTH_TEST);
70 | glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
71 | glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
72 | // Enables Depth Testing
73 | glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
74 |
75 | m_rotx=0;
76 | m_roty=0;
77 | m_rotz=0;
78 | }
79 | void GlModelView::setModel(Model3D * model)
80 | {
81 | m_model = model;
82 | }
83 |
84 | void GlModelView::setParams(float xoff,float yoff,float zoom,float contrast,float xrot,float yrot,float zrot,float scale)
85 | {
86 | m_zoom=zoom;
87 | m_contrast=contrast;
88 | m_scale=scale;
89 | m_rotx=xrot;
90 | m_roty=yrot;
91 | m_rotz=zrot;
92 | m_xoffset=xoff;
93 | m_yoffset=yoff;
94 | setPerspective();
95 | }
96 |
97 | void GlModelView::setZoom(float zoom)
98 | {
99 | m_zoom=zoom;
100 | setPerspective();
101 | }
102 | void GlModelView::setScale(float scale)
103 | {
104 | m_scale=scale;
105 | setPerspective();
106 | }
107 |
108 | void GlModelView::setContrast(float contrast)
109 | {
110 | m_contrast=contrast;
111 | setPerspective();
112 | }
113 | typedef struct
114 | {
115 | unsigned int numPoints;
116 | unsigned int numTriangles;
117 | unsigned int raster_width;
118 | unsigned int raster_height;
119 | float rotate_x;
120 | float rotate_y;
121 | float rotate_z;
122 | float x_offset;
123 | float y_offset;
124 | float zoom;
125 | float contrast;
126 | } raster_prefs_t;
127 |
128 | const QImage* GlModelView::snapShot()
129 | {
130 | unsigned int out_width=((ModelDepthViewer*)m_parent)->getOutputImageWidth();
131 | unsigned int out_height=((ModelDepthViewer*)m_parent)->getOutputImageHeight();
132 | out_width=out_width&0xfffffffc;
133 | unsigned int numPoints=m_model->numPoints();
134 | unsigned int numTriangles=m_model->numTriangles();
135 | const float *points=m_model->pointsData();
136 | const unsigned int *triangles=m_model->trianglesData();
137 | unsigned char * buffer=new unsigned char[out_height*out_width];
138 | float real_scale= pow(2,m_scale/1000);
139 | trirender(buffer, out_width, out_height, points, numPoints,triangles, numTriangles, m_rotx, m_roty, m_rotz,m_zoom,m_contrast,m_xoffset,m_yoffset,real_scale);
140 | QByteArray result = QByteArray((const char*)buffer,out_width * out_height);
141 |
142 |
143 | imdata=QImage(out_width,out_height,QImage::Format_Indexed8);
144 | imdata=imdata.convertToFormat(QImage::Format_Indexed8,StereoMaker::getGrayScale());
145 | memcpy(imdata.bits(),result.data(),result.size());
146 | imdata=imdata.mirrored();
147 | delete [] buffer;
148 | return &imdata;
149 | /*raster_prefs_t rprefs;
150 | int outputSize=out_width * out_height * sizeof(GLubyte);
151 | const float *points=m_model->pointsData();
152 | const unsigned int *triangles=m_model->trianglesData();
153 | rprefs.numPoints=m_model->numPoints();
154 | rprefs.numTriangles=m_model->numTriangles();
155 | unsigned int out_width=((ModelDepthViewer*)m_parent)->getOutputImageWidth();
156 | unsigned int out_height=((ModelDepthViewer*)m_parent)->getOutputImageHeight();
157 | out_width=out_width&0xfffffffc;
158 | rprefs.raster_width=out_width;
159 | rprefs.raster_height=out_height;
160 | rprefs.rotate_x=m_rotx;
161 | rprefs.rotate_y=m_roty;
162 | rprefs.rotate_z=m_rotz;
163 | rprefs.x_offset=m_xoffset;
164 | rprefs.y_offset=m_yoffset;
165 | rprefs.zoom=m_zoom;
166 | rprefs.contrast=m_contrast;
167 |
168 | QProcess renderer;
169 | QString rasterizer_path=QCoreApplication::applicationDirPath ()+"/m3draster";
170 | renderer.start(rasterizer_path);
171 | if (!renderer.waitForStarted())
172 | {
173 | QMessageBox::warning(this,"Error","can't open "+rasterizer_path);
174 | return 0;
175 | }
176 | renderer.write((char*)&rprefs,sizeof(raster_prefs_t));
177 | renderer.waitForBytesWritten();
178 | int remaining=rprefs.numPoints*3*sizeof(float);
179 | int bytes_per_write=256*3*sizeof(float);
180 | int written=0;
181 | while (remaining>=bytes_per_write)
182 | {
183 | renderer.write(((char*)points)+written,bytes_per_write);
184 | remaining-=bytes_per_write;
185 | written+=bytes_per_write;
186 | renderer.waitForBytesWritten();
187 | }
188 | if (remaining>0)
189 | {
190 | renderer.write(((char*)points)+written,remaining);
191 | renderer.waitForBytesWritten();
192 | }
193 |
194 | remaining=rprefs.numTriangles*3*sizeof(unsigned int);
195 | bytes_per_write=256*3*sizeof(unsigned int);
196 | written=0;
197 | while (remaining>=bytes_per_write)
198 | {
199 | renderer.write(((char*)triangles)+written,bytes_per_write);
200 | remaining-=bytes_per_write;
201 | written+=bytes_per_write;
202 | renderer.waitForBytesWritten();
203 | }
204 | if (remaining>0)
205 | {
206 | renderer.write(((char*)triangles)+written,remaining);
207 | renderer.waitForBytesWritten();
208 | }
209 |
210 | imdata=QImage();
211 | if (!renderer.waitForFinished())
212 | return 0;
213 | QByteArray result = renderer.readAll();
214 | int outputSize=out_width * out_height * sizeof(GLubyte);
215 |
216 | if ((unsigned int)result.size()==outputSize)
217 | {
218 | imdata=QImage(out_width,out_height,QImage::Format_Indexed8);
219 | imdata=imdata.convertToFormat(QImage::Format_Indexed8,StereoMaker::getGrayScale());
220 | memcpy(imdata.bits(),result.data(),result.size());
221 | imdata.invertPixels();
222 | imdata=imdata.mirrored();
223 | }
224 |
225 | return &imdata;*/
226 |
227 | }
228 | void print_matrix(int mattype)
229 | {
230 | //usage: print_matrix(GL_MODELVIEW_MATRIX);
231 | //or: print_matrix(GL_PROJECTION_MATRIX);
232 | GLfloat matrix[16];
233 | glGetFloatv (mattype, matrix);
234 | for (int i=0; i<16; ++i)
235 | {
236 | printf("%f ",matrix[(i%4)*4+(i/4)]);
237 | if (i%4==3)
238 | printf("\n");
239 | }
240 | printf("\n");
241 | fflush(0);
242 | }
243 |
244 | void GlModelView::setPerspective()
245 | {
246 | glMatrixMode(GL_PROJECTION);
247 | glLoadIdentity();
248 |
249 | gluPerspective(20.0f,(GLfloat)m_new_width/(GLfloat)m_new_height,m_zoom-m_contrast,m_zoom+m_contrast); // Calculate The Aspect Ratio Of The Window
250 |
251 |
252 | glMatrixMode(GL_MODELVIEW);
253 | }
254 |
255 | void GlModelView::resizeGL( int width, int height )
256 | {
257 | unsigned int out_width=((ModelDepthViewer*)m_parent)->getOutputImageWidth();
258 | unsigned int out_height=((ModelDepthViewer*)m_parent)->getOutputImageHeight();
259 | setViewport(out_width,out_height);
260 | }
261 |
262 | GlModelView::~GlModelView()
263 | {
264 | if (m_model)
265 | delete m_model;
266 | }
267 |
268 | void GlModelView::setViewport(int width_, int height_)
269 | {
270 | if (height_==0) // Prevent A Divide By Zero By
271 | {
272 | height_=1; // Making Height Equal One
273 | }
274 | float hratio=(float)height_/height();
275 | float wratio=(float)width_/width();
276 | float ratio=qMax(hratio,wratio);
277 | m_new_width=width_/ratio;
278 | if (m_new_width>width())
279 | m_new_width=width();
280 | m_new_height=height_/ratio;
281 | if (m_new_height>height())
282 | m_new_height=height();
283 |
284 | glViewport((width()-m_new_width)/2,(height()-m_new_height)/2,m_new_width,m_new_height); // Reset The Current Viewport
285 | setPerspective();
286 | }
287 |
288 | void GlModelView::paintGL()
289 | {
290 | glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);//clear with white...
291 | if (m_antialias)
292 | glEnable(GL_MULTISAMPLE);
293 | //make black bacground...
294 |
295 | glPushMatrix();
296 | double large_val=10000;
297 | glTranslatef(0,0,-m_zoom-m_contrast+0.01);
298 | glColor3b(255,0,0);
299 | glBegin(GL_QUADS);
300 | glVertex2d(large_val,large_val);
301 | glVertex2d(-large_val,large_val);
302 | glVertex2d(-large_val,-large_val);
303 | glVertex2d(large_val,-large_val);
304 | glEnd();
305 | glPopMatrix();
306 |
307 | //till here
308 | if (m_model)
309 | {
310 | glPushMatrix();
311 | glTranslatef(m_xoffset,m_yoffset,-m_zoom);
312 | float real_scale= pow(2,m_scale/1000);
313 | glScalef(real_scale,real_scale,1.0);
314 | glRotatef(m_rotx,1,0,0);
315 | glRotatef(m_roty,0,1,0);
316 | glRotatef(m_rotz,0,0,1);
317 | m_model->DrawGL(m_noShaders);
318 | glPopMatrix();
319 | }
320 | glDisable(GL_MULTISAMPLE);
321 | }
322 |
--------------------------------------------------------------------------------
/modeldepthviewer.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ModelDepthViewer
4 |
5 |
6 |
7 | 0
8 | 0
9 | 976
10 | 671
11 |
12 |
13 |
14 |
15 | 0
16 | 0
17 |
18 |
19 |
20 |
21 | 1200
22 | 830
23 |
24 |
25 |
26 | Model Viewer
27 |
28 |
29 | 1.000000000000000
30 |
31 |
32 |
33 |
34 | 0
35 | 0
36 |
37 |
38 |
39 | -
40 |
41 |
42 | true
43 |
44 |
45 |
46 | 0
47 | 0
48 |
49 |
50 |
51 |
52 | 800
53 | 600
54 |
55 |
56 |
57 |
58 | -
59 |
60 |
-
61 |
62 |
63 | Rotate X
64 |
65 |
66 |
67 | -
68 |
69 |
70 |
71 | 150
72 | 0
73 |
74 |
75 |
76 | -180
77 |
78 |
79 | 180
80 |
81 |
82 | Qt::Horizontal
83 |
84 |
85 |
86 | -
87 |
88 |
89 | Rotate Y
90 |
91 |
92 |
93 | -
94 |
95 |
96 |
97 | 150
98 | 0
99 |
100 |
101 |
102 | -180
103 |
104 |
105 | 180
106 |
107 |
108 | Qt::Horizontal
109 |
110 |
111 | 0
112 |
113 |
114 |
115 | -
116 |
117 |
118 | Rotate Z
119 |
120 |
121 |
122 | -
123 |
124 |
125 |
126 | 150
127 | 0
128 |
129 |
130 |
131 | -180
132 |
133 |
134 | 180
135 |
136 |
137 | Qt::Horizontal
138 |
139 |
140 | QSlider::NoTicks
141 |
142 |
143 | 0
144 |
145 |
146 |
147 | -
148 |
149 |
150 | Move X
151 |
152 |
153 |
154 | -
155 |
156 |
157 | -800
158 |
159 |
160 | 800
161 |
162 |
163 | 0
164 |
165 |
166 | Qt::Horizontal
167 |
168 |
169 | QSlider::TicksBelow
170 |
171 |
172 | 800
173 |
174 |
175 |
176 | -
177 |
178 |
179 | Move Y
180 |
181 |
182 |
183 | -
184 |
185 |
186 | -800
187 |
188 |
189 | 800
190 |
191 |
192 | 10
193 |
194 |
195 | Qt::Horizontal
196 |
197 |
198 | QSlider::TicksBelow
199 |
200 |
201 | 800
202 |
203 |
204 |
205 | -
206 |
207 |
-
208 |
209 |
210 | Width
211 |
212 |
213 |
214 | -
215 |
216 |
217 | 320
218 |
219 |
220 | 4096
221 |
222 |
223 | 2048
224 |
225 |
226 |
227 |
228 |
229 | -
230 |
231 |
-
232 |
233 |
234 | Height
235 |
236 |
237 |
238 | -
239 |
240 |
241 | 320
242 |
243 |
244 | 4096
245 |
246 |
247 | 1536
248 |
249 |
250 |
251 |
252 |
253 | -
254 |
255 |
256 | Qt::Vertical
257 |
258 |
259 |
260 | 20
261 | 40
262 |
263 |
264 |
265 |
266 | -
267 |
268 |
269 | Scale
270 |
271 |
272 |
273 | -
274 |
275 |
276 | -1000
277 |
278 |
279 | 1000
280 |
281 |
282 | 2
283 |
284 |
285 | 25
286 |
287 |
288 | 0
289 |
290 |
291 | Qt::Horizontal
292 |
293 |
294 |
295 | -
296 |
297 |
298 | Distance
299 |
300 |
301 |
302 | -
303 |
304 |
305 | 200
306 |
307 |
308 | 800
309 |
310 |
311 | 10
312 |
313 |
314 | 25
315 |
316 |
317 | 500
318 |
319 |
320 | Qt::Horizontal
321 |
322 |
323 |
324 | -
325 |
326 |
327 | Contrast
328 |
329 |
330 |
331 | -
332 |
333 |
334 | 30
335 |
336 |
337 | 150
338 |
339 |
340 | 100
341 |
342 |
343 | Qt::Horizontal
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
369 |
370 |
371 |
372 |
373 | :/images/save.png:/images/save.png
374 |
375 |
376 | Save Image...
377 |
378 |
379 | true
380 |
381 |
382 |
383 |
384 | Push Image
385 |
386 |
387 |
388 |
389 |
390 | GlModelView
391 | QWidget
392 |
393 | 1
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
--------------------------------------------------------------------------------
/trirender.cpp:
--------------------------------------------------------------------------------
1 | #include "trirender.h"
2 | #include
3 | #include //for memset
4 | #include
5 | using namespace std;
6 |
7 | typedef struct
8 | {
9 | long long x;
10 | long long y;
11 | long long z;
12 | }Vertice;
13 | const int int_scale=1024;
14 | static unsigned char * image_buffer;
15 | static int image_width;
16 | static int image_height;
17 | int sabs(int a)
18 | {
19 | if (a<0)
20 | return -a;
21 | return a;
22 | }
23 |
24 | static void putPixel(long long x,long long y, long long value)
25 | {
26 |
27 | if (x=0 && y=0)
28 | {
29 | if (value>(256*int_scale-1)) return;
30 | //value=(256*int_scale-1);
31 | else if (value<0)
32 | value=0;
33 | if (image_buffer[(x/int_scale)+(y/int_scale)*image_width]<(unsigned char)(value/int_scale))
34 | image_buffer[(x/int_scale)+(y/int_scale)*image_width]=(unsigned char)(value/int_scale);
35 | }
36 |
37 | }
38 |
39 | static void drawScanLine(long long fromx, long long tox,long long fromc,long long toc, long long y)
40 | {
41 | long long x,c=fromc;
42 | x=(fromx+int_scale-1);
43 | x=x-(x%int_scale);
44 | for (;x=v3.x)//rounding is toward zero...
63 | {
64 | for (; scanlineY < v2.y; scanlineY+=int_scale)
65 | {
66 | curx1 = v1.x-((-v2.x + v1.x)*(scanlineY-v1.y) / (v2.y - v1.y));
67 | curx2 = v1.x-((-v3.x + v1.x)*(scanlineY-v1.y) / (v3.y - v1.y));
68 | curc1 = v1.z+(v2.z - v1.z)*(scanlineY-v1.y) / (v2.y - v1.y);
69 | curc2 = v1.z+(v3.z - v1.z)*(scanlineY-v1.y) / (v3.y - v1.y);
70 | drawScanLine(curx1-1, curx2,curc1, curc2, scanlineY);
71 | }
72 | }
73 | else if (v1.x<=v2.x)
74 | {
75 | for (; scanlineY < v2.y; scanlineY+=int_scale)
76 | {
77 | curx1 = v1.x+((v2.x - v1.x)*(scanlineY-v1.y) / (v2.y - v1.y));
78 | curx2 = v1.x+((v3.x - v1.x)*(scanlineY-v1.y) / (v3.y - v1.y));
79 | curc1 = v1.z+(v2.z - v1.z)*(scanlineY-v1.y) / (v2.y - v1.y);
80 | curc2 = v1.z+(v3.z - v1.z)*(scanlineY-v1.y) / (v3.y - v1.y);
81 | drawScanLine(curx1, curx2+1,curc1, curc2, scanlineY);
82 | }
83 | }
84 | else
85 | for (; scanlineY < v2.y; scanlineY+=int_scale)
86 | {
87 | curx1 = v1.x-((-v2.x + v1.x)*(scanlineY-v1.y) / (v2.y - v1.y));
88 | curx2 = v1.x+((v3.x - v1.x)*(scanlineY-v1.y) / (v3.y - v1.y));
89 | curc1 = v1.z+(v2.z - v1.z)*(scanlineY-v1.y) / (v2.y - v1.y);
90 | curc2 = v1.z+(v3.z - v1.z)*(scanlineY-v1.y) / (v3.y - v1.y);
91 | drawScanLine(curx1-1, curx2+1,curc1, curc2, scanlineY);
92 | }
93 | }
94 |
95 | static void fillTopFlatTriangle(const Vertice& v1, const Vertice& v2, const Vertice& v3)
96 | {
97 |
98 | long long curx1;
99 | long long curx2;
100 | long long curc1;
101 | long long curc2;
102 | long long scanlineY = v3.y-1;
103 | scanlineY=scanlineY-(scanlineY%int_scale);
104 | if (v3.x>=v2.x)
105 | {
106 | for (; scanlineY >= v1.y; scanlineY-=int_scale)
107 | {
108 | curx1 = v3.x-((v3.x - v1.x)*(v3.y-scanlineY) / (v3.y - v1.y));
109 | curx2 = v3.x-((v3.x - v2.x)*(v3.y-scanlineY) / (v3.y - v2.y));
110 | curc1 = v3.z-(v3.z - v1.z)*(v3.y-scanlineY) / (v3.y - v1.y);
111 | curc2 = v3.z-(v3.z - v2.z)*(v3.y-scanlineY) / (v3.y - v2.y);
112 | drawScanLine(curx1-1, curx2,curc1, curc2, scanlineY);
113 | }
114 | }
115 | else if (v3.x<=v1.x)
116 | {
117 | for (; scanlineY >= v1.y; scanlineY-=int_scale)
118 | {
119 | curx1 = v3.x+((-v3.x + v1.x)*(v3.y-scanlineY) / (v3.y - v1.y));
120 | curx2 = v3.x+((-v3.x + v2.x)*(v3.y-scanlineY) / (v3.y - v2.y));
121 | curc1 = v3.z-(v3.z - v1.z)*(v3.y-scanlineY) / (v3.y - v1.y);
122 | curc2 = v3.z-(v3.z - v2.z)*(v3.y-scanlineY) / (v3.y - v2.y);
123 | drawScanLine(curx1, curx2+1,curc1, curc2, scanlineY);
124 | }
125 | }
126 | else
127 | for (; scanlineY >= v1.y; scanlineY-=int_scale)
128 | {
129 | curx1 = v3.x-((v3.x - v1.x)*(v3.y-scanlineY) / (v3.y - v1.y));
130 | curx2 = v3.x+((-v3.x + v2.x)*(v3.y-scanlineY) / (v3.y - v2.y));
131 | curc1 = v3.z-(v3.z - v1.z)*(v3.y-scanlineY) / (v3.y - v1.y);
132 | curc2 = v3.z-(v3.z - v2.z)*(v3.y-scanlineY) / (v3.y - v2.y);
133 | drawScanLine(curx1-1, curx2+1,curc1, curc2, scanlineY);
134 | }
135 | }
136 |
137 | #define SWAPON(V1,V2,C) do{if(V1->C > V2->C) {temp=V1;V1=V2;V2=temp;}}while(0);
138 |
139 | static void drawTriangle(const Vertice* v1,const Vertice* v2,const Vertice* v3)
140 | {
141 | const Vertice* temp;
142 | SWAPON(v1,v2,y);
143 | SWAPON(v1,v3,y);
144 | SWAPON(v2,v3,y);
145 |
146 |
147 | /* here we know that v1->y <= v2->y <= v3->y */
148 | /* check for trivial case of bottom-flat triangle */
149 |
150 | if (v1->y != v3->y)
151 | {
152 | if ( v2->y == v3->y)
153 | {
154 | SWAPON(v2,v3,x);
155 | fillBottomFlatTriangle(*v1, *v2, *v3);
156 | }
157 | // check for trivial case of top-flat triangle
158 | else if (v1->y == v2->y)
159 | {
160 | SWAPON(v1,v2,x);
161 | fillTopFlatTriangle(*v1, *v2, *v3);
162 | }
163 | else
164 | {
165 | // general case - split the triangle in a topflat and bottom-flat one
166 | Vertice v4;
167 | v4.x=(v1->x + ((v3->x - v1->x)*(v2->y - v1->y))/ (v3->y - v1->y));
168 | v4.y=v2->y;
169 | v4.z=(v1->z + ((v3->z - v1->z)*(v2->y - v1->y))/ (v3->y - v1->y));
170 | drawTriangle(v1, v2, &v4);
171 | drawTriangle(v2, &v4, v3);
172 |
173 | }
174 | }
175 | else// all y are equal
176 | {
177 | /*SWAPON(v1,v2,x);
178 | SWAPON(v1,v3,x);
179 | SWAPON(v2,v3,x);
180 | drawScanLine(v2->x, v3->x,v2->z, v3->z, v2->y);
181 | drawScanLine(v1->x, v3->x,v1->z, v3->z, v1->y);
182 | drawScanLine(v1->x, v2->x,v1->z, v2->z, v1->y);*/
183 |
184 | }
185 | }
186 | static void drawTri(/*unsigned char *buffer, int w, int h,*/const long long *points,const unsigned int *triangles, int tri_ind)
187 | {
188 | unsigned int t[3];
189 | for (int i=0;i<3;++i)
190 | t[i]=triangles[tri_ind*3+i];
191 | const Vertice *v[3];
192 | for (int i=0;i<3;++i)
193 | {
194 | v[i]=(const Vertice*)&points[t[i]*3];
195 | }
196 | drawTriangle(v[0],v[1],v[2]);
197 | }
198 | #define DEG2RAD (M_PI/180.0)
199 | #define MAP_MATRIX(I,J) (J*4+I)
200 | static void my_PerspectiveFOV(float fov, float aspect, float near, float far, float* mret) {
201 |
202 | float yScale = 1.0 / tan(DEG2RAD * fov / 2);
203 | float xScale = yScale / aspect;
204 | float nearmfar = near - far;
205 | float m[16] = {
206 | xScale, 0, 0, 0,
207 | 0, yScale, 0, 0,
208 | 0, 0, (far + near) / nearmfar, -1,
209 | 0, 0, 2*far*near / nearmfar, 0
210 | };
211 | memcpy(mret, m, sizeof(float)*16);
212 | }
213 | static void mult_mat(float* m1,float* m2,float* res)
214 | {
215 | float m[16] = {
216 | m1[ 0 ]*m2[ 0 ]+m1[ 4 ]*m2[ 1 ]+m1[ 8 ]*m2[ 2 ]+m1[ 12 ]*m2[ 3 ],
217 | m1[ 1 ]*m2[ 0 ]+m1[ 5 ]*m2[ 1 ]+m1[ 9 ]*m2[ 2 ]+m1[ 13 ]*m2[ 3 ],
218 | m1[ 2 ]*m2[ 0 ]+m1[ 6 ]*m2[ 1 ]+m1[ 10 ]*m2[ 2 ]+m1[ 14 ]*m2[ 3 ],
219 | m1[ 3 ]*m2[ 0 ]+m1[ 7 ]*m2[ 1 ]+m1[ 11 ]*m2[ 2 ]+m1[ 15 ]*m2[ 3 ],
220 | m1[ 0 ]*m2[ 4 ]+m1[ 4 ]*m2[ 5 ]+m1[ 8 ]*m2[ 6 ]+m1[ 12 ]*m2[ 7 ],
221 | m1[ 1 ]*m2[ 4 ]+m1[ 5 ]*m2[ 5 ]+m1[ 9 ]*m2[ 6 ]+m1[ 13 ]*m2[ 7 ],
222 | m1[ 2 ]*m2[ 4 ]+m1[ 6 ]*m2[ 5 ]+m1[ 10 ]*m2[ 6 ]+m1[ 14 ]*m2[ 7 ],
223 | m1[ 3 ]*m2[ 4 ]+m1[ 7 ]*m2[ 5 ]+m1[ 11 ]*m2[ 6 ]+m1[ 15 ]*m2[ 7 ],
224 | m1[ 0 ]*m2[ 8 ]+m1[ 4 ]*m2[ 9 ]+m1[ 8 ]*m2[ 10 ]+m1[ 12 ]*m2[ 11 ],
225 | m1[ 1 ]*m2[ 8 ]+m1[ 5 ]*m2[ 9 ]+m1[ 9 ]*m2[ 10 ]+m1[ 13 ]*m2[ 11 ],
226 | m1[ 2 ]*m2[ 8 ]+m1[ 6 ]*m2[ 9 ]+m1[ 10 ]*m2[ 10 ]+m1[ 14 ]*m2[ 11 ],
227 | m1[ 3 ]*m2[ 8 ]+m1[ 7 ]*m2[ 9 ]+m1[ 11 ]*m2[ 10 ]+m1[ 15 ]*m2[ 11 ],
228 | m1[ 0 ]*m2[ 12 ]+m1[ 4 ]*m2[ 13 ]+m1[ 8 ]*m2[ 14 ]+m1[ 12 ]*m2[ 15 ],
229 | m1[ 1 ]*m2[ 12 ]+m1[ 5 ]*m2[ 13 ]+m1[ 9 ]*m2[ 14 ]+m1[ 13 ]*m2[ 15 ],
230 | m1[ 2 ]*m2[ 12 ]+m1[ 6 ]*m2[ 13 ]+m1[ 10 ]*m2[ 14 ]+m1[ 14 ]*m2[ 15 ],
231 | m1[ 3 ]*m2[ 12 ]+m1[ 7 ]*m2[ 13 ]+m1[ 11 ]*m2[ 14 ]+m1[ 15 ]*m2[ 15 ]
232 | };
233 | memcpy(res, m, sizeof(float)*16);
234 | }
235 |
236 | static void xrotation_mat(float xrot, float* mret) {
237 |
238 | float cxrot=cosf(xrot*DEG2RAD);
239 | float sxrot=sinf(xrot*DEG2RAD);
240 | float m[16] = {
241 | 1, 0, 0, 0,
242 | 0, cxrot, sxrot, 0,
243 | 0, -sxrot, cxrot, 0,
244 | 0, 0, 0, 1
245 | };
246 | memcpy(mret, m, sizeof(float)*16);
247 | }
248 | static void yrotation_mat(float yrot, float* mret) {
249 |
250 | float cyrot=cosf(yrot*DEG2RAD);
251 | float syrot=sinf(yrot*DEG2RAD);
252 | float m[16] = {
253 | cyrot, 0, -syrot, 0,
254 | 0 , 1, 0 , 0,
255 | syrot, 0, cyrot , 0,
256 | 0, 0, 0, 1
257 | };
258 | memcpy(mret, m, sizeof(float)*16);
259 | }
260 | static void zrotation_mat(float zrot, float* mret) {
261 |
262 | float czrot=cosf(zrot*DEG2RAD);
263 | float szrot=sinf(zrot*DEG2RAD);
264 | float m[16] = {
265 | czrot, szrot, 0, 0,
266 | -szrot , czrot, 0 , 0,
267 | 0, 0, 1, 0,
268 | 0, 0, 0, 1
269 | };
270 | memcpy(mret, m, sizeof(float)*16);
271 | }
272 | static void translation_mat(float x,float y,float z, float* mret) {
273 |
274 | float m[16] = {
275 | 1, 0, 0, 0,
276 | 0 , 1, 0 , 0,
277 | 0, 0, 1, 0,
278 | x, y, z, 1
279 | };
280 | memcpy(mret, m, sizeof(float)*16);
281 | }
282 | static void scale_mat(float sx,float sy,float sz, float* mret) {
283 |
284 | float m[16] = {
285 | sx, 0, 0, 0,
286 | 0 , sy, 0 , 0,
287 | 0, 0, sz, 0,
288 | 0, 0, 0, 1
289 | };
290 | memcpy(mret, m, sizeof(float)*16);
291 | }
292 |
293 | static void mult_mat_vec(float* m , float *v,float *out_v)
294 | {
295 | float res[4] = {
296 | m[ 0 ]*v[ 0 ]+m[ 4 ]*v[ 1 ]+m[ 8 ]*v[ 2 ]+m[ 12 ]*v[ 3 ],
297 | m[ 1 ]*v[ 0 ]+m[ 5 ]*v[ 1 ]+m[ 9 ]*v[ 2 ]+m[ 13 ]*v[ 3 ],
298 | m[ 2 ]*v[ 0 ]+m[ 6 ]*v[ 1 ]+m[ 10 ]*v[ 2 ]+m[ 14 ]*v[ 3 ],
299 | m[ 3 ]*v[ 0 ]+m[ 7 ]*v[ 1 ]+m[ 11 ]*v[ 2 ]+m[ 15 ]*v[ 3 ]};
300 | memcpy(out_v, res, sizeof(float)*4);
301 | }
302 |
303 | extern float projMatrix[16];
304 | extern float modelMatrix[16];
305 |
306 | void trirender(unsigned char *buffer, int width, int height, const float *points, int np,const unsigned int *triangles, int nt, float xrot, float yrot, float zrot,
307 | float zoom,float contrast,float xoff,float yoff,float scale)
308 | {
309 | image_buffer=buffer;
310 | image_width=width;
311 | image_height=height;
312 | memset(buffer,0,width*height);
313 |
314 | long long *i_points=new long long[np*3];
315 | /*float cxrot=cosf(xrot*DEG2RAD);
316 | float sxrot=sinf(xrot*DEG2RAD);
317 | float cyrot=cosf(yrot*DEG2RAD);
318 | float syrot=sinf(yrot*DEG2RAD);
319 | float czrot=cosf(zrot*DEG2RAD);
320 | float szrot=sinf(zrot*DEG2RAD);*/
321 | float prjmat[16];
322 | float temp_mat[16];
323 | float model_mat[16]={1,0,0,0,
324 | 0,1,0,0,
325 | 0,0,1,0,
326 | 0,0,0,1};
327 |
328 | my_PerspectiveFOV(20,(float)width/height,(zoom-contrast),(zoom+contrast),prjmat);
329 |
330 | //float _w,old_val_x;
331 |
332 |
333 | //float x,y,z;
334 | translation_mat(xoff,yoff,-zoom,temp_mat);
335 | mult_mat(model_mat,temp_mat,model_mat);
336 | scale_mat(scale,scale,1,temp_mat);
337 | mult_mat(model_mat,temp_mat,model_mat);
338 | xrotation_mat(xrot,temp_mat);
339 | mult_mat(model_mat,temp_mat,model_mat);
340 | yrotation_mat(yrot,temp_mat);
341 | mult_mat(model_mat,temp_mat,model_mat);
342 | zrotation_mat(zrot,temp_mat);
343 | mult_mat(model_mat,temp_mat,model_mat);
344 |
345 | for (int i=0;i
3 | #define MY_PRECISION 512
4 | #else
5 | #include
6 | #endif
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #define INVALID_OFFSET (-1)
14 | #define MYDEBUG 0
15 |
16 | #ifndef USE_MPFR
17 | #ifndef USE_FLOAT
18 | #ifndef USE_LDBL
19 | typedef double DBL_T;
20 | #define STR_FUNC strtod
21 | #define EXP_FUNC exp
22 | #define POW_FUNC pow
23 | #define SIN_FUNC sin
24 | #define TYPE_MOD "%lf"
25 | #ifndef NAN
26 | #define NAN nan("");
27 | #endif
28 | #else
29 | typedef long double DBL_T;
30 | #define STR_FUNC strtold
31 | #define EXP_FUNC expl
32 | #define POW_FUNC powl
33 | #define SIN_FUNC sinl
34 | #define TYPE_MOD "%Lf"
35 | #ifndef NAN
36 | #define NAN nanl("");
37 | #endif
38 | #endif
39 | #else
40 | typedef float DBL_T;
41 | #define STR_FUNC strtof
42 | #define EXP_FUNC expf
43 | #define POW_FUNC powf
44 | #define SIN_FUNC sinf
45 | #define TYPE_MOD "%f"
46 | #ifndef NAN
47 | #define NAN nanf("");
48 | #endif
49 | #endif
50 | #endif
51 | #ifdef USE_MPFR
52 | #define TYPE_MOD "%.128Rf"
53 | void parse_level1(const char* buffer, int *offset, mpfr_t res, mpfr_t* values);
54 | void parse_level2(const char* buffer, int *offset, mpfr_t res, mpfr_t* values);
55 | void parse_level3(const char* buffer, int *offset, mpfr_t res, mpfr_t* values);
56 | void parse_level4(const char* buffer, int *offset, mpfr_t res, mpfr_t* values);
57 | #else
58 | #define MPFR_DECL_INIT(X,PERC) DBL_T X=NAN;
59 | #define mpfr_init2(X,Y) {do{} while(0);}
60 | #define mpfr_set(X,Y,METHOD) {do{X=Y;} while(0);}
61 | #define mpfr_set_si(X,Y, METHOD) {do{X=Y;} while(0);}
62 | #define mpfr_clear(X) do{} while(0);
63 | #define mpfr_add(RES,A,B,METHOD) {do{RES=A+B;} while(0);}
64 | #define mpfr_mul(RES,A,B,METHOD) {do{RES=A*B;} while(0);}
65 | #define mpfr_div(RES,A,B,METHOD) {do{RES=A/B;} while(0);}
66 | #define mpfr_pow(RES,A,B,METHOD) {do{RES=POW_FUNC(A,B);} while(0);}
67 | #define mpfr_sin(RES,X,METHOD) {do{RES=SIN_FUNC(X);} while(0);}
68 | #define mpfr_exp(RES,POWER,METHOD) {do{RES=EXP_FUNC(POWER);} while(0);}
69 | #define mpfr_set_nan(X) {do{X=NAN;} while(0);}
70 | #define mpfr_strtofr(X, STR, TAIL, BASE, METHOD) X=STR_FUNC(STR, TAIL);
71 | #define mpfr_const_pi(X,METHOD) {do{X=M_PI;} while(0);}
72 | #define mpfr_printf(...) {do{printf(__VA_ARGS__);} while(0);}
73 |
74 | #define MPFR_RNDN 0
75 | typedef DBL_T mpfr_t;
76 | void parse_level1(const char* buffer, int *offset, DBL_T& res, mpfr_t* values);
77 | void parse_level2(const char* buffer, int *offset, DBL_T& res, mpfr_t* values);
78 | void parse_level3(const char* buffer, int *offset, DBL_T& res, mpfr_t* values);
79 | void parse_level4(const char* buffer, int *offset, DBL_T& res, mpfr_t* values);
80 | #endif
81 | #define STRLEN(X) (sizeof(X)/sizeof(X[0])-1) //minus one to remove the null termination
82 | #define CHECK_INITIALS(STR,NEEDLE) (strncmp(STR,NEEDLE,STRLEN(NEEDLE))==0 && isalnum(*(STR+STRLEN(NEEDLE)))==0)
83 |
84 | bool is_whitespace(char c)
85 | {
86 | return (' ' == c) || ('\n' == c) ||
87 | ('\r' == c) || ('\t' == c) ||
88 | ('\b' == c) || ('\v' == c) ||
89 | ('\f' == c) ;
90 | }
91 | bool is_functional(char c)
92 | {
93 | return ('(' == c) || (')' == c) ||
94 | ('+' == c) || ('-' == c) ||
95 | ('*' == c) || ('/' == c)|| ('.' == c);
96 | }
97 | bool is_Digit(char c)
98 | {
99 | return (c>='0' && c<='9');
100 | }
101 | bool is_Alpha(char c)
102 | {
103 | return (c>='a' && c<='z')||(c>='A' && c<='Z');
104 | }
105 | void skip_spaces(const char* buffer, int *offset)
106 | {
107 | while (is_whitespace(buffer[*offset]))
108 | {
109 | (*offset)++;
110 | }
111 | }
112 |
113 |
114 | #ifdef USE_MPFR
115 | void parse_level1(const char* buffer, int *offset, mpfr_t res, mpfr_t* values) //addition and subtraction
116 | #else
117 | void parse_level1(const char* buffer, int *offset, DBL_T& res, mpfr_t* values) //addition and subtraction
118 | #endif
119 | {
120 | #if MYDEBUG
121 | printf("parse_level1 %d\n",*offset);
122 | #endif
123 |
124 | mpfr_t left;
125 | int my_offset;
126 | skip_spaces(buffer, offset);
127 | my_offset=*offset;
128 |
129 | parse_level2(buffer,&my_offset,left,values);
130 | #if MYDEBUG
131 | printf("parse_level1 a %d\n",*offset);
132 | #ifdef USE_MPFR
133 | mpfr_printf ("parse_level1 n = " TYPE_MOD "\n",left);
134 | #endif
135 | #endif
136 | if (*offset==my_offset || *offset==INVALID_OFFSET)
137 | {
138 | *offset=INVALID_OFFSET;
139 | return;
140 | }
141 |
142 | #if MYDEBUG
143 | printf("parse_level1 b %d\n",*offset);
144 | #endif
145 | skip_spaces(buffer, &my_offset);
146 | *offset=my_offset;
147 | while (buffer[my_offset]=='+' || buffer[my_offset]=='-')
148 | {
149 | #if MYDEBUG
150 | printf("parse_level1 loop %d\n",*offset);
151 | #endif
152 | char op=buffer[my_offset];
153 | if (op=='-')
154 | {
155 | op='+';
156 | }
157 | else
158 | ++my_offset;
159 | mpfr_t right;
160 | skip_spaces(buffer, &my_offset);
161 | *offset=my_offset;
162 | parse_level2(buffer,&my_offset,right,values);
163 | #if MYDEBUG
164 | printf("parse_level1 c %d %d\n",*offset,my_offset);
165 | #endif
166 | if (*offset==my_offset || *offset==INVALID_OFFSET)
167 | {
168 | *offset=INVALID_OFFSET;
169 | return;
170 | }
171 | #if MYDEBUG
172 | printf("parse_level1 d %d\n",*offset);
173 | #endif
174 | skip_spaces(buffer, &my_offset);
175 |
176 | *offset=my_offset;
177 | mpfr_add(left,left,right,MPFR_RNDN);
178 | mpfr_clear (right);
179 |
180 |
181 | }
182 | if (buffer[my_offset]!='\n' && buffer[my_offset]!=')' && buffer[my_offset]!='\0' && buffer[my_offset]!=',')
183 | {
184 | *offset=INVALID_OFFSET;
185 | return;
186 | }
187 | #if MYDEBUG
188 | else
189 | {
190 | printf("parse_level1 character %c\n",buffer[my_offset]);
191 | }
192 | #endif
193 |
194 | mpfr_init2(res,MY_PRECISION);
195 | mpfr_set(res,left,MPFR_RNDN);
196 | mpfr_clear (left);
197 |
198 | return;
199 | }
200 | #ifdef USE_MPFR
201 | void parse_level2(const char* buffer, int *offset, mpfr_t res, mpfr_t* values) //multiplication and division
202 | #else
203 | void parse_level2(const char* buffer, int *offset, DBL_T& res, mpfr_t* values)
204 | #endif
205 | {
206 | mpfr_t left;
207 |
208 |
209 | int my_offset;
210 |
211 | my_offset=*offset;
212 | parse_level3(buffer,&my_offset,left,values);
213 |
214 |
215 | if (*offset==my_offset || *offset==INVALID_OFFSET)
216 | {
217 | *offset=INVALID_OFFSET;
218 | return;
219 | }
220 | *offset=my_offset;
221 | while (buffer[my_offset]=='*' || buffer[my_offset]=='/')
222 | {
223 |
224 | char op=buffer[my_offset];
225 | ++my_offset;
226 | mpfr_t right;
227 | skip_spaces(buffer, &my_offset);
228 | *offset=my_offset;
229 | parse_level3(buffer,&my_offset,right,values);
230 | if (*offset==my_offset || *offset==INVALID_OFFSET)
231 | {
232 | *offset=INVALID_OFFSET;
233 | return;
234 | }
235 | skip_spaces(buffer, &my_offset);
236 | *offset=my_offset;
237 | if (op=='*')
238 | {
239 | mpfr_mul(left,left,right,MPFR_RNDN);
240 | }
241 | else
242 | {
243 | mpfr_div(left,left,right,MPFR_RNDN);
244 | }
245 | mpfr_clear (right);
246 | }
247 |
248 | mpfr_init2(res,MY_PRECISION);
249 | mpfr_set(res,left,MPFR_RNDN);
250 | mpfr_clear (left);
251 |
252 | return;
253 | }
254 | #ifdef USE_MPFR
255 | void parse_level3(const char* buffer, int *offset, mpfr_t res, mpfr_t* values) //minus sign
256 | #else
257 | void parse_level3(const char* buffer, int *offset, DBL_T& res, mpfr_t* values)
258 | #endif
259 | {
260 |
261 | char op=0;
262 |
263 | int my_offset;
264 |
265 | my_offset=*offset;
266 | if (buffer[my_offset]=='-')
267 | {
268 | op='-';
269 | ++my_offset;
270 | }
271 | parse_level4(buffer,&my_offset,res,values);
272 |
273 | if (*offset==my_offset || *offset==INVALID_OFFSET)
274 | {
275 |
276 | *offset=INVALID_OFFSET;
277 | return;
278 | }
279 | skip_spaces(buffer, &my_offset);
280 | *offset=my_offset;
281 |
282 | if (op)
283 | {
284 | mpfr_t minus_one;
285 | mpfr_init2(minus_one,MPFR_PREC_MIN+2);
286 | mpfr_set_si (minus_one, -1, MPFR_RNDN);
287 | mpfr_mul(res,res,minus_one,MPFR_RNDN);
288 | mpfr_clear(minus_one);
289 | }
290 |
291 | }
292 | #ifdef USE_MPFR
293 | void parse_level4(const char* buffer, int *offset, mpfr_t res, mpfr_t* values) //object itself
294 | #else
295 | void parse_level4(const char* buffer, int *offset, DBL_T& res, mpfr_t* values)
296 | #endif
297 | {
298 |
299 | int my_offset;
300 | my_offset=*offset;
301 | if (buffer[*offset]==0 || buffer[*offset]==')')//unbalanced?
302 | {
303 | *offset=INVALID_OFFSET;
304 | return;
305 | }
306 | if (buffer[my_offset]=='(')
307 | {
308 | ++my_offset;
309 | parse_level1(buffer,&my_offset,res,values);
310 |
311 | if (buffer[my_offset]!=')')
312 | {
313 | *offset=INVALID_OFFSET;
314 | return;
315 | }
316 | ++my_offset;
317 | *offset=my_offset;
318 | return;
319 | }
320 |
321 | if (values!=0)
322 | {
323 | if (CHECK_INITIALS(&buffer[my_offset],"x"))
324 | {
325 | mpfr_init2(res,MY_PRECISION);
326 | mpfr_set(res,values[0],MPFR_RNDN);
327 | my_offset+=STRLEN("x");
328 | *offset=my_offset;
329 | return;
330 | }
331 | if (CHECK_INITIALS(&buffer[my_offset],"y"))
332 | {
333 | mpfr_init2(res,MY_PRECISION);
334 | mpfr_set(res,values[1],MPFR_RNDN);
335 | my_offset+=STRLEN("y");
336 | *offset=my_offset;
337 | return;
338 | }
339 | }
340 | if (CHECK_INITIALS(&buffer[my_offset],"pi"))
341 | {
342 | mpfr_init2(res,MY_PRECISION);
343 | mpfr_const_pi (res,MPFR_RNDN);
344 | my_offset+=STRLEN("pi");
345 | *offset=my_offset;
346 | return;
347 | }
348 | if (CHECK_INITIALS(&buffer[my_offset],"e"))
349 | {
350 | mpfr_init2(res,MY_PRECISION);
351 | mpfr_set_si(res,1,MPFR_RNDN);
352 | mpfr_exp (res, res, MPFR_RNDN);
353 | my_offset+=STRLEN("e");
354 | *offset=my_offset;
355 | return;
356 | }
357 | if (CHECK_INITIALS(&buffer[my_offset],"pow"))
358 | {
359 | my_offset+=STRLEN("pow");
360 | *offset=my_offset;
361 | skip_spaces(buffer, &my_offset);
362 | if (buffer[my_offset]=='(')
363 | {
364 | ++my_offset;
365 | mpfr_t left;
366 | parse_level1(buffer,&my_offset,left,values);
367 |
368 | if (buffer[my_offset]!=',')
369 | {
370 | *offset=INVALID_OFFSET;
371 | return;
372 | }
373 | ++my_offset;
374 | mpfr_t right;
375 | parse_level1(buffer,&my_offset,right,values);
376 | if (buffer[my_offset]!=')')
377 | {
378 | *offset=INVALID_OFFSET;
379 | return;
380 | }
381 | ++my_offset;
382 | *offset=my_offset;
383 | mpfr_init2(res,MY_PRECISION);
384 | mpfr_pow(res,left,right,MPFR_RNDN);
385 | mpfr_clear (right);
386 | mpfr_clear (left);
387 | return;
388 | }
389 | else
390 | {
391 | *offset=INVALID_OFFSET;
392 | return;
393 | }
394 | return;
395 | }
396 | if (CHECK_INITIALS(&buffer[my_offset],"sin"))
397 | {
398 | my_offset+=STRLEN("sin");
399 | *offset=my_offset;
400 | skip_spaces(buffer, &my_offset);
401 | if (buffer[my_offset]=='(')
402 | {
403 | ++my_offset;
404 | mpfr_t left;
405 | parse_level1(buffer,&my_offset,left,values);
406 | if (my_offset==INVALID_OFFSET)
407 | {
408 | *offset=INVALID_OFFSET;
409 | return;
410 | }
411 | if (buffer[my_offset]!=')')
412 | {
413 | *offset=INVALID_OFFSET;
414 | return;
415 | }
416 | ++my_offset;
417 | *offset=my_offset;
418 | mpfr_init2(res,MY_PRECISION);
419 | mpfr_sin(res,left,MPFR_RNDN);
420 | mpfr_clear (left);
421 | return;
422 | }
423 | else
424 | {
425 | *offset=INVALID_OFFSET;
426 | return;
427 | }
428 | }
429 | if (is_Digit(buffer[my_offset])||buffer[my_offset]=='.'||buffer[my_offset]=='+')
430 | {
431 | mpfr_init2(res,MY_PRECISION);
432 | char* endptr;
433 | mpfr_strtofr (res, buffer+my_offset, &endptr, 10, MPFR_RNDN);
434 | *offset=my_offset=(int)((ptrdiff_t)endptr-(ptrdiff_t)buffer);
435 | }
436 | else
437 | {
438 | *offset=INVALID_OFFSET;
439 | return;
440 | }
441 | }
442 |
443 |
444 | void parse(const char* buffer)
445 | {
446 | mpfr_t res;
447 | int offset=0;
448 | do{
449 | parse_level1(buffer, &offset,res,0);
450 | if (offset!=INVALID_OFFSET && (buffer[offset]==0||buffer[offset]==','))
451 | {
452 | mpfr_printf ("!! res = " TYPE_MOD "\n",res);
453 | }
454 | else
455 | {
456 | mpfr_init2(res,MY_PRECISION);
457 | mpfr_set_nan(res);
458 | break;
459 | }
460 | }
461 | while(buffer[offset++]==',');
462 | #ifdef USE_MPFR
463 | mpfr_free_cache();
464 | #endif
465 | }
466 | #ifdef USE_FLOAT
467 | float parseXY(const char* buffer,float x,float y,bool* ok)
468 | {
469 | float values[2];
470 | values[0]=x;
471 | values[1]=y;
472 | int offset=0;
473 | float res;
474 | parse_level1(buffer, &offset,res,values);
475 | //mpfr_printf ("!! res = " TYPE_MOD "\n",res);
476 | if (offset!=INVALID_OFFSET && buffer[offset]==0)
477 | {
478 | *ok=true;
479 | }
480 | else
481 | {
482 | *ok=false;
483 | }
484 | return res;
485 |
486 | }
487 | #endif
488 |
--------------------------------------------------------------------------------
/RPly/rply.h:
--------------------------------------------------------------------------------
1 | #ifndef RPLY_H
2 | #define RPLY_H
3 | /* ----------------------------------------------------------------------
4 | * RPly library, read/write PLY files
5 | * Diego Nehab, IMPA
6 | * http://www.impa.br/~diego/software/rply
7 | *
8 | * This library is distributed under the MIT License. See notice
9 | * at the end of this file.
10 | * ---------------------------------------------------------------------- */
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 | #define RPLY_VERSION "RPly 1.1.4"
17 | #define RPLY_COPYRIGHT "Copyright (C) 2003-2015 Diego Nehab"
18 | #define RPLY_AUTHORS "Diego Nehab"
19 |
20 | /* ----------------------------------------------------------------------
21 | * Types
22 | * ---------------------------------------------------------------------- */
23 | /* structures are opaque */
24 | typedef struct t_ply_ *p_ply;
25 | typedef struct t_ply_element_ *p_ply_element;
26 | typedef struct t_ply_property_ *p_ply_property;
27 | typedef struct t_ply_argument_ *p_ply_argument;
28 |
29 | /* ply format mode type */
30 | typedef enum e_ply_storage_mode_ {
31 | PLY_BIG_ENDIAN,
32 | PLY_LITTLE_ENDIAN,
33 | PLY_ASCII,
34 | PLY_DEFAULT /* has to be the last in enum */
35 | } e_ply_storage_mode; /* order matches ply_storage_mode_list */
36 |
37 | /* ply data type */
38 | typedef enum e_ply_type {
39 | PLY_INT8, PLY_UINT8, PLY_INT16, PLY_UINT16,
40 | PLY_INT32, PLY_UIN32, PLY_FLOAT32, PLY_FLOAT64,
41 | PLY_CHAR, PLY_UCHAR, PLY_SHORT, PLY_USHORT,
42 | PLY_INT, PLY_UINT, PLY_FLOAT, PLY_DOUBLE,
43 | PLY_LIST /* has to be the last in enum */
44 | } e_ply_type; /* order matches ply_type_list */
45 |
46 | /* ----------------------------------------------------------------------
47 | * Error callback prototype
48 | *
49 | * message: error message
50 | * ply: handle returned by ply_open or ply_create
51 | * ---------------------------------------------------------------------- */
52 | typedef void (*p_ply_error_cb)(p_ply ply, const char *message);
53 |
54 | /* ----------------------------------------------------------------------
55 | * Gets user data from within an error callback
56 | *
57 | * ply: handle returned by ply_open or ply_create
58 | * idata,pdata: contextual information set in ply_open or ply_create
59 | * ---------------------------------------------------------------------- */
60 | int ply_get_ply_user_data(p_ply ply, void **pdata, long *idata);
61 |
62 | /* ----------------------------------------------------------------------
63 | * Opens a PLY file for reading (fails if file is not a PLY file)
64 | *
65 | * name: file name
66 | * error_cb: error callback function
67 | * idata,pdata: contextual information available to users
68 | *
69 | * Returns 1 if successful, 0 otherwise
70 | * ---------------------------------------------------------------------- */
71 | p_ply ply_open(const char *name, p_ply_error_cb error_cb, long idata,
72 | void *pdata);
73 |
74 | /* ----------------------------------------------------------------------
75 | * Reads and parses the header of a PLY file returned by ply_open
76 | *
77 | * ply: handle returned by ply_open
78 | *
79 | * Returns 1 if successfull, 0 otherwise
80 | * ---------------------------------------------------------------------- */
81 | int ply_read_header(p_ply ply);
82 |
83 | /* ----------------------------------------------------------------------
84 | * Property reading callback prototype
85 | *
86 | * argument: parameters for property being processed when callback is called
87 | *
88 | * Returns 1 if should continue processing file, 0 if should abort.
89 | * ---------------------------------------------------------------------- */
90 | typedef int (*p_ply_read_cb)(p_ply_argument argument);
91 |
92 | /* ----------------------------------------------------------------------
93 | * Sets up callbacks for property reading after header was parsed
94 | *
95 | * ply: handle returned by ply_open
96 | * element_name: element where property is
97 | * property_name: property to associate element with
98 | * read_cb: function to be called for each property value
99 | * pdata/idata: user data that will be passed to callback
100 | *
101 | * Returns 0 if no element or no property in element, returns the
102 | * number of element instances otherwise.
103 | * ---------------------------------------------------------------------- */
104 | long ply_set_read_cb(p_ply ply, const char *element_name,
105 | const char *property_name, p_ply_read_cb read_cb,
106 | void *pdata, long idata);
107 |
108 | /* ----------------------------------------------------------------------
109 | * Returns information about the element originating a callback
110 | *
111 | * argument: handle to argument
112 | * element: receives a the element handle (if non-null)
113 | * instance_index: receives the index of the current element instance
114 | * (if non-null)
115 | *
116 | * Returns 1 if successfull, 0 otherwise
117 | * ---------------------------------------------------------------------- */
118 | int ply_get_argument_element(p_ply_argument argument,
119 | p_ply_element *element, long *instance_index);
120 |
121 | /* ----------------------------------------------------------------------
122 | * Returns information about the property originating a callback
123 | *
124 | * argument: handle to argument
125 | * property: receives the property handle (if non-null)
126 | * length: receives the number of values in this property (if non-null)
127 | * value_index: receives the index of current property value (if non-null)
128 | *
129 | * Returns 1 if successfull, 0 otherwise
130 | * ---------------------------------------------------------------------- */
131 | int ply_get_argument_property(p_ply_argument argument,
132 | p_ply_property *property, long *length, long *value_index);
133 |
134 | /* ----------------------------------------------------------------------
135 | * Returns user data associated with callback
136 | *
137 | * pdata: receives a copy of user custom data pointer (if non-null)
138 | * idata: receives a copy of user custom data integer (if non-null)
139 | *
140 | * Returns 1 if successfull, 0 otherwise
141 | * ---------------------------------------------------------------------- */
142 | int ply_get_argument_user_data(p_ply_argument argument, void **pdata,
143 | long *idata);
144 |
145 | /* ----------------------------------------------------------------------
146 | * Returns the value associated with a callback
147 | *
148 | * argument: handle to argument
149 | *
150 | * Returns the current data item
151 | * ---------------------------------------------------------------------- */
152 | double ply_get_argument_value(p_ply_argument argument);
153 |
154 | /* ----------------------------------------------------------------------
155 | * Reads all elements and properties calling the callbacks defined with
156 | * calls to ply_set_read_cb
157 | *
158 | * ply: handle returned by ply_open
159 | *
160 | * Returns 1 if successfull, 0 otherwise
161 | * ---------------------------------------------------------------------- */
162 | int ply_read(p_ply ply);
163 |
164 | /* ----------------------------------------------------------------------
165 | * Iterates over all elements by returning the next element.
166 | * Call with NULL to return handle to first element.
167 | *
168 | * ply: handle returned by ply_open
169 | * last: handle of last element returned (NULL for first element)
170 | *
171 | * Returns element if successfull or NULL if no more elements
172 | * ---------------------------------------------------------------------- */
173 | p_ply_element ply_get_next_element(p_ply ply, p_ply_element last);
174 |
175 | /* ----------------------------------------------------------------------
176 | * Iterates over all comments by returning the next comment.
177 | * Call with NULL to return pointer to first comment.
178 | *
179 | * ply: handle returned by ply_open
180 | * last: pointer to last comment returned (NULL for first comment)
181 | *
182 | * Returns comment if successfull or NULL if no more comments
183 | * ---------------------------------------------------------------------- */
184 | const char *ply_get_next_comment(p_ply ply, const char *last);
185 |
186 | /* ----------------------------------------------------------------------
187 | * Iterates over all obj_infos by returning the next obj_info.
188 | * Call with NULL to return pointer to first obj_info.
189 | *
190 | * ply: handle returned by ply_open
191 | * last: pointer to last obj_info returned (NULL for first obj_info)
192 | *
193 | * Returns obj_info if successfull or NULL if no more obj_infos
194 | * ---------------------------------------------------------------------- */
195 | const char *ply_get_next_obj_info(p_ply ply, const char *last);
196 |
197 | /* ----------------------------------------------------------------------
198 | * Returns information about an element
199 | *
200 | * element: element of interest
201 | * name: receives a pointer to internal copy of element name (if non-null)
202 | * ninstances: receives the number of instances of this element (if non-null)
203 | *
204 | * Returns 1 if successfull or 0 otherwise
205 | * ---------------------------------------------------------------------- */
206 | int ply_get_element_info(p_ply_element element, const char** name,
207 | long *ninstances);
208 |
209 | /* ----------------------------------------------------------------------
210 | * Iterates over all properties by returning the next property.
211 | * Call with NULL to return handle to first property.
212 | *
213 | * element: handle of element with the properties of interest
214 | * last: handle of last property returned (NULL for first property)
215 | *
216 | * Returns element if successfull or NULL if no more properties
217 | * ---------------------------------------------------------------------- */
218 | p_ply_property ply_get_next_property(p_ply_element element,
219 | p_ply_property last);
220 |
221 | /* ----------------------------------------------------------------------
222 | * Returns information about a property
223 | *
224 | * property: handle to property of interest
225 | * name: receives a pointer to internal copy of property name (if non-null)
226 | * type: receives the property type (if non-null)
227 | * length_type: for list properties, receives the scalar type of
228 | * the length field (if non-null)
229 | * value_type: for list properties, receives the scalar type of the value
230 | * fields (if non-null)
231 | *
232 | * Returns 1 if successfull or 0 otherwise
233 | * ---------------------------------------------------------------------- */
234 | int ply_get_property_info(p_ply_property property, const char** name,
235 | e_ply_type *type, e_ply_type *length_type, e_ply_type *value_type);
236 |
237 | /* ----------------------------------------------------------------------
238 | * Creates new PLY file
239 | *
240 | * name: file name
241 | * storage_mode: file format mode
242 | * error_cb: error callback function
243 | * idata,pdata: contextual information available to users
244 | *
245 | * Returns handle to PLY file if successfull, NULL otherwise
246 | * ---------------------------------------------------------------------- */
247 | p_ply ply_create(const char *name, e_ply_storage_mode storage_mode,
248 | p_ply_error_cb error_cb, long idata, void *pdata);
249 |
250 | /* ----------------------------------------------------------------------
251 | * Adds a new element to the PLY file created by ply_create
252 | *
253 | * ply: handle returned by ply_create
254 | * name: name of new element
255 | * ninstances: number of element of this time in file
256 | *
257 | * Returns 1 if successfull, 0 otherwise
258 | * ---------------------------------------------------------------------- */
259 | int ply_add_element(p_ply ply, const char *name, long ninstances);
260 |
261 | /* ----------------------------------------------------------------------
262 | * Adds a new property to the last element added by ply_add_element
263 | *
264 | * ply: handle returned by ply_create
265 | * name: name of new property
266 | * type: property type
267 | * length_type: scalar type of length field of a list property
268 | * value_type: scalar type of value fields of a list property
269 | *
270 | * Returns 1 if successfull, 0 otherwise
271 | * ---------------------------------------------------------------------- */
272 | int ply_add_property(p_ply ply, const char *name, e_ply_type type,
273 | e_ply_type length_type, e_ply_type value_type);
274 |
275 | /* ----------------------------------------------------------------------
276 | * Adds a new list property to the last element added by ply_add_element
277 | *
278 | * ply: handle returned by ply_create
279 | * name: name of new property
280 | * length_type: scalar type of length field of a list property
281 | * value_type: scalar type of value fields of a list property
282 | *
283 | * Returns 1 if successfull, 0 otherwise
284 | * ---------------------------------------------------------------------- */
285 | int ply_add_list_property(p_ply ply, const char *name,
286 | e_ply_type length_type, e_ply_type value_type);
287 |
288 | /* ----------------------------------------------------------------------
289 | * Adds a new property to the last element added by ply_add_element
290 | *
291 | * ply: handle returned by ply_create
292 | * name: name of new property
293 | * type: property type
294 | *
295 | * Returns 1 if successfull, 0 otherwise
296 | * ---------------------------------------------------------------------- */
297 | int ply_add_scalar_property(p_ply ply, const char *name, e_ply_type type);
298 |
299 | /* ----------------------------------------------------------------------
300 | * Adds a new comment item
301 | *
302 | * ply: handle returned by ply_create
303 | * comment: pointer to string with comment text
304 | *
305 | * Returns 1 if successfull, 0 otherwise
306 | * ---------------------------------------------------------------------- */
307 | int ply_add_comment(p_ply ply, const char *comment);
308 |
309 | /* ----------------------------------------------------------------------
310 | * Adds a new obj_info item
311 | *
312 | * ply: handle returned by ply_create
313 | * comment: pointer to string with obj_info data
314 | *
315 | * Returns 1 if successfull, 0 otherwise
316 | * ---------------------------------------------------------------------- */
317 | int ply_add_obj_info(p_ply ply, const char *obj_info);
318 |
319 | /* ----------------------------------------------------------------------
320 | * Writes the PLY file header after all element and properties have been
321 | * defined by calls to ply_add_element and ply_add_property
322 | *
323 | * ply: handle returned by ply_create
324 | *
325 | * Returns 1 if successfull, 0 otherwise
326 | * ---------------------------------------------------------------------- */
327 | int ply_write_header(p_ply ply);
328 |
329 | /* ----------------------------------------------------------------------
330 | * Writes one property value, in the order they should be written to the
331 | * file. For each element type, write all elements of that type in order.
332 | * For each element, write all its properties in order. For scalar
333 | * properties, just write the value. For list properties, write the length
334 | * and then each of the values.
335 | *
336 | * ply: handle returned by ply_create
337 | *
338 | * Returns 1 if successfull, 0 otherwise
339 | * ---------------------------------------------------------------------- */
340 | int ply_write(p_ply ply, double value);
341 |
342 | /* ----------------------------------------------------------------------
343 | * Closes a PLY file handle. Releases all memory used by handle
344 | *
345 | * ply: handle to be closed.
346 | *
347 | * Returns 1 if successfull, 0 otherwise
348 | * ---------------------------------------------------------------------- */
349 | int ply_close(p_ply ply);
350 |
351 | #ifdef __cplusplus
352 | }
353 | #endif
354 |
355 | #endif /* RPLY_H */
356 |
357 | /* ----------------------------------------------------------------------
358 | * Copyright (C) 2003-2015 Diego Nehab. All rights reserved.
359 | *
360 | * Permission is hereby granted, free of charge, to any person obtaining
361 | * a copy of this software and associated documentation files (the
362 | * "Software"), to deal in the Software without restriction, including
363 | * without limitation the rights to use, copy, modify, merge, publish,
364 | * distribute, sublicense, and/or sell copies of the Software, and to
365 | * permit persons to whom the Software is furnished to do so, subject to
366 | * the following conditions:
367 | *
368 | * The above copyright notice and this permission notice shall be
369 | * included in all copies or substantial portions of the Software.
370 | *
371 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
372 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
373 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
374 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
375 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
376 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
377 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
378 | * ---------------------------------------------------------------------- */
379 |
--------------------------------------------------------------------------------