ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
automatic_reconstruction_widget.cc
Go to the documentation of this file.
1 // Copyright (c) 2018, ETH Zurich and UNC Chapel Hill.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
15 // its contributors may be used to endorse or promote products derived
16 // from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
31 
33 
34 #include "ui/main_window.h"
35 
36 namespace colmap {
37 
39  MainWindow* main_window)
40  : OptionsWidget(main_window),
41  main_window_(main_window),
42  thread_control_widget_(new ThreadControlWidget(this)) {
43  setWindowTitle("Automatic reconstruction");
44 
45  AddOptionDirPath(&options_.workspace_path, "Workspace folder");
46  AddSpacer();
47  AddOptionDirPath(&options_.image_path, "Image folder");
48  AddSpacer();
49  AddOptionDirPath(&options_.mask_path, "Mask folder");
50  AddSpacer();
51  AddOptionFilePath(&options_.vocab_tree_path, "Vocabulary tree<br>(optional)");
52 
53  AddSpacer();
54 
55  QLabel* data_type_label = new QLabel(tr("Data type"), this);
56  data_type_label->setFont(font());
57  data_type_label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
58  grid_layout_->addWidget(data_type_label, grid_layout_->rowCount(), 0);
59 
60  data_type_cb_ = new QComboBox(this);
61  data_type_cb_->addItem("Individual images");
62  data_type_cb_->addItem("Video frames");
63  data_type_cb_->addItem("Internet images");
64  grid_layout_->addWidget(data_type_cb_, grid_layout_->rowCount() - 1, 1);
65 
66  QLabel* quality_label = new QLabel(tr("Quality"), this);
67  quality_label->setFont(font());
68  quality_label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
69  grid_layout_->addWidget(quality_label, grid_layout_->rowCount(), 0);
70 
71  quality_cb_ = new QComboBox(this);
72  quality_cb_->addItem("Low");
73  quality_cb_->addItem("Medium");
74  quality_cb_->addItem("High");
75  quality_cb_->addItem("Extreme");
76  quality_cb_->setCurrentIndex(2);
77  grid_layout_->addWidget(quality_cb_, grid_layout_->rowCount() - 1, 1);
78 
79  AddSpacer();
80 
81  AddOptionBool(&options_.single_camera, "Shared intrinsics");
82  AddOptionBool(&options_.sparse, "Sparse model");
83  AddOptionBool(&options_.dense, "Dense model");
84  AddOptionBool(&options_.texturing, "Mesh texturing");
85 
86  QLabel* mesher_label = new QLabel(tr("Mesher"), this);
87  mesher_label->setFont(font());
88  mesher_label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
89  grid_layout_->addWidget(mesher_label, grid_layout_->rowCount(), 0);
90 
91  mesher_cb_ = new QComboBox(this);
92  mesher_cb_->addItem("Delaunay");
93  mesher_cb_->addItem("Poisson");
94  mesher_cb_->setCurrentIndex(0);
95  grid_layout_->addWidget(mesher_cb_, grid_layout_->rowCount() - 1, 1);
96 
97  AddSpacer();
98 
99  AddOptionInt(&options_.num_threads, "num_threads", -1);
100  AddOptionBool(&options_.use_gpu, "GPU");
101  AddOptionText(&options_.gpu_index, "gpu_index");
102 
103  AddSpacer();
104 
105  QPushButton* run_button = new QPushButton(tr("Run"), this);
106  grid_layout_->addWidget(run_button, grid_layout_->rowCount(), 1);
107  connect(run_button, &QPushButton::released, this,
109 
110  render_result_ = new QAction(this);
111  connect(render_result_, &QAction::triggered, this,
112  &AutomaticReconstructionWidget::RenderResult, Qt::QueuedConnection);
113 }
114 
116  WriteOptions();
117 
118  if (!ExistsDir(options_.workspace_path)) {
119  QMessageBox::critical(this, "", tr("Invalid workspace folder"));
120  return;
121  }
122 
123  if (!ExistsDir(options_.image_path)) {
124  QMessageBox::critical(this, "", tr("Invalid image folder"));
125  return;
126  }
127 
128  switch (data_type_cb_->currentIndex()) {
129  case 0:
130  options_.data_type =
132  break;
133  case 1:
135  break;
136  case 2:
137  options_.data_type =
139  break;
140  default:
141  options_.data_type =
143  break;
144  }
145 
146  switch (quality_cb_->currentIndex()) {
147  case 0:
149  break;
150  case 1:
152  break;
153  case 2:
155  break;
156  case 3:
158  break;
159  default:
161  break;
162  }
163 
164  switch (mesher_cb_->currentIndex()) {
165  case 0:
166  options_.mesher =
168  break;
169  case 1:
170  options_.mesher =
172  break;
173  default:
174  options_.mesher =
176  break;
177 }
178 
179  main_window_->reconstruction_manager_.Clear();
180  main_window_->reconstruction_manager_widget_->Update();
181  main_window_->RenderClear();
182  main_window_->RenderNow();
183 
186  options_, &main_window_->reconstruction_manager_);
187 
189  [this]() { render_result_->trigger(); });
190 
191  thread_control_widget_->StartThread("Reconstructing...", true, controller);
192 }
193 
194 void AutomaticReconstructionWidget::RenderResult() {
195  if (main_window_->reconstruction_manager_.Size() > 0) {
196  main_window_->reconstruction_manager_widget_->Update();
197  main_window_->RenderClear();
198  main_window_->RenderNow();
199  }
200 
201  if (options_.sparse) {
202  QMessageBox::information(
203  this, "",
204  tr("Imported the reconstructed sparse models for visualization. The "
205  "models were also exported to the <i>sparse</i> sub-folder in the "
206  "workspace."));
207  }
208 
209  if (options_.dense) {
210  QMessageBox::information(
211  this, "",
212  tr("To visualize the reconstructed dense point cloud, navigate to the "
213  "<i>dense</i> sub-folder in your workspace with <i>File > Import "
214  "model from...</i>. To visualize the meshed model, you must use an "
215  "external viewer such as Meshlab."));
216  }
217 }
218 
219 } // namespace colmap
QLineEdit * AddOptionText(std::string *option, const std::string &label_text)
QLineEdit * AddOptionFilePath(std::string *option, const std::string &label_text)
QSpinBox * AddOptionInt(int *option, const std::string &label_text, const int min=0, const int max=static_cast< int >(1e7))
QLineEdit * AddOptionDirPath(std::string *option, const std::string &label_text)
QGridLayout * grid_layout_
QCheckBox * AddOptionBool(bool *option, const std::string &label_text)
void StartThread(const QString &progress_text, const bool stoppable, Thread *thread)
void AddCallback(const int id, const std::function< void()> &func)
Definition: threading.cc:117
bool ExistsDir(const std::string &path)
Definition: misc.cc:104