1 /*
2     viewer.h: Contains the graphical user interface of Instant Meshes
3 
4     This file is part of the implementation of
5 
6         Instant Field-Aligned Meshes
7         Wenzel Jakob, Daniele Panozzo, Marco Tarini, and Olga Sorkine-Hornung
8         In ACM Transactions on Graphics (Proc. SIGGRAPH Asia 2015)
9 
10     All rights reserved. Use of this source code is governed by a
11     BSD-style license that can be found in the LICENSE.txt file.
12 */
13 
14 #pragma once
15 
16 #include "glutil.h"
17 #include "widgets.h"
18 #include "hierarchy.h"
19 #include "field.h"
20 #include "bvh.h"
21 #include "meshstats.h"
22 #include <set>
23 
24 using nanogui::Alignment;
25 using nanogui::Arcball;
26 using nanogui::BoxLayout;
27 using nanogui::Button;
28 using nanogui::CheckBox;
29 using nanogui::Color;
30 using nanogui::ComboBox;
31 using nanogui::GLFramebuffer;
32 using nanogui::GroupLayout;
33 using nanogui::ImagePanel;
34 using nanogui::Label;
35 using nanogui::MessageDialog;
36 using nanogui::Orientation;
37 using nanogui::Popup;
38 using nanogui::PopupButton;
39 using nanogui::ProgressBar;
40 using nanogui::Screen;
41 using nanogui::Slider;
42 using nanogui::TextBox;
43 using nanogui::ToolButton;
44 using nanogui::VScrollPanel;
45 using nanogui::Widget;
46 using nanogui::Window;
47 using nanogui::frustum;
48 using nanogui::lookAt;
49 using nanogui::project;
50 using nanogui::scale;
51 using nanogui::translate;
52 using nanogui::unproject;
53 using nanogui::utf8;
54 
55 struct CurvePoint;
56 
57 class Viewer : public Screen {
58 public:
59     Viewer(bool fullscreen, bool deterministic);
60     virtual ~Viewer();
61 
62     bool mouseMotionEvent(const Vector2i &p, const Vector2i &rel,
63                                   int button, int modifiers);
64 
65     bool mouseButtonEvent(const Vector2i &p, int button, bool down,
66                                   int modifiers);
67 
68     bool keyboardEvent(int key, int scancode, int action, int modifiers);
69 
70     bool scrollEvent(const Vector2i &p, const Vector2f &rel);
71 
72     void loadInput(std::string filename,
73                    Float creaseAngle = std::numeric_limits<Float>::infinity(),
74                    Float scale = -1, int face_count = -1, int vertex_count = -1,
75                    int rosy = 4, int posy = 4, int knn_points = 10);
76 
77     void setSymmetry(int rosy, int posy);
78     void setExtrinsic(bool extrinsic);
79 
80     void resetState();
81     void loadState(std::string filename, bool compat = false);
82     void saveState(std::string filename);
83     void renderMitsuba();
84     void setFloorPosition();
85     void draw(NVGcontext *ctx);
86 
87 protected:
88     void extractMesh();
89     void extractConsensusGraph();
90 
91     void drawContents();
92     void drawOverlay();
93 
94     bool resizeEvent(const Vector2i &size);
95 
96     void refreshColors();
97 
98     void traceFlowLines();
99 
100     void refreshStrokes();
101 
102     void showProgress(const std::string &caption, Float value);
103 
104     void computeCameraMatrices(Eigen::Matrix4f &model,
105                                Eigen::Matrix4f &view,
106                                Eigen::Matrix4f &proj);
107 
108     void setLevel(int level);
109     void setTargetScale(Float scale);
110     void setTargetVertexCount(uint32_t v);
111     void setTargetVertexCountPrompt(uint32_t v);
112 
113     bool createSmoothPath(const std::vector<Vector2i> &curve);
114 
115     void repaint();
116 
117     void setCreaseAnglePrompt(bool enabled, Float creaseAngle);
118     void shareGLBuffers();
119     bool refreshPositionSingularities();
120     bool refreshOrientationSingularities();
121     std::pair<Vector3f, Vector3f> singularityPositionAndNormal(uint32_t v) const;
122     bool toolActive() const;
123 
124 protected:
125     struct CameraParameters {
126         Arcball arcball;
127         float zoom = 1.0f, viewAngle = 45.0f;
128         float dnear = 0.05f, dfar = 100.0f;
129         Eigen::Vector3f eye = Eigen::Vector3f(0.0f, 0.0f, 5.0f);
130         Eigen::Vector3f center = Eigen::Vector3f(0.0f, 0.0f, 0.0f);
131         Eigen::Vector3f up = Eigen::Vector3f(0.0f, 1.0f, 5.0f);
132         Eigen::Vector3f modelTranslation = Eigen::Vector3f::Zero();
133         Eigen::Vector3f modelTranslation_start = Eigen::Vector3f::Zero();
134         float modelZoom = 1.0f;
135     };
136 
137     std::vector<std::pair<int, std::string>> mExampleImages;
138     std::string mFilename;
139     bool mDeterministic;
140     bool mUseHalfFloats;
141 
142     /* Data being processed */
143     std::map<uint32_t, uint32_t> mCreaseMap;
144     std::set<uint32_t> mCreaseSet;
145     VectorXb mNonmanifoldVertices;
146     VectorXb mBoundaryVertices;
147     MultiResolutionHierarchy mRes;
148     Optimizer mOptimizer;
149     BVH *mBVH;
150     MeshStats mMeshStats;
151     int mSelectedLevel;
152     Float mCreaseAngle;
153     Matrix4f mFloor;
154     VectorXu mE2E;
155 
156     /* Painting tools */
157     std::vector<Vector2i> mScreenCurve;
158     std::vector<std::pair<uint32_t, std::vector<CurvePoint>>> mStrokes;
159 
160     /* Extraction result */
161     MatrixXu mF_extracted;
162     MatrixXf mV_extracted;
163     MatrixXf mN_extracted, mNf_extracted;
164 
165     /* Camera / navigation / misc */
166     CameraParameters mCamera;
167     CameraParameters mCameraSnapshots[12];
168     Vector2i mTranslateStart;
169     bool mTranslate, mDrag;
170     std::map<uint32_t, uint32_t> mOrientationSingularities;
171     std::map<uint32_t, Vector2i> mPositionSingularities;
172     bool mContinueWithPositions;
173 
174     /* Colors */
175     Vector3f mSpecularColor, mBaseColor;
176     Vector3f mInteriorFactor, mEdgeFactor0;
177     Vector3f mEdgeFactor1, mEdgeFactor2;
178 
179     /* OpenGL objects */
180     GLFramebuffer mFBO;
181     SerializableGLShader mPointShader63, mPointShader24, mPointShader44;
182     SerializableGLShader mMeshShader63, mMeshShader24, mMeshShader44;
183     SerializableGLShader mOrientationFieldShader;
184     SerializableGLShader mPositionFieldShader;
185     SerializableGLShader mPositionSingularityShader;
186     SerializableGLShader mOrientationSingularityShader;
187     SerializableGLShader mFlowLineShader, mStrokeShader;
188     SerializableGLShader mOutputMeshShader;
189     SerializableGLShader mOutputMeshWireframeShader;
190     bool mNeedsRepaint;
191     uint32_t mDrawIndex;
192 
193     /* GUI-related */
194     enum Layers {
195         InputMesh,
196         InputMeshWireframe,
197         FaceLabels,
198         VertexLabels,
199         FlowLines,
200         OrientationField,
201         OrientationFieldSingularities,
202         PositionField,
203         PositionFieldSingularities,
204         BrushStrokes,
205         OutputMesh,
206         OutputMeshWireframe,
207         LayerCount
208     };
209 
210     CheckBox *mLayers[LayerCount];
211     ComboBox *mVisualizeBox, *mSymmetryBox;
212     CheckBox *mExtrinsicBox, *mAlignToBoundariesBox;
213     CheckBox *mCreaseBox, *mPureQuadBox;
214     ProgressButton *mSolveOrientationBtn, *mSolvePositionBtn;
215     Button *mHierarchyMinusButton, *mHierarchyPlusButton;
216     Button *mSaveBtn, *mSwitchBtn;
217     PopupButton *mExportBtn;
218     ToolButton *mOrientationComb, *mOrientationAttractor, *mOrientationScareBrush;
219     ToolButton *mEdgeBrush, *mPositionAttractor, *mPositionScareBrush;
220     TextBox *mHierarchyLevelBox, *mScaleBox, *mCreaseAngleBox;
221     TextBox *mOrientationSingularityBox, *mPositionSingularityBox, *mSmoothBox;
222     Slider *mScaleSlider, *mCreaseAngleSlider, *mSmoothSlider;
223     Slider *mOrientationFieldSizeSlider, *mOrientationFieldSingSizeSlider;
224     Slider *mPositionFieldSingSizeSlider, *mFlowLineSlider;
225 #ifdef VISUALIZE_ERROR
226     Graph *mGraph;
227 #endif
228 
229     /* Progress display */
230     std::function<void(const std::string &, Float)> mProgress;
231     Window *mProgressWindow;
232     ProgressBar *mProgressBar;
233     Label *mProgressLabel;
234     tbb::spin_mutex mProgressMutex;
235     double mLastProgressMessage;
236     double mOperationStart;
237     uint32_t mOutputMeshFaces, mOutputMeshLines;
238     uint32_t mFlowLineFaces, mStrokeFaces;
239 };
240