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