1 #include <iostream>
2 #include <fstream>
3 #include "bwm_observer_mgr.h"
4 //:
5 // \file
6 #include "algo/bwm_utils.h"
7 #include "bwm_world.h"
8 #include "bwm_3d_corr.h"
9 #include "vgl/vgl_point_2d.h"
10 #include "vgl/vgl_vector_2d.h"
11 #include "vgl/vgl_point_3d.h"
12 #include "vgl/vgl_plane_3d.h"
13 #include <vpgl/algo/vpgl_rational_adjust_onept.h>
14 #include "vsl/vsl_basic_xml_element.h"
15 #include <vsol/vsol_point_3d.h>
16 #include <vsol/vsol_polygon_3d.h>
17 #include "vgui/vgui_soview.h"
18 #include "vgui/vgui_dialog.h"
19 #ifdef _MSC_VER
20 # include "vcl_msvc_warnings.h"
21 #endif
22
23 bwm_observer_cam* bwm_observer_mgr::BWM_MASTER_OBSERVER = nullptr;
24 bwm_observer_cam* bwm_observer_mgr::BWM_EO_OBSERVER = nullptr;
25 bwm_observer_cam* bwm_observer_mgr::BWM_OTHER_MODE_OBSERVER = nullptr;
26
27 bwm_observer_mgr* bwm_observer_mgr::instance_ = nullptr;
28
instance()29 bwm_observer_mgr* bwm_observer_mgr::instance()
30 {
31 if (!instance_)
32 instance_ = new bwm_observer_mgr();
33 return bwm_observer_mgr::instance_;
34 }
35
clear()36 void bwm_observer_mgr::clear()
37 {
38 corr_mode_ = IMAGE_TO_IMAGE;
39 n_corrs_ = SINGLE_PT_CORR;
40 corr_type_ = FEATURE_CORR;
41 start_corr_ = false;
42 corr_list_.clear();
43 }
44
observers_cam() const45 std::vector<bwm_observer_cam*> bwm_observer_mgr::observers_cam() const
46 {
47 std::vector<bwm_observer_cam*> v;
48 for (unsigned i=0; i< observers_.size(); i++) {
49 if (observers_[i]->type_name().compare("bwm_observer_cam") == 0)
50 v.push_back(static_cast<bwm_observer_cam*> (observers_[i]));
51 if (observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0)
52 v.push_back(static_cast<bwm_observer_cam*> (observers_[i]));
53 if (observers_[i]->type_name().compare("bwm_observer_proj_cam") == 0)
54 v.push_back(static_cast<bwm_observer_cam*> (observers_[i]));
55 if (observers_[i]->type_name().compare("bwm_observer_geo_cam") == 0)
56 v.push_back(static_cast<bwm_observer_cam*> (observers_[i]));
57 if (observers_[i]->type_name().compare("bwm_observer_video") == 0)
58 v.push_back(static_cast<bwm_observer_cam*> (observers_[i]));
59 }
60 return v;
61 }
62
observers_rat_cam() const63 std::vector<bwm_observer_rat_cam*> bwm_observer_mgr::observers_rat_cam() const
64 {
65 std::vector<bwm_observer_rat_cam*> v;
66
67 for (unsigned i=0; i< observers_.size(); i++) {
68 if (observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0)
69 v.push_back(static_cast<bwm_observer_rat_cam*> (observers_[i]));
70 }
71
72 return v;
73 }
74
add(bwm_observer * o)75 void bwm_observer_mgr::add(bwm_observer* o)
76 {
77 observers_.push_back(o);
78
79 // make the connection between this observer and the available observables
80 std::vector<bwm_observable_sptr> objects = bwm_world::instance()->objects();
81 #if 0
82 vgui_message msg;
83 msg.data = "new";
84 #endif
85 for (unsigned i=0; i<objects.size(); i++) {
86 bwm_observable_sptr obj = objects[i];
87 if (!obj)
88 std::cerr << "ERROR: world has an invalid (NULL) object!\n";
89 else {
90 obj->attach(o);
91 o->add_new_obj(obj);
92 }
93 }
94 }
95
attach(bwm_observable_sptr obs)96 void bwm_observer_mgr::attach(bwm_observable_sptr obs)
97 {
98 for (unsigned i=0; i<observers_.size(); i++)
99 obs->attach(observers_[i]);
100 }
101
detach(bwm_observable_sptr obs)102 void bwm_observer_mgr::detach(bwm_observable_sptr obs)
103 {
104 for (unsigned i=0; i<observers_.size(); i++)
105 obs->detach(observers_[i]);
106 }
107
remove(bwm_observer * observer)108 void bwm_observer_mgr::remove(bwm_observer* observer)
109 {
110 for (unsigned i=0; i<observers_.size(); i++)
111 if (observers_[i] == observer)
112 observers_.erase(observers_.begin()+i);
113 }
114
comp_avg_camera_center(vgl_point_3d<double> & cam_center)115 bool bwm_observer_mgr::comp_avg_camera_center(vgl_point_3d<double> &cam_center)
116 {
117 unsigned num = 0;
118 double x=0, y=0, z=0;
119 vgl_point_3d<double> c;
120
121 // go through the camera observers and compute a camera center
122 for (unsigned i=0; i<observers_.size(); i++) {
123 if (observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0) {
124 bwm_observer_rat_cam* obs = static_cast<bwm_observer_rat_cam*> (observers_[i]);
125 obs->camera_center(c);
126 vgl_point_3d<double> temp(c);
127 x += temp.x();
128 y += temp.y();
129 z += temp.z();
130 num++;
131 }
132 }
133
134 if (num == 0)
135 return false;
136
137 cam_center.set(x/num, y/num, z/num);
138 return true;
139 }
140
141 #if 0
142 //: Set a world point to be used in correspondences from world to image
143 void bwm_observer_mgr::set_world_pt(vgl_point_3d<double> world_pt)
144 {
145 corr_world_pt_ = world_pt;
146 world_point_valid_ = true;
147 }
148 #endif
149
150 //: Set the correspondence mode which is either image_to_image or world_to_image
151 // The world_to_image mode is only possible if there is a world point available
152 // The existence of a valid world point is defined by the flag \a world_point_valid_
set_corr_mode()153 void bwm_observer_mgr::set_corr_mode()
154 {
155 vgui_dialog params ("Correspondence Mode");
156 std::string empty="";
157 std::vector<std::string> modes;
158 int mode = bwm_observer_mgr::instance()->corr_mode();
159 modes.push_back("Image to Image");
160 modes.push_back("World to Image");
161 modes.push_back("Image to Fiducial");
162
163 std::vector<std::string> n_corrs;
164 int n = bwm_observer_mgr::instance()->n_corrs();
165 n_corrs.push_back("Single Correspondence ");
166 n_corrs.push_back("Multiple Correspondence ");
167
168 std::vector<std::string> types;
169 int t = bwm_observer_mgr::instance()->corr_type();
170 types.push_back("Feature Correspondence ");
171 types.push_back("Terrain Correspondence ");
172 types.push_back("Fiducial Position ");
173
174 std::string name, type;
175 params.choice("Correspondence Mode", modes, mode);
176 params.choice("Correspondence Type ", types, t);
177 params.choice("Number of Correspondences ", n_corrs, n);
178
179 if (!params.ask())
180 return;
181 if (mode ==bwm_observer_mgr::WORLD_TO_IMAGE) {
182 if (bwm_world::instance()->world_pt_valid()) {
183 corr_mode_ = bwm_observer_mgr::WORLD_TO_IMAGE;
184 return;
185 }
186 else {
187 std::cout << "In bwm_observer_mgr::set_corr_mode() -\n"
188 << " can't use WORLD_TO_IMAGE mode since the 3-d world"
189 << " point is not defined" << std::endl;
190 }
191 }else if(mode ==bwm_observer_mgr::IMAGE_TO_IMAGE){
192 corr_mode_ = bwm_observer_mgr::IMAGE_TO_IMAGE;
193 }else if(mode ==bwm_observer_mgr::FIDUCIAL_IMAGE_LOCATION){
194 corr_mode_ = bwm_observer_mgr::FIDUCIAL_IMAGE_LOCATION;
195 }
196 if (t == bwm_observer_mgr::FEATURE_CORR) {
197 corr_type_ = bwm_observer_mgr::FEATURE_CORR;
198 }
199 else if (t == bwm_observer_mgr::TERRAIN_CORR) {
200 corr_type_ = bwm_observer_mgr::TERRAIN_CORR;
201 }else if(t == bwm_observer_mgr::FIDUCIAL_CORR){
202 corr_type_ = bwm_observer_mgr::FIDUCIAL_CORR;
203 }else
204 std::cout << "In bwm_observer_mgr::set_corr_mode() Undefined TYPE - " << t << std::endl;
205
206 corr_mode_ = bwm_observer_mgr::IMAGE_TO_IMAGE;
207
208 n_corrs_ = (BWM_N_CORRS) n;
209 }
210
collect_corr()211 void bwm_observer_mgr::collect_corr()
212 {
213 bwm_corr_sptr corr = new bwm_corr();
214 vgl_point_2d<double> pt;
215
216 // set mode
217 if (corr_mode_ == IMAGE_TO_IMAGE)
218 corr->set_mode(true);
219 else if (corr_mode_ == WORLD_TO_IMAGE) {
220 vgl_point_3d<double> wpt;
221 if (!bwm_world::instance()->world_pt(wpt))
222 {
223 std::cerr << " In bwm_observer_mgr::collect_corr() -"
224 << " Can't do world to image, world pt invalid\n";
225 return;
226 }
227 corr->set_mode(false);
228 corr->set_world_pt(wpt);
229 }
230 else
231 std::cerr << "Unknown correspondence mode!\n";
232
233 bool found = false;
234 std::vector<bwm_observer_cam*> obs_cam = this->observers_cam();
235 for (unsigned i=0; i< obs_cam.size(); i++) {
236 bwm_observer_cam* obs = obs_cam[i];
237 if (obs->corr_pt(pt)) {
238 corr->set_match(obs, pt.x(), pt.y());
239 obs->record_corr_pt();
240 found = true;
241 }
242 }
243
244 if (found)
245 {
246 if (n_corrs_==MULTIPLE_CORRS) {
247 if (corr_type_ == FEATURE_CORR)
248 corr_list_.push_back(corr);
249 else if (corr_type_ == TERRAIN_CORR)
250 terrain_corr_list_.push_back(corr);
251 return;
252 }
253 else if (n_corrs_==SINGLE_PT_CORR) // in this case there can be only one
254 {
255 if (corr_type_ == FEATURE_CORR) {
256 corr_list_.clear();
257 corr_list_.push_back(corr);
258 }
259 else if (corr_type_ == TERRAIN_CORR) {
260 terrain_corr_list_.clear();
261 terrain_corr_list_.push_back(corr);
262 }
263 return;
264 }
265 }
266 std::cerr << "No Correspondence SET yet!!\n";
267 }
268
set_corr(bwm_corr_sptr corr)269 void bwm_observer_mgr::set_corr(bwm_corr_sptr corr)
270 {
271 if (corr->num_matches() > 0) {
272 if (corr_type_ == FEATURE_CORR) {
273 corr_list_.push_back(corr);
274 }
275 else if (corr_type_ == TERRAIN_CORR) {
276 terrain_corr_list_.push_back(corr);
277 }
278 }
279 }
280
update_corr(bwm_observer_cam * obs,vgl_point_2d<double> old_pt,vgl_point_2d<double> new_pt)281 void bwm_observer_mgr::update_corr(bwm_observer_cam* obs,
282 vgl_point_2d<double> old_pt,
283 vgl_point_2d<double> new_pt)
284 {
285 for (unsigned i=0; i< corr_list_.size(); i++) {
286 if (corr_type_ == FEATURE_CORR) {
287 bwm_corr_sptr corr = corr_list_[i];
288 if (corr->update_match(obs, old_pt, new_pt))
289 return;
290 }
291 else if (corr_type_ == TERRAIN_CORR) {
292 bwm_corr_sptr corr = terrain_corr_list_[i];
293 if (corr->update_match(obs, old_pt, new_pt))
294 return;
295 }
296 }
297 }
298
299 //: finds out if that observer involved with any of the correspondences
obs_in_corr(bwm_observer_cam * obs)300 bool bwm_observer_mgr::obs_in_corr(bwm_observer_cam *obs)
301 {
302 for (unsigned i=0; i<corr_list_.size(); i++) {
303 vgl_point_2d<double> c;
304 if (corr_list_[i]->obs_in(obs, c))
305 return true;
306 }
307 return false;
308 }
309
310 //: returns the list correspondence points of a given observer
311 std::vector<vgl_point_2d<double> >
get_corr_points(bwm_observer_cam * obs)312 bwm_observer_mgr::get_corr_points(bwm_observer_cam *obs)
313 {
314 std::vector<vgl_point_2d<double> > corr_list;
315 for (unsigned i=0; i<corr_list_.size(); i++) {
316 vgl_point_2d<double> corr;
317 if (corr_list_[i]->obs_in(obs, corr)) {
318 corr_list.push_back(corr);
319 }
320 }
321 return corr_list;
322 }
323
save_corr(std::ostream & s)324 void bwm_observer_mgr::save_corr(std::ostream& s)
325 {
326 if (corr_list_.size() == 0)
327 std::cerr << "No correspondences to save yet!\n";
328 else
329 {
330 #if 0
331 std::string fname = bwm_utils::select_file();
332 std::ofstream s(fname.data());
333
334 s << "Cameras:" << std::endl;
335 #endif
336 // first write down the camera info
337 std::map<bwm_observer_cam*, unsigned> camera_map;
338 for (unsigned i=0; i< observers_.size(); i++)
339 {
340 if ((observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0) ||
341 (observers_[i]->type_name().compare("bwm_observer_cam_proj") == 0))
342 {
343 bwm_observer_cam* obs = static_cast<bwm_observer_cam *> (observers_[i]);
344
345 // check if that camera is involved with any of the correspondences
346 if (obs_in_corr(obs)) {
347 s << "CAM_TAB: " << i << '\n'
348 << "IMAGE: " << obs->image_tableau()->file_name() << '\n'
349 << "CAMERA_TYPE: ";
350 if (observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0)
351 s << "rational" << std::endl;
352 else if (observers_[i]->type_name().compare("bwm_observer_cam_proj") == 0)
353 s << "projective" << std::endl;
354 s << "CAMERA_PATH: " << obs->camera_path() << '\n' << std::endl;
355 camera_map[obs] = i;
356 }
357 }
358 }
359
360 s << "CORRESPONDENCES: " << corr_list_.size() << '\n'
361 << "CORR_MODE: ";
362 if (corr_mode_ == IMAGE_TO_IMAGE)
363 s << "IMAGE_TO_IMAGE" << std::endl;
364 else
365 s << "WORLD_TO_IMAGE" << std::endl;
366 for (unsigned i=0; i< corr_list_.size(); i++)
367 {
368 bwm_corr_sptr corr = corr_list_[i];
369 s << "C: " << corr->num_matches() << std::endl;
370
371 std::vector<bwm_observer_cam*> obs = corr->observers();
372 #if 0
373 s << obs.size() << std::endl;
374 #endif
375 if (! corr->mode()) { // WORLD TO IMAGE
376 s << "WORLD_POINT: " << corr->world_pt().x() << ' ' << corr->world_pt().y()
377 << ' ' << corr->world_pt().z() << std::endl;
378 }
379 for (unsigned j=0; j< obs.size(); j++) {
380 vgl_point_2d<double> p;
381 if (corr->match(obs[j], p))
382 s << camera_map[obs[j]] << ' ' << p.x() << ' ' << p.y() << std::endl;
383 }
384 }
385 s << "END" << std::endl;
386 }
387 }
388
save_corr_XML()389 void bwm_observer_mgr::save_corr_XML()
390 {
391 if (corr_list_.size() == 0)
392 std::cerr << "No correspondences to save yet!\n";
393 else
394 {
395 std::string fname = bwm_utils::select_file();
396 std::ofstream s(fname.data());
397
398 s << "<BWM_CONFIG>" << '\n'
399 << "<TABLEAUS>" << std::endl;
400 // first write down the camera info
401 std::map<bwm_observer_cam*, unsigned> camera_map;
402 for (unsigned i=0; i< observers_.size(); i++)
403 {
404 if ((observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0) ||
405 (observers_[i]->type_name().compare("bwm_observer_cam_proj") == 0))
406 {
407 bwm_observer_cam* obs = static_cast<bwm_observer_cam *> (observers_[i]);
408
409 // check if that camera is involved with any of the correspondences
410 if (obs_in_corr(obs))
411 {
412 vsl_basic_xml_element tab("CameraTableau");
413 tab.add_attribute("name", obs->tab_name());
414 tab.x_write_open(s);
415
416 vsl_basic_xml_element img_path("imagePath");
417 img_path.append_cdata(obs->image_tableau()->file_name());
418 img_path.x_write(s);
419
420 std::string type;
421 if (observers_[i]->type_name().compare("bwm_observer_rat_cam") == 0)
422 type = "rational";
423 else if (observers_[i]->type_name().compare("bwm_observer_cam_proj") == 0)
424 type = "projective";
425
426 vsl_basic_xml_element cam_path("cameraPath");
427 cam_path.add_attribute("type", type);
428 cam_path.append_cdata(obs->camera_path());
429 cam_path.x_write(s);
430 camera_map[obs] = i;
431 tab.x_write_close(s);
432 }
433 }
434 }
435 s << "</TABLEAUS>" << std::endl;
436
437 // write out the correspondence list
438 std::string m = "";
439 if (corr_mode_ == IMAGE_TO_IMAGE)
440 m = "IMAGE_TO_IMAGE";
441 else
442 m = "WORLD_TO_IMAGE";
443 vsl_basic_xml_element xml_element("Correspondences");
444 xml_element.add_attribute("mode", m);
445
446 std::string n = "";
447 if (n_corrs_==MULTIPLE_CORRS)
448 n = "MULTIPLE";
449 else
450 n = "SINGLE";
451 xml_element.add_attribute("type", n);
452 xml_element.x_write_open(s);
453
454
455 for (unsigned i=0; i< corr_list_.size(); i++) {
456 bwm_corr_sptr corr = corr_list_[i];
457 std::cout << corr->num_matches() << std::endl;
458 corr->x_write(s);
459 }
460 xml_element.x_write_close(s);
461 s << "</BWM_CONFIG>" << std::endl;
462 }
463 }
464
delete_last_corr()465 void bwm_observer_mgr::delete_last_corr()
466 {
467 unsigned i = corr_list_.size();
468 if (i > 0) {
469 // first notify the observer to delete the corr point on the screen
470 bwm_corr_sptr corr = corr_list_[i-1];
471 std::vector<bwm_observer_cam*> obs = corr->observers();
472 for (unsigned i=0; i<obs.size(); i++) {
473 obs[i]->remove_corr_pt();
474 obs[i]->post_redraw();
475 }
476 corr_list_.pop_back(); // removes the last element
477 }
478 }
479
delete_all_corr()480 void bwm_observer_mgr::delete_all_corr()
481 {
482 while (corr_list_.size() > 0) {
483 delete_last_corr();
484 }
485 }
486
print_observers()487 void bwm_observer_mgr::print_observers()
488 {
489 for (unsigned i=0; i< observers_.size(); i++) {
490 std::cout << i << " - " << observers_[i]->type_name() << std::endl;
491 }
492 }
493
move_to_corr()494 void bwm_observer_mgr::move_to_corr()
495 {
496 if (!corr_list_.size())
497 {
498 std::cerr << "In bwm_observer_mgr::move_to_corr() -"
499 << " no correspondences to move to\n";
500 return;
501 }
502 bwm_corr_sptr corr = corr_list_[0];
503 std::vector<bwm_observer_cam*> obs = corr->observers();
504 for (std::vector<bwm_observer_cam*>::iterator oit = obs.begin();
505 oit != obs.end(); ++oit)
506 {
507 vgl_point_2d<double> p;
508 //observer has a match so can zoom
509 if (corr->match(*oit, p))
510 {
511 float x = static_cast<float>(p.x());
512 float y = static_cast<float>(p.y());
513 (*oit)->move_to_point(x, y);
514 }
515 }
516 }
517
adjust_camera_offsets()518 void bwm_observer_mgr::adjust_camera_offsets()
519 {
520 if (!corr_list_.size())
521 return;
522 bwm_corr_sptr corr = corr_list_[0];
523 std::vector<bwm_observer_cam*> obs = corr->observers();
524 std::vector<vpgl_rational_camera<double> > rcams;
525 std::vector<vgl_point_2d<double> > cpoints;
526 for (std::vector<bwm_observer_cam*>::iterator oit = obs.begin();
527 oit != obs.end(); ++oit)
528 {
529 if ((*oit)->type_name() != "bwm_observer_rat_cam")
530 continue;
531 bwm_observer_rat_cam* obscr =
532 static_cast<bwm_observer_rat_cam*>(*oit);
533 rcams.push_back(obscr->camera());
534 vgl_point_2d<double> p;
535 if (corr->match(*oit, p))
536 cpoints.push_back(p);
537 }
538 if (cpoints.size()!=rcams.size())
539 {
540 std::cerr << "In bwm_observer_mgr::adjust_image_offsets - "
541 << " inconsistent number of points and cameras\n";
542 return;
543 }
544
545 std::cout << "Executing adjust image offsets\n";
546 std::vector<vgl_vector_2d<double> > cam_trans;
547 vgl_point_3d<double> intersection;
548 if (!vpgl_rational_adjust_onept::adjust(rcams, cpoints, cam_trans,
549 intersection))
550 {
551 std::cerr << "In bwm_observer_rat_cam::adjust_image_offsets - "
552 << " adjustment failed\n";
553 return;
554 }
555
556 vgl_plane_3d<double> world_plane(0,0,1,-intersection.z());
557 std::vector<vgl_vector_2d<double> >::iterator ti = cam_trans.begin();
558 std::vector<bwm_observer_cam*>::iterator oit = obs.begin();
559 for (; oit != obs.end() && ti != cam_trans.end(); ++oit, ++ti)
560 {
561 if ((*oit)->type_name() != "bwm_observer_rat_cam")
562 continue;
563 bwm_observer_rat_cam* obsrc =
564 static_cast<bwm_observer_rat_cam*>(*oit);
565 std::cout << "Shifting camera[" << obsrc->camera_path() << "]:\n("
566 << (*ti).x() << ' ' << (*ti).y() << "):\n point_3d("
567 << intersection.x() << ' ' << intersection.y()
568 << ' ' << intersection.z() << ")\n";
569 obsrc->shift_camera((*ti).x(), (*ti).y());
570 // here is where we would set the terrain plane and maybe not
571 // do anything to the projection plane of each observer.
572 // but this approach works for now.
573 obsrc->set_proj_plane(world_plane);
574 obsrc->update_all();
575 }
576
577 // send the objects in the world the fact that they need to redisplay
578 std::vector<bwm_observable_sptr> objs = bwm_world::instance()->objects();
579 for (std::vector<bwm_observable_sptr>::iterator oit = objs.begin();
580 oit != objs.end(); ++oit)
581 (*oit)->send_update();
582
583 //
584 // now that the 3-d intersection is available, the correspondence mode
585 // should be changed to "world_to_image." The mode should only be
586 // changed back to "image_to_image" if a new image is added to the
587 // site and the intersection point is re-computed
588 //
589 for (std::vector<bwm_corr_sptr>::iterator cit = corr_list_.begin();
590 cit != corr_list_.end(); ++cit)
591 {
592 (*cit)->set_mode(false); //mode is set to world_to_image
593 (*cit)->set_world_pt(intersection);
594 }
595
596 bwm_world::instance()->set_world_pt(intersection);
597 this->set_corr_mode(bwm_observer_mgr::WORLD_TO_IMAGE);
598 }
599
find_terrain_points(std::vector<vgl_point_3d<double>> & points)600 void bwm_observer_mgr::find_terrain_points(std::vector<vgl_point_3d<double> >& points)
601 {
602 if (!terrain_corr_list_.size())
603 return;
604
605 for (unsigned i=0; i<terrain_corr_list_.size(); i++) {
606 bwm_corr_sptr corr = terrain_corr_list_[i];
607 std::vector<bwm_observer_cam*> obs = corr->observers();
608 std::vector<vpgl_rational_camera<double> > rcams;
609 std::vector<vgl_point_2d<double> > cpoints;
610 for (std::vector<bwm_observer_cam*>::iterator oit = obs.begin();
611 oit != obs.end(); ++oit)
612 {
613 if ((*oit)->type_name() != "bwm_observer_rat_cam")
614 continue;
615 bwm_observer_rat_cam* obscr =
616 static_cast<bwm_observer_rat_cam*>(*oit);
617 rcams.push_back(obscr->camera());
618 vgl_point_2d<double> p;
619 if (corr->match(*oit, p))
620 cpoints.push_back(p);
621 }
622 if (cpoints.size()!=rcams.size())
623 {
624 std::cerr << "In bwm_observer_mgr::adjust_image_offsets - "
625 << " inconsistent number of points and cameras\n";
626 return;
627 }
628
629 std::cout << "Executing adjust image offsets\n";
630 std::vector<vgl_vector_2d<double> > cam_trans;
631 vgl_point_3d<double> intersection;
632 if (!vpgl_rational_adjust_onept::adjust(rcams, cpoints, cam_trans,
633 intersection))
634 {
635 std::cerr << "In bwm_observer_rat_cam::find_terrain_points - "
636 << " adjustment failed\n";
637 return;
638 }
639 points.push_back(intersection);
640 }
641 terrain_corr_list_.clear();
642 }
643
644 //: find all selected polygons across all observers
645 std::vector<bwm_observable_sptr> bwm_observer_mgr::
all_selected_observables(std::string const & soview_type) const646 all_selected_observables(std::string const& soview_type) const
647 {
648 std::vector<bwm_observable_sptr> sel_obsbls;
649 std::vector<bwm_observer_cam*> obs_cam = this->observers_cam();
650
651 for (std::vector<bwm_observer_cam*>::iterator oit = obs_cam.begin();
652 oit != obs_cam.end(); ++oit) {
653 bwm_observer_cam* obs = *oit;
654 if (!obs) {
655 std::cout << "null observer in all_selected_observables\n";
656 return sel_obsbls;//empty
657 }
658 std::vector<vgui_soview*> soviews = obs->get_selected_soviews();
659 for (std::vector<vgui_soview*>::iterator sit = soviews.begin();
660 sit != soviews.end(); ++sit) {
661 if ((*sit)->type_name().compare(soview_type)==0) {
662 unsigned face_id;
663 bwm_observable_sptr obj=(*oit)->find_object(soviews[0]->get_id(),face_id);
664 if (obj) sel_obsbls.push_back(obj);
665 }
666 }
667 }
668
669
670 return sel_obsbls;
671 }
672
673 //: requires exactly two selected vertices each in a unique site
add_3d_corr_vertex()674 bool bwm_observer_mgr::add_3d_corr_vertex()
675 {
676 // not implemented yet
677 return true;
678 }
679
680 //: requires exactly two selected polygons each in a unique site. Corresponds centroids of the polygons
add_3d_corr_centroid()681 bool bwm_observer_mgr::add_3d_corr_centroid()
682 {
683 std::vector<bwm_observable_sptr> obs =
684 this->all_selected_observables("bgui_vsol_soview2D_polygon");
685 if (obs.size()!=2) {
686 std::cout << "must have exactly two polygons selected\n";
687 return false;
688 }
689 bwm_observable_sptr obs0 = obs[0], obs1 = obs[1];
690 if (obs0->site() == obs1->site()) {
691 std::cout << "each polygon must be from a different site\n";
692 return false;
693 }
694 std::map<int, vsol_polygon_3d_sptr> polys0 = obs0->extract_faces();
695 std::map<int, vsol_polygon_3d_sptr> polys1 = obs1->extract_faces();
696 if (polys0.size() !=1 || polys1.size() !=1) {
697 std::cout << "must be exactly 1 polygon in each observable\n";
698 return false;
699 }
700 std::map<int, vsol_polygon_3d_sptr>::iterator pit = polys0.begin();
701 vsol_polygon_3d_sptr poly0 = (*pit).second;
702 pit = polys1.begin();
703 vsol_polygon_3d_sptr poly1 = (*pit).second;
704 unsigned n0 = poly0->size(), n1 = poly1->size();
705 if (!n0||!n1) {
706 std::cout << "poly with no vertices in add_3d_corr";
707 return false;
708 }
709 double xc0 = 0.0, yc0 = 0.0, zc0 = 0.0;
710 double xc1 = 0.0, yc1 = 0.0, zc1 = 0.0;
711 for (unsigned i = 0; i<n0; ++i) {
712 vsol_point_3d_sptr vi = poly0->vertex(i);
713 xc0 += (*vi).x(); yc0 += (*vi).y(); zc0 += (*vi).z();
714 }
715 for (unsigned i = 0; i<n1; ++i) {
716 vsol_point_3d_sptr vi = poly1->vertex(i);
717 xc1 += (*vi).x(); yc1 += (*vi).y(); zc1 += (*vi).z();
718 }
719 bwm_3d_corr_sptr corr_3d = new bwm_3d_corr();
720 corr_3d->set_match(obs0->site(), xc0/n0, yc0/n0, zc0/n0);
721 corr_3d->set_match(obs1->site(), xc1/n1, yc1/n1, zc1/n1);
722 site_to_site_corr_list_.push_back(corr_3d);
723 return true;
724 }
725
726 //: save 3d_corrs
save_3d_corrs() const727 void bwm_observer_mgr::save_3d_corrs() const
728 {
729 std::string path = "";
730 std::string ext = "*.cor";
731 vgui_dialog corr_dlg("Save 3d Correspondences");
732 corr_dlg.file("Corr file", ext, path);
733 if (!corr_dlg.ask())
734 return;
735 bwm_observer_mgr::save_3d_corrs(path, site_to_site_corr_list_);
736 }
737
save_3d_corrs(std::string const & path,std::vector<bwm_3d_corr_sptr> const & corrs)738 void bwm_observer_mgr::save_3d_corrs(std::string const& path,
739 std::vector<bwm_3d_corr_sptr> const& corrs)
740 {
741 std::ofstream os(path.c_str());
742 if (!os.is_open())
743 {
744 std::cout << "couldn't open 3d_corr file path\n";
745 return ;
746 }
747 unsigned n = corrs.size();
748 if (!n) {
749 std::cout << "no 3d_corrs to save\n";
750 return ;
751 }
752 os << "Ncorrs: " << n << '\n';
753 for (unsigned i = 0; i<n; ++i)
754 os << *corrs[i];
755 }
756
757 //: load 3d_corrs
load_3d_corrs()758 void bwm_observer_mgr::load_3d_corrs()
759 {
760 std::string path = "";
761 std::string ext = "*.cor";
762 vgui_dialog corr_dlg("Load 3d Correspondences");
763 corr_dlg.file("Corr file", ext, path);
764 if (!corr_dlg.ask())
765 return;
766 bwm_observer_mgr::load_3d_corrs(path, site_to_site_corr_list_);
767 }
768
load_3d_corrs(std::string const & path,std::vector<bwm_3d_corr_sptr> & corrs)769 void bwm_observer_mgr::load_3d_corrs(std::string const& path,
770 std::vector<bwm_3d_corr_sptr>& corrs)
771 {
772 std::ifstream is(path.c_str());
773 if (!is.is_open())
774 {
775 std::cout << "couldn't open 3d_corr file path\n";
776 return ;
777 }
778 //clear out any existing correspondences
779 corrs.clear();
780 std::string temp, temp1, temp2;
781 is >> temp;
782 if (temp!="Ncorrs:") {
783 std::cout << "error in 3d_corr file 1\n";
784 return;
785 }
786 unsigned n_corrs = 0;
787 is >> n_corrs;
788 for (unsigned i = 0; i<n_corrs; ++i) {
789 is >> temp >> temp1 >> temp2;
790 if (temp2!="Sites:") {
791 std::cout << "error in 3d_corr file 2\n";
792 return;
793 }
794 unsigned n_sites = 0;
795 is >> n_sites;
796 double x = 0.0, y = 0.0, z = 0.0;
797 std::string site;
798 bwm_3d_corr_sptr corr = new bwm_3d_corr();
799 for (unsigned s = 0; s<n_sites; ++s) {
800 is >> temp >> temp1;
801 if (temp != "Site[") {
802 std::cout << "error in 3d_corr file 3\n";
803 return;
804 }
805 site = temp1;
806 is >> temp >> temp1;
807 if (temp1 != "X:") {
808 std::cout << "error in 3d_corr file 4\n";
809 return;
810 }
811 is >> x;
812 is >> temp;
813 if (temp != "Y:") {
814 std::cout << "error in 3d_corr file 5\n";
815 return;
816 }
817 is >> y;
818 is >> temp;
819 if (temp != "Z:") {
820 std::cout << "error in 3d_corr file 6\n";
821 return;
822 }
823 is >> z;
824 is >> temp;//eat up the trailing ")"
825 corr->set_match(site, x, y, z);
826 }
827 corrs.push_back(corr);
828 }
829 }
830