Nori  23
main.cpp
1 /*
2  This file is part of Nori, a simple educational ray tracer
3 
4  Copyright (c) 2015 by Wenzel Jakob, Romain Prévost
5 
6  Nori is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Nori is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <nori/block.h>
20 #include <nori/gui.h>
21 #include <filesystem/path.h>
22 #include <indicators/progress_bar.hpp>
23 
24 using namespace nori;
25 
26 
27 bool run_gui(std::string filename, bool is_xml) {
28  try {
29  nanogui::init();
30 
31  // Open the UI with a dummy image
32  ImageBlock block(Vector2i(720, 720), nullptr);
33  {
34  // Scoped
35  nanogui::ref<NoriScreen> screen = new NoriScreen(block);
36 
37  if (filename.length() > 0) {
38  if (is_xml) {
39  /* Render the XML scene file */
40  screen->openXML(filename);
41  } else {
42  /* Alternatively, provide a basic OpenEXR image viewer */
43  screen->openEXR(filename);
44  }
45  }
46 
47  nanogui::mainloop(50.f);
48  }
49 
50  nanogui::shutdown();
51 
52  } catch (const std::exception &e) {
53  cerr << "Fatal error: " << e.what() << endl;
54  return 1;
55  }
56 
57  return 0;
58 }
59 
60 
61 bool render_headless(std::string filename, bool is_xml) {
62  // TODOs - proper handling of an ctrl+z, progress bar, CL argument -b for headless
63  ImageBlock block(Vector2i(720, 720), nullptr);
64  RenderThread renderer(block);
65 
66  if (!filename.length()) {
67  cerr << "Need to provide an input XML file to render in headless mode" << endl;
68  return 1;
69  }
70 
71  if (!is_xml) {
72  cerr << "Only XML files supported in the headless mode" << endl;
73  return 1;
74  }
75 
76  try {
77  // StringBar m_cliBar;
78  renderer.renderScene(filename);
79 
80 #ifndef NORI_HEADLESS
81  indicators::ProgressBar bar{
82  indicators::option::PrefixText{"Rendering... "},
83  indicators::option::BarWidth{50},
84  indicators::option::ShowPercentage{true},
85  indicators::option::ShowElapsedTime{true},
86  indicators::option::ShowRemainingTime{true}
87  };
88  while (renderer.isBusy()) {
89  bar.set_progress(renderer.getProgress() * 100);
90  std::this_thread::sleep_for(std::chrono::seconds(1));
91  }
92 #else
93  while (renderer.isBusy()) {
94  std::this_thread::sleep_for(std::chrono::seconds(1));
95  }
96 #endif
97 
98  }
99  catch (const std::exception &e) {
100  cerr << "Failed to render in the headless mode " << e.what() << endl;
101  return 1;
102  }
103 
104  return 0;
105 }
106 
107 
108 int main(int argc, char **argv) {
109  std::string filename = "";
110  bool headless = false;
111 
112  for (int i = 1; i < argc; ++i) {
113  std::string token(argv[i]);
114  if (token == "--help") {
115  cout << "Syntax: " << argv[0] << "[-b] <scene.[xml|exr]>" << endl;
116  return 0;
117  }
118 
119  if (token == "-b" || token == "--background") {
120  headless = true;
121  continue;
122  }
123 
124  if (!filename.length()) {
125  filename = token;
126  continue;
127  } else {
128  cerr << "Syntax: " << argv[0] << "[-b] <scene.[xml|exr]>" << endl;
129  return -1;
130  }
131  }
132 
133  bool is_xml = false;
134  if (filename.length()) {
135  filesystem::path path(filename);
136 
137  if (path.extension() == "xml") {
138  is_xml = true;
139  } else if (path.extension() == "exr") {
140  /* Alternatively, provide a basic OpenEXR image viewer */
141  is_xml = false;
142  } else {
143  cerr << "Error: unknown file \"" << filename
144  << "\", expected an extension of type .xml or .exr" << endl;
145  }
146  }
147 
148 #ifdef NORI_HEADLESS
149  if (!headless) {
150  cout << "Forcing background mode" << endl;
151  headless = true;
152  }
153 #endif
154 
155  if (headless) {
156  return render_headless(filename, is_xml);
157  } else {
158  return run_gui(filename, is_xml);
159  }
160 
161 }
Weighted pixel storage for a rectangular subregion of an image.
Definition: block.h:48
Definition: gui.h:47