1 #include <iostream>
2 #include <cstdio>
3 #include <sstream>
4 #include "bwm_site_mgr.h"
5 //:
6 // \file
7 #include <bwm/io/bwm_site_sptr.h>
8 #include <bwm/io/bwm_site.h>
9 #include "bwm_observer_mgr.h"
10 #include "bwm_tableau_mgr.h"
11 #include "bwm_tableau_video.h"
12 #include "bwm_tableau_fiducial.h"
13 
14 #include "bwm_observable_mesh.h"
15 #include "bwm_world.h"
16 #include "bwm_def.h"
17 #include "algo/bwm_utils.h"
18 #include "video/bwm_video_site_io.h"
19 #include "video/bwm_video_corr.h"
20 #include "video/bwm_video_cam_istream.h"
21 #include "vpgl/vpgl_perspective_camera.h"
22 #include <bpgl/algo/bpgl_project.h>
23 #include <depth_map/depth_map_scene.h>
24 #include "vgl/vgl_point_3d.h"
25 #include "vgl/vgl_vector_3d.h"
26 #include "vgl/vgl_box_3d.h"
27 #include <vgl/algo/vgl_rotation_3d.h>
28 #include "vnl/vnl_double_3.h"
29 #include "vnl/vnl_quaternion.h"
30 #ifdef _MSC_VER
31 #  include "vcl_msvc_warnings.h"
32 #endif
33 
34 #include "vul/vul_file.h"
35 #include "vul/vul_string.h"
36 #include "vgui/vgui_tableau_sptr.h"
37 
38 #ifdef WIN32
39  #define _LIB
40 #endif
41 #include <expatpp.h> // for accessing methods in parent class of bwm_io_config_parser
42 
43 bwm_site_mgr* bwm_site_mgr::instance_ = nullptr;
44 
instance()45 bwm_site_mgr* bwm_site_mgr::instance()
46 {
47   if (!instance_) {
48     instance_ = new bwm_site_mgr();
49   }
50   return bwm_site_mgr::instance_;
51 }
52 
bwm_site_mgr()53 bwm_site_mgr::bwm_site_mgr(): site_name_(""), site_dir_(""), pyr_exe_(""),
54                               camera_path_(""), video_path_("")
55 {
56   tk_name_ = vgui::toolkit_name();
57 #ifdef HAS_MFC
58   site_create_process_ = new bwm_site_process();
59 #endif
60   object_types_.resize(OBJ_UNDEF);
61   object_types_[MESH_FEATURE] = BWM_MESH_FEATURE_STR;
62   object_types_[MESH_IMAGE_PROCESSING] = BWM_MESH_IMAGE_PROCESSING_STR;
63   object_types_[MESH_TERRAIN] = BWM_MESH_TERRAIN_STR;
64   object_types_[VSOL] = BWM_OBJ_VSOL_STR;
65 }
66 
~bwm_site_mgr()67 bwm_site_mgr::~bwm_site_mgr()
68 {
69 #ifdef HAS_MFC
70   delete site_create_process_;
71 #endif
72 }
73 
init_site()74 void bwm_site_mgr::init_site()
75 {
76   if(tk_name_ != "mfc"){
77     std::cout << tk_name_ << " lacks functionality to create" << std::endl;
78     return;
79   }
80   // delete the active tableaux
81   for (unsigned i=0; i<active_tableaus_.size(); i++)
82     delete active_tableaus_[i];
83   active_tableaus_.clear();
84 
85   // delete the inactive tableaux
86   for (unsigned i=0; i<inactive_tableaus_.size(); i++)
87     delete inactive_tableaus_[i];
88   inactive_tableaus_.clear();
89 
90   // clear the objects
91   site_objs_.clear();
92 #ifdef HAS_MFC
93   if (site_create_process_) {
94     delete site_create_process_;
95     this->site_create_process_ = new bwm_site_process();
96   }
97 #endif
98   site_name_="";
99   site_dir_="";
100   pyr_exe_="";
101 
102   bwm_observer_mgr::instance()->clear();
103   bwm_world::instance()->clear();
104 
105   timer_.mark();
106 }
107 
create_site_dialog(vgui_dialog_extensions & site_dialog,std::string & site_name,std::string & site_dir,std::string & pyr_exe_dir,std::vector<std::string> & files,bool * pyr_v,bool * act_v,std::vector<std::string> & pyr_levels,std::vector<std::string> & objs,int * choices,double & lat,double & lon,double & elev)108 void bwm_site_mgr::create_site_dialog(vgui_dialog_extensions &site_dialog,
109                                       std::string &site_name,
110                                       std::string &site_dir,
111                                       std::string &pyr_exe_dir,
112                                       std::vector<std::string> &files,
113                                       bool* pyr_v, bool* act_v,
114                                       std::vector<std::string> &pyr_levels,
115                                       std::vector<std::string> &objs,
116                                       int* choices,
117                                       double &lat, double &lon, double &elev)
118 {
119   std::string ext;
120   site_dialog.field("SITE NAME:", site_name);
121   site_dialog.line_break();
122   site_dialog.dir("DIRECTORY:", ext, site_dir);
123   site_dialog.line_break();
124   site_dialog.file("Pyramid exe path:", ext, pyr_exe_dir);
125   site_dialog.line_break();
126   //site_dialog.line_break();
127   site_dialog.set_modal(true);
128 
129   // add a bunch of images
130   site_dialog.message("Please Choose the Images for this site:");
131   site_dialog.line_break();
132   for (unsigned i=0; i<files.size(); i++) {
133     site_dialog.file("Image Path:", ext, files[i]);
134     site_dialog.checkbox("Do Pyramid?", pyr_v[i]);
135     site_dialog.field("Levels:", pyr_levels[i]);
136     site_dialog.checkbox("Is Active?", act_v[i]);
137     site_dialog.line_break();
138   }
139 
140   site_dialog.message("Please Choose the objects to add to the site:");
141   site_dialog.line_break();
142 
143   std::vector<std::string> obj_types(4);
144   for (unsigned i=0; i<objs.size(); i++) {
145     site_dialog.file("Enter input object:", ext, objs[i]);
146     site_dialog.choice("Type:", object_types_, choices[i]);
147     site_dialog.line_break();
148   }
149 
150   //site_dialog.line_break();
151   site_dialog.message("Enter the LVCS origin for this site:");
152   site_dialog.line_break();
153   site_dialog.field("Lat:", lat);
154   site_dialog.field("Lon:", lon);
155   site_dialog.field("Elev:", elev);
156   site_dialog.line_break();
157   site_dialog.set_ok_button("CREATE");
158 }
159 
160 
161 //: create a dialog box to create site to add images, objects, etc..
create_site()162 void bwm_site_mgr::create_site()
163 {
164   if(tk_name_ != "mfc"){
165     std::cout << tk_name_ << " lacks functionality to create a site" << std::endl;
166     return;
167   }
168   vgui_dialog_extensions site_dialog("CrossCut Site Creation");
169 
170   std::string site_name, site_dir, pyr_exe_path;
171 
172   int num_images = 3;
173   std::vector<std::string> files(num_images);
174   bool pyr[3] = {false, false, false};
175   bool act[3] = {true, true, true};
176   std::vector<std::string> levels(num_images, "7");
177 
178   int num_objs = 3;
179   std::vector<std::string> objs(num_objs);
180   int choices[3] = {0, 0, 0};
181   double lat=0.0, lon=0.0, elev=0.0;
182 
183   create_site_dialog(site_dialog, site_name, site_dir, pyr_exe_path, files, pyr,
184                      act, levels, objs, choices, lat, lon, elev);
185 
186   if (!site_dialog.ask()) {
187     return;
188   }
189   else
190   {
191     // collect the parameters
192     std::cout << "name:" << site_name << '\n'
193              << "dir:" << site_dir << std::endl;
194 
195     // make sure site name is filled
196     while (site_name.size() == 0) {
197       vgui_dialog error ("Error");
198       error.message ("Please enter a valid SITE NAME!            " );
199       error.ask();
200       if (! site_dialog.ask())
201         return;
202     }
203 
204     // make sure site directory is filled and valid
205     while ((site_dir.size() == 0) || !vul_file::is_directory(site_dir)) {
206       vgui_dialog error ("Error");
207       error.message ("Please enter a valid SITE DIRECTORY!            " );
208       error.ask();
209       if (! site_dialog.ask())
210         return;
211     }
212 
213     // check if the levels are numbers
214     bool not_int = true;
215     while (not_int) {
216       not_int = false;
217       for (unsigned i=0; i<levels.size(); i++) {
218         int l = vul_string_atoi(levels[i].c_str());
219         if (l == 0) {
220           not_int = true;
221           break;
222         }
223       }
224       if (not_int) {
225         vgui_dialog error ("Error");
226         error.message ("Please enter an integer level value!            " );
227         error.ask();
228         if (! site_dialog.ask())
229           return;
230       }
231       else {
232         not_int = false;
233       }
234     }
235   }
236 
237   std::vector<bool> pyramid;
238   std::vector<bool> active;
239   for (unsigned j=0; j<files.size(); j++) {
240     pyramid.push_back(pyr[j]);
241     active.push_back(act[j]);
242   }
243 
244   std::vector<std::pair<std::string, std::string> > objects;
245   for (unsigned obj=0; obj<objs.size(); obj++) {
246     std::pair<std::string, std::string> pair(objs[obj], object_types_[choices[obj]]);
247     objects.push_back(pair);
248   }
249 
250   bwm_site_sptr site = new bwm_site(site_name, site_dir, files, pyramid, active,
251                                     levels, objects, new vsol_point_3d(lat, lon, elev));
252 
253   // temporarily setting the exe path, will find a better solution later - Gamze
254   site->pyr_exe_path_ = pyr_exe_path;
255 #ifdef HAS_MFC
256   site_create_process_->set_site(site);
257   site_create_process_->StartBackgroundTask();
258 #else
259   vgui_dialog error ("Error");
260   error.message ("Site is not created! MFC (Windows platforms) is needed for this task!" );
261   error.ask();
262   if (! site_dialog.ask())
263     return;
264   std::cout << "Site is not created MFC (Windows) is needed for this task!" << std::endl;
265 #endif
266 }
267 
268 //: create a dialog box to create site to add images, objects, etc..
edit_site()269 void bwm_site_mgr::edit_site()
270 {
271   if(tk_name_ != "mfc"){
272     std::cout << tk_name_ << " lacks functionality to edit" << std::endl;
273     return;
274   }
275   bwm_io_config_parser* parser = nullptr;
276   parser = parse_config();
277   if (parser == nullptr) {
278     std::cerr << "Site File is not a valid XML site!\n";
279     return;
280   }
281 
282   vgui_dialog_extensions site_edit_dialog("Edit World Model Site");
283   bwm_site_sptr site = parser->site();
284 
285   // new creation vars
286   int num_images = 3;
287   std::vector<std::string> files(num_images);
288   bool pyr[3] = {false, false, false};
289   bool act[3] = {true, true, true};
290   std::vector<std::string> levels(num_images, "7");
291 
292   int num_objs = 3;
293   std::vector<std::string> objs(num_objs);
294   int choices[3] = {0, 0, 0};
295   double lat=0.0, lon=0.0, elev=0.0;
296 
297   // previously created obj vars
298   bool act_old[30];
299   bool tab_remove[30];
300   std::vector<std::string> cam;
301   std::string ext;
302 
303   site_edit_dialog.file("Pyramid Exe Path:", ext, site->pyr_exe_path_);
304   site_edit_dialog.line_break();
305 
306   // first place the existing tableaux on the dialog
307   std::vector<bwm_io_tab_config* > tableaus;
308   site->tableaus(tableaus);
309   cam.resize(tableaus.size());
310   if (tableaus.size() > 0)
311   {
312     site_edit_dialog.message("EXISTING IMAGES:");
313     site_edit_dialog.line_break();
314 
315     for (unsigned i=0; i<tableaus.size(); i++)
316     {
317       bwm_io_tab_config* t = tableaus[i];
318       if (t->type_name.compare(IMAGE_TABLEAU_TAG) == 0)
319       {
320         bwm_io_tab_config_img* img_tab = static_cast<bwm_io_tab_config_img* > (t);
321         bool active = img_tab->status;
322         std::string name = img_tab->name;
323         std::string path = img_tab->img_path;
324         site_edit_dialog.message((" -- "+path).c_str());
325         tab_remove[i] = false;
326         site_edit_dialog.checkbox("Remove", tab_remove[i]);
327         act_old[i] = active;
328         site_edit_dialog.checkbox("Active", act_old[i]);
329 #if 0
330         std::string ext = "*.RPG";
331         site_edit_dialog.file("Add Camera:", ext, cam[i]);
332 #endif // 0
333         site_edit_dialog.line_break();
334       }
335       else if (t->type_name.compare(CAMERA_TABLEAU_TAG) == 0)
336       {
337         bwm_io_tab_config_cam* cam_tab = static_cast<bwm_io_tab_config_cam* > (t);
338         bool active = cam_tab->status;
339         site_edit_dialog.message((" -- "+cam_tab->img_path).c_str());
340         tab_remove[i] = false;
341         site_edit_dialog.checkbox("Remove ", tab_remove[i]);
342         act_old[i] = active;
343         site_edit_dialog.checkbox("Active ", act_old[i]);
344         site_edit_dialog.line_break();
345       }
346     }
347   }
348 
349   // add a bunch of images
350   site_edit_dialog.message("ADD NEW:");
351   site_edit_dialog.line_break();
352   for (unsigned i=0; i<files.size(); i++) {
353     std::string ext;
354     site_edit_dialog.file("Image Path:", ext, files[i]);
355     site_edit_dialog.checkbox("Do Pyramid?", pyr[i]);
356     site_edit_dialog.field("Levels:", levels[i]);
357     site_edit_dialog.checkbox("Is Active?", act[i]);
358     site_edit_dialog.line_break();
359   }
360 
361   site_edit_dialog.line_break();
362 
363   // put the existing objects
364   std::vector<std::pair<std::string, std::string> > object_paths;
365   bool obj_remove[30];
366   parser->site()->objects(object_paths);
367 
368   if (object_paths.size() > 0) {
369     site_edit_dialog.message("EXISTING OBJECTS:");
370     site_edit_dialog.line_break();
371 
372     for (unsigned i=0; i<object_paths.size(); i++) {
373       site_edit_dialog.message((" -- " + object_paths[i].first).c_str());
374       std::string object_type = object_paths[i].second;
375       site_edit_dialog.message(("Type: " + object_type).c_str());
376       obj_remove[i] = false;
377       site_edit_dialog.checkbox("Remove ", obj_remove[i]);
378       site_edit_dialog.line_break();
379     }
380   }
381   // create new objects
382   site_edit_dialog.message("ADD OBJECTS:");
383   site_edit_dialog.line_break();
384   for (unsigned i=0; i<objs.size(); i++) {
385     site_edit_dialog.file("Object:", ext, objs[i]);
386     site_edit_dialog.choice("Type:", object_types_, choices[i]);
387     site_edit_dialog.line_break();
388   }
389 
390   // lvcs
391   site_edit_dialog.line_break();
392   site_edit_dialog.message("LVCS origin for this site:");
393   site_edit_dialog.line_break();
394 
395   lat = lon = elev = 0.0;
396   if (parser->site()->lvcs_) {
397     lat = parser->site()->lvcs_->x();
398     lon = parser->site()->lvcs_->y();
399     elev = parser->site()->lvcs_->z();
400   }
401   site_edit_dialog.field("Lat:", lat);
402   site_edit_dialog.field("Lon:", lon);
403   site_edit_dialog.field("Elev:", elev);
404 
405   site_edit_dialog.line_break();
406   site_edit_dialog.set_ok_button("EDIT");
407   if (!site_edit_dialog.ask()) {
408     return;
409   }
410   else
411   {
412     // check if the level values are integer
413 
414     // create a removal list for the tableaux that are marked for removal
415     std::vector<unsigned> removal;
416     for (unsigned t=0; t<tableaus.size(); t++) {
417       tableaus[t]->status = act_old[t];
418       if (tab_remove[t])
419         removal.push_back(t);
420     }
421     site->remove_ = removal;
422 
423     // delete objects that are marked for removal
424     std::vector<std::pair<std::string, std::string> > undeleted_objs;
425     bool deleted = false;
426     for (unsigned i=0; i<object_paths.size(); i++) {
427       if (!obj_remove[i]) {
428         undeleted_objs.push_back(object_paths[i]);
429       }
430       else
431         deleted = true;
432     }
433     if (deleted) {
434       site->objects_.clear();
435       site->objects_ = undeleted_objs;
436     }
437 
438     // create an updated site
439     std::vector<bool> pyramid;
440     std::vector<bool> active;
441     for (unsigned j=0; j<files.size(); j++) {
442       pyramid.push_back(pyr[j]);
443       active.push_back(act[j]);
444     }
445 
446     std::vector<std::pair<std::string, std::string> > objects;
447     for (unsigned obj=0; obj<objs.size(); obj++) {
448       std::pair<std::string, std::string> pair(objs[obj], object_types_[choices[obj]]);
449       objects.push_back(pair);
450     }
451 #if 0
452     std::vector<std::vector<std::pair<std::string, vsol_point_2d> > > corr = parser->correspondences();
453     for (unsigned i=0; i<corr.size(); i++) {
454       bwm_corr_sptr c = new bwm_corr();
455       if (parser->corresp_mode().compare("IMAGE_TO_IMAGE") == 0)
456         c->set_mode(true);
457       else {
458         c->set_mode(false);
459         c->set_world_point(parser->corresp_world_pts()[i]);
460       }
461     }
462     site->corresp_mode = parser->corresp_mode();
463     site->corr_type_ = parser->corresp_type();
464     // std::vector<vsol_point_3d> corresp_world_pts() {return corresp_world_pts_; }
465 #endif // 0
466 
467     site->add(files, pyramid, active, levels, objects, new vsol_point_3d(lat, lon, elev));
468 #ifdef HAS_MFC
469     site_create_process_->set_site(site);
470     site_create_process_->StartBackgroundTask();
471 #endif
472   }
473 }
474 
475 
load_site()476 void bwm_site_mgr::load_site()
477 {
478   bwm_io_config_parser* parser = parse_config();
479 
480   if (parser)
481   {
482     init_site();
483     bwm_site_sptr site = parser->site();
484     std::vector<bwm_io_tab_config* > tableaus;
485     site->tableaus(tableaus);
486 
487     site_name_ = site->name_;
488     site_dir_ = site->path_;
489     pyr_exe_ = site->pyr_exe_path_;
490 
491     // get the lvcs
492     vsol_point_3d_sptr lvcs = site->lvcs_;
493     // if LVCS is not set, do not use it
494     if (!lvcs||*lvcs == vsol_point_3d(0, 0, 0))
495       lvcs = nullptr;
496     else {
497       double lat = lvcs->x();
498       double lon = lvcs->y();
499       double elev = lvcs->z();
500       bwm_world::instance()->set_lvcs(lat, lon, elev);
501     }
502 
503     // create the active tableaux
504     for (unsigned i=0; i<tableaus.size(); i++)
505     {
506       bwm_io_tab_config* t = tableaus[i];
507       if (t->status) {
508         // create an active tableau
509         bwm_tableau_img* tab = tableau_factory_.create_tableau(t);
510         bwm_tableau_mgr::instance()->add_tableau(tab, t->name);
511         active_tableaus_.push_back(t->clone());
512       }
513       else // inactive tableau
514         inactive_tableaus_.push_back(t->clone());
515     }
516 
517     // create the correspondences
518     std::vector<std::vector<std::pair<std::string, vsol_point_2d> > > corresp;
519     corresp = site->corresp_;
520     if (corresp.size() > 0) {
521       std::string mode = site->corr_mode_;
522       std::string type = site->corr_type_;
523 
524       if (type.compare("MULTIPLE") == 0)
525         bwm_observer_mgr::instance()->set_n_corrs(bwm_observer_mgr::MULTIPLE_CORRS);
526       else if (type.compare("SINGLE") == 0)
527         bwm_observer_mgr::instance()->set_n_corrs(bwm_observer_mgr::SINGLE_PT_CORR);
528       else
529         std::cerr << "ERROR: Undefined Correspondence type=" << type << '\n';
530 
531       if (mode == "WORLD_TO_IMAGE") {
532         if (corresp.size() > 0) {
533           if (site->corresp_world_pts_.size() > 0)
534             bwm_world::instance()->set_world_pt(site->corresp_world_pts_[0].get_p());
535           else
536             std::cerr << "There is something wrong, the more is W-to-I but there is no world point\n";
537         }
538         bwm_observer_mgr::instance()->set_corr_mode(bwm_observer_mgr::WORLD_TO_IMAGE);
539       }
540       else if (mode == "IMAGE_TO_IMAGE") {
541         bwm_observer_mgr::instance()->set_corr_mode(bwm_observer_mgr::IMAGE_TO_IMAGE);
542       }
543 
544       for (unsigned i=0; i<corresp.size(); i++)
545       {
546         bwm_corr_sptr corr = new bwm_corr();
547         std::vector<std::pair<std::string, vsol_point_2d> > elm = corresp[i];
548 
549         if (mode == "WORLD_TO_IMAGE") {
550           corr->set_mode(false);
551           corr->set_world_pt(site->corresp_world_pts_[i].get_p());
552           //sets the same pt each time FIXME -JLM
553           //bwm_world::instance()->set_world_pt(corr->world_pt());
554         }
555         else if (mode == "IMAGE_TO_IMAGE") {
556           corr->set_mode(true);
557         }
558 
559         std::string tab_name;
560         double X, Y;
561         for (unsigned j=0; j<elm.size(); j++) {
562           tab_name = elm[j].first;
563           X = elm[j].second.x();
564           Y = elm[j].second.y();
565           bwm_tableau_mgr::instance()->add_corresp(tab_name, corr, X, Y);
566 #if 0 // commented out
567           vgui_tableau_sptr tab = this->find_tableau(tab_name);
568           if (tab) {
569             if ((tab->type_name().compare("bwm_tableau_proj_cam") == 0) ||
570                 (tab->type_name().compare("bwm_tableau_rat_cam") == 0)) {
571               bwm_tableau_cam* tab_cam = static_cast<bwm_tableau_cam*> (tab.as_pointer());
572               bwm_observer_cam* obs = tab_cam->observer();
573               if (obs) {
574                 corr->set_match(obs, X, Y);
575                 obs->add_cross(X, Y, 3);
576               }
577             }
578           }
579 #endif // 0
580         }
581         bwm_observer_mgr::instance()->set_corr(corr);
582       }
583     }
584     // create the objects
585     std::vector<std::pair<std::string, std::string> > objs;
586     site->objects(objs);
587     for (unsigned i=0; i<objs.size(); i++)
588     {
589       std::string path = objs[i].first;
590       std::string type = objs[i].second;
591       if (path.size() > 0)
592       {
593         if (!vul_file::exists(path))
594           std::cerr << "ERROR: The object file \"" << path << "\" could not be found!\n";
595         else {
596           if (type.compare(object_types_[VSOL]) == 0) {
597             // will be implemented later!!!
598           }
599           else {
600             // comes here if it is a mesh
601             bwm_observable_mesh_sptr mesh = new bwm_observable_mesh();
602             mesh->load_from(path);
603             if (mesh) {
604               bwm_observable_mesh_sptr obj = new bwm_observable_mesh();
605               obj->set_site(site_name_);
606               bwm_observer_mgr::instance()->attach(obj);
607               if (type.compare(object_types_[MESH_FEATURE]) == 0)
608                 obj->set_mesh_type(bwm_observable_mesh::BWM_MESH_FEATURE);
609               else if (type.compare(object_types_[MESH_IMAGE_PROCESSING]) == 0)
610                 obj->set_mesh_type(bwm_observable_mesh::BWM_MESH_IMAGE_PROCESSING);
611               else if (type.compare(object_types_[MESH_TERRAIN]) == 0)
612                 obj->set_mesh_type(bwm_observable_mesh::BWM_MESH_TERRAIN );
613               obj->set_object(mesh->get_object()->clone());
614               bwm_world::instance()->add(obj);
615             }
616           }
617         }
618       }
619     }
620     delete parser;
621     bwm_tableau_mgr::instance()->redraw();
622   }
623 }
624 
625 //: saves the site to an XML file
save_site()626 void bwm_site_mgr::save_site()
627 {
628   bwm_site_sptr site = new bwm_site();
629 
630   if ((this->site_name_.size() > 0) &&
631       (this->site_dir_.size() > 0) &&
632       (vul_file::exists(this->site_dir_)))
633   {
634     vgui_dialog_extensions d("Saving the Site");
635     d.message(("Saving the site " + site_name_).c_str());
636     d.message(("under: " + site_dir_).c_str());
637     d.line_break();
638     if (!d.ask()) {
639       return;
640     }
641     site->name_ = this->site_name_;
642     site->path_ = this->site_dir_;
643     site->pyr_exe_path_ = this->pyr_exe_;
644   }
645   else
646   {
647     // ask the path for saving the site
648     std::string site_name, site_dir, pyr_exe, ext;
649     vgui_dialog_extensions d("Save the Site!");
650     d.field("Site name:", site_name);
651     d.line_break();
652     d.dir("Site dir:", ext, site_dir);
653     d.line_break();
654     //d.file("Pyramid exe path:" , ext, pyr_exe);
655     //d.line_break();
656     d.line_break();
657     if (!d.ask())
658       return;
659 
660     if (!vul_file::is_directory(site_dir)) {
661       std::cerr << "Please enter a directory for the site\n";
662       return;
663     }
664 
665     site->name_ = this->site_name_ = site_name;
666     site->path_ = this->site_dir_ = site_dir;
667     site->pyr_exe_path_ = this->pyr_exe_;
668   }
669 
670   long time = timer_.real();
671   std::stringstream strm;
672   strm << std::fixed << time;
673   std::string str(strm.str());
674   std::string site_path = site_dir_ + "\\" + site_name_ + "_v" + str + ".xml";
675   std::ofstream s(site_path.data());
676 
677   // get the tableaux
678   for (unsigned i=0; i<active_tableaus_.size(); i++) {
679     if (active_tableaus_[i]->type_name.compare("CameraTableau") == 0) {
680       std::string new_cam_path = bwm_tableau_mgr::instance()->save_camera(active_tableaus_[i]->name);
681       bwm_io_tab_config_cam* t  = static_cast<bwm_io_tab_config_cam*> (active_tableaus_[i]);
682       t->cam_path = new_cam_path;
683     }
684     site->tableaus_.push_back(active_tableaus_[i]->clone());
685   }
686 
687   // add the inactive tableaux
688   for (unsigned i=0; i<inactive_tableaus_.size(); i++) {
689     site->tableaus_.push_back(inactive_tableaus_[i]->clone());
690   }
691 
692   // add the correspondences if any
693   bwm_observer_mgr* obs_mgr = bwm_observer_mgr::instance();
694   if (obs_mgr->corr_mode() == bwm_observer_mgr::IMAGE_TO_IMAGE)
695     site->corr_mode_ = "IMAGE_TO_IMAGE";
696   else {
697     site->corr_mode_ = "WORLD_TO_IMAGE";
698   }
699 
700   if (obs_mgr->n_corrs() == bwm_observer_mgr::MULTIPLE_CORRS)
701     site->corr_type_ = "MULTIPLE";
702   else
703     site->corr_type_ = "SINGLE";
704 
705   std::vector<bwm_corr_sptr> c_list = bwm_observer_mgr::instance()->correspondences();
706   for (unsigned i=0; i<c_list.size(); i++) {
707     site->corresp_.push_back(c_list[i]->match_list());
708     site->corresp_world_pts_.push_back(c_list[i]->world_pt());
709   }
710 
711   // add the objects
712   // ask one camera tableau to save its objects
713   std::vector<bwm_observable_sptr> objs = bwm_world::instance()->objects();
714   std::string obj_path = site_dir_ + "\\" + site_name_ + "_objects\\";
715   vul_file::make_directory(obj_path);
716   for (unsigned i=0; i<objs.size(); i++) {
717     if (objs[i]) {
718       std::stringstream strm;
719       strm << std::fixed << i;
720       std::string str(strm.str());
721       std::string fname = obj_path + "mesh_" + str + ".ply";
722       objs[i]->save(fname.c_str());
723       site->objects_.push_back(std::pair<std::string, std::string>(fname, object_types_[MESH_FEATURE]));
724     }
725   }
726 
727   site->x_write(s);
728 }
729 
load_video_site()730 void bwm_site_mgr::load_video_site()
731 {
732   std::string site_path = bwm_utils::select_file();
733   if (!site_path.size())
734   {
735     std::cerr << "In bwm_site_mgr::load_video_site() - no site path specified\n";
736     return;
737   }
738 
739   bwm_video_site_io cio;
740   if (!cio.open(site_path))
741   {
742     std::cerr << "In bwm_site_mgr::load_video_site() - load failed in XML parse\n";
743     return;
744   }
745   site_name_ = cio.name();
746   std::string frame_glob = cio.video_path();
747   std::string camera_glob = cio.camera_path();
748   bwm_io_tab_config_video* v = new bwm_io_tab_config_video(site_name_, true, frame_glob, camera_glob);
749   active_tableaus_.push_back(v);
750   bwm_tableau_img* t = tableau_factory_.create_tableau(v);
751   if (!t)
752     return;
753   bwm_tableau_video* vt = static_cast<bwm_tableau_video*> (t);
754   vt->set_corrs(cio.corrs());
755   bwm_tableau_mgr::instance()->add_tableau(t, site_name_);
756 
757   site_dir_ = cio.site_directory();
758   video_path_ = cio.video_path();
759   camera_path_ = cio.camera_path();
760   std::vector<std::string> obj_types = cio.object_types();
761   std::vector<std::string> obj_paths = cio.object_paths();
762   unsigned nobj = obj_types.size();
763   if (!nobj) return;
764   bwm_tableau_mgr::instance()->set_draw_mode_face();
765   for (unsigned i = 0; i<nobj; ++i) {
766     if (obj_types[i]!="mesh_feature") continue;
767     bwm_observable_mesh_sptr mesh = new bwm_observable_mesh();
768     mesh->load_from(obj_paths[i]);
769     if (mesh) {
770       bwm_observable_mesh_sptr obj = new bwm_observable_mesh();
771       bwm_observer_mgr::instance()->attach(obj);
772       obj->set_path(obj_paths[i]);
773       obj->set_mesh_type(bwm_observable_mesh::BWM_MESH_FEATURE);
774       obj->set_object(mesh->get_object()->clone());
775       bwm_world::instance()->add(obj);
776     }
777   }
778 }
779 
save_video_site()780 void bwm_site_mgr::save_video_site()
781 {
782   //for now - only support one video observer
783 
784   //also for now if the site was initialized with just a directory containing
785   //mesh objects the saved site file will have a null directory path
786   //but with the individual object paths included inside the objects scope.
787   //the effect is the same it is just that the file is somewhat more verbose
788   // it is not clear where an object directory path should go bwm_world?
789 
790   bool found = false;
791   std::vector<bwm_observer_cam*> obsvs =
792     bwm_observer_mgr::instance()->observers_cam();
793   bwm_observer_video* obv = nullptr;
794 
795   for (std::vector<bwm_observer_cam*>::iterator oit = obsvs.begin();
796        oit != obsvs.end()&&!found; ++oit)
797     if ((*oit)->type_name()=="bwm_observer_video")
798     {
799       obv = static_cast<bwm_observer_video*>(*oit);
800       found =true;
801     }
802 
803   if (!found)
804   {
805     std::cerr << "In bwm_site_mgr::save_video_site() - no observer of type video\n";
806     return;
807   }
808 
809   bwm_video_site_io vio;
810 
811   if ((this->site_name_.size() > 0) &&
812       (this->site_dir_.size() > 0) &&
813       (vul_file::exists(this->site_dir_)))
814   {
815     vgui_dialog d("Saving the Video Site");
816     d.message(("Saving the site " + site_name_).c_str());
817     d.message(("under: " + site_dir_).c_str());
818     d.line_break();
819     if (!d.ask()) {
820       return;
821     }
822     vio.set_name(this->site_name_);
823     vio.set_site_directory(this->site_dir_);
824     vio.set_video_path(this->video_path_);
825     vio.set_camera_path(this->camera_path_);
826   }
827   else
828   {
829     // ask the path for saving the site
830     std::string ext = "png";
831     vgui_dialog_extensions d("Save the Video Site!"); //Still will NOT work in Linux!
832     d.field("Video Site Name:", this->site_name_);
833     d.line_break();
834     d.dir("Video Site Dir:", ext, this->site_dir_);
835     d.line_break();
836     d.line_break();
837     if (!d.ask())
838       return;
839     if (!vul_file::is_directory(this->site_dir_)) {
840       std::cerr << "Please enter a directory for the video site\n";
841       return;
842     }
843 
844     vio.set_name(this->site_name_);
845     vio.set_site_directory(this->site_dir_);
846     vio.set_video_path(obv->image_path());
847     vio.set_camera_path(obv->camera_path());
848   }
849 
850   std::vector<bwm_observable_sptr> objs = bwm_world::instance()->objects();
851   std::vector<std::string> obj_types;
852   std::vector<std::string> obj_paths;
853   std::string obj_dir = site_dir_ + "/" + site_name_ + "_objects/";
854   vul_file::make_directory(obj_dir);
855   unsigned iobj = 0;
856   for (std::vector<bwm_observable_sptr>::iterator oit = objs.begin();
857        oit != objs.end(); ++oit, ++iobj)
858     if ((*oit)->type_name()=="bwm_observable_mesh") {
859       std::stringstream strm;
860       strm << std::fixed << iobj;
861       std::string str(strm.str());
862       std::string path = obj_dir + "mesh_" + str + ".ply";
863       obj_types.push_back("mesh_feature");
864       obj_paths.push_back(path);
865       (*oit)->save(path.c_str());
866     }
867     else
868       std::cout << "Can't save object of type " << (*oit)->type_name() << '\n';
869   vio.set_object_types(obj_types);
870   vio.set_object_paths(obj_paths);
871 
872   std::vector<bwm_video_corr_sptr> corrs = obv->corrs();
873   vio.set_corrs(corrs);
874   long time = timer_.real();
875   std::stringstream strm;
876   strm << std::fixed << time;
877   std::string ver(strm.str());
878   std::string site_path = site_dir_ + "/" + site_name_ + "_v" + ver + ".xml";
879   vio.x_write(site_path);
880 }
881 
load_img_tableau()882 void bwm_site_mgr::load_img_tableau()
883 {
884   vgui_dialog/*_extensions*/ params ("Image Tableau");
885   std::string ext, name, img_file, empty="";
886   params.field("Tableau Name", name);
887   // params.line_break();
888   params.file("Image...", ext, img_file);
889   //params.line_break();
890   params.set_modal(true);
891   if (!params.ask())
892     return;
893 
894   if (img_file == "") {
895     bwm_utils::show_error("Please specify an image file (prefix).");
896     return;
897   }
898 
899   bwm_io_tab_config_img img(name, true, img_file);
900   bwm_tableau_img* tab = tableau_factory_.create_tableau(&img);
901   bwm_tableau_mgr::instance()->add_tableau(tab, name);
902   active_tableaus_.push_back(img.clone());
903 
904   tab->post_redraw();
905 }
906 
load_video_tableau()907 void bwm_site_mgr::load_video_tableau()
908 {
909   static std::string video_path = "";
910   static std::string camera_glob = "";
911   std::string name = "none";
912   std::string ext = "";
913   if(tk_name_ == "mfc"){
914     vgui_dialog_extensions params ("Video Tableau");
915     params.field("Tableau Name", name);
916     params.line_break();
917     params.dir("Frame Glob or File", ext, video_path);
918     params.line_break();
919     params.dir("Camera Glob", ext, camera_glob);
920     params.line_break();
921     params.set_modal(true);
922     if (!params.ask())
923       return;
924   }else{
925     vgui_dialog params ("Video Tableau");
926     params.field("Tableau Name", name);
927     params.line_break();
928     params.file("Frame Glob or File", ext, video_path);
929     params.line_break();
930     params.file("Camera Glob", ext, camera_glob);
931     params.line_break();
932     params.set_modal(true);
933     if (!params.ask())
934       return;
935   }
936   if (video_path == "") {
937    bwm_utils::show_error("Please specify a video path");
938    return;
939   }
940 
941   bwm_io_tab_config_video* video = new bwm_io_tab_config_video(name, true, video_path, camera_glob);
942   active_tableaus_.push_back(video);
943   bwm_tableau_img*  t = tableau_factory_.create_tableau(video);
944   bwm_tableau_mgr::instance()->add_tableau(t, name);
945 }
946 
load_cam_tableau()947 void bwm_site_mgr::load_cam_tableau()
948 {
949 
950   std::string ext, name, img_file, cam_file, empty="";
951   //std::string ext, name, cam_file, empty="";
952   //static std::string img_file = "";
953   static int camera_type = 0;
954   std::vector<std::string> types;
955   types.push_back("generic");
956   types.push_back("rational");
957   types.push_back("projective");
958   types.push_back("perspective");
959   types.push_back("identity");
960   if(tk_name_ == "mfc"){
961   vgui_dialog_extensions params ("Camera Tableau");
962   params.field("Tableau Name", name);
963   params.line_break();
964   params.file("Image...", ext, img_file);
965   params.line_break();
966   params.choice("Camera Type",types, camera_type);
967   params.line_break();
968   params.file("Camera...", ext, cam_file);
969   params.line_break();
970   if (!params.ask())
971     return;
972   }else{
973     vgui_dialog params ("Camera Tableau");
974     params.field("Tableau Name", name);
975     params.line_break();
976     params.file("Image...", ext, img_file);
977     params.line_break();
978     params.choice("Camera Type",types, camera_type);
979     params.line_break();
980     params.file("Camera...", ext, cam_file);
981     params.line_break();
982     if (!params.ask())
983       return;
984   }
985   if ((img_file == "") || (cam_file == "" && camera_type != 4)) {  // for identity camera type, cam_file can be empty ?
986     vgui_dialog error ("Error");
987     error.message ("Please specify an input file (prefix)." );
988     error.ask();
989     return;
990   }
991 
992   std::string cam_str;
993   switch (camera_type)
994   {
995    case 0:
996     cam_str = "generic";
997     break;
998    case 1:
999     cam_str = "rational";
1000     break;
1001    case 2:
1002     cam_str = "projective";
1003     break;
1004    case 3:
1005     cam_str = "perspective";
1006     break;
1007    case 4:
1008     cam_str = "identity";
1009     break;
1010    case 5:
1011     cam_str = "geo";
1012     break;
1013    default:
1014     cam_str = "unknown";
1015   }
1016 
1017   bwm_io_tab_config_cam* cam = new bwm_io_tab_config_cam(name, true, img_file, cam_file, cam_str);
1018   active_tableaus_.push_back(cam);
1019   bwm_tableau_img*  t = tableau_factory_.create_tableau(cam);
1020   bwm_tableau_mgr::instance()->add_tableau(t, name);
1021 }
1022 // a tableau for specifying the image locations of 3-d fiducial data
load_fiducial_tableau()1023 void bwm_site_mgr::load_fiducial_tableau()
1024 {
1025   std::string ext, name, img_file, fid_file, empty="";
1026   if (tk_name_ == "mfc") {
1027     vgui_dialog_extensions params("Fiducial Tableau (fid xor img )");
1028     params.field("Tableau Name", name);
1029     params.line_break();
1030     params.file("Image...", ext, img_file);
1031     params.line_break();
1032     params.file("Fiducials...", ext, fid_file);
1033     params.line_break();
1034     if (!params.ask())
1035       return;
1036   }else {
1037     vgui_dialog params("Fiducial Tableau (fid xor img )");
1038     params.field("Tableau Name", name);
1039     params.line_break();
1040     params.file("Image...", ext, img_file);
1041     params.line_break();
1042     params.file("Fiducials...", ext, fid_file);
1043     params.line_break();
1044     if (!params.ask())
1045       return;
1046   }
1047     // the fid file contains the data to populate a fiducial tableau (like a site file)
1048     // initially just load a composite fiducial placement image and save the resulting
1049     // fiducial correspondences to a fid file path defined by the fiducial tableau popup
1050     // the state of the tableau is restored by loading the fid file
1051     if ((img_file == "" && fid_file == "")||(img_file != "" && fid_file != "")) {
1052       vgui_dialog error ("Error");
1053       error.message ("only one of img_file and fid file can be entered");
1054       error.ask();
1055       return;
1056     }
1057 
1058     bwm_io_tab_config_fiducial* fid = new bwm_io_tab_config_fiducial(name, true, img_file, fid_file);
1059   active_tableaus_.push_back(fid);
1060   bwm_tableau_fiducial*  t = dynamic_cast<bwm_tableau_fiducial*>(tableau_factory_.create_tableau(fid));
1061   if (!t) {
1062       std::cerr << "factory can't create the fiducial tableau" << std::endl;
1063       return;
1064   }
1065   bwm_tableau_mgr::instance()->add_tableau(t, name);
1066 }
1067 
parse_config(std::string const & path)1068 bwm_io_config_parser* bwm_site_mgr::parse_config(std::string const& path)
1069 {
1070   std::string fname = path;
1071   if(fname == "")
1072    fname = bwm_utils::select_file();
1073 
1074   if (fname.size() == 0)
1075     return nullptr;
1076 
1077   bwm_io_config_parser* parser = new bwm_io_config_parser();
1078   std::FILE* xmlFile = std::fopen(fname.c_str(), "r");
1079   if (!xmlFile) {
1080     std::cerr << fname.c_str() << " error on opening\n";
1081     delete parser;
1082     return nullptr;
1083   }
1084   if (!parser->parseFile(xmlFile)) {
1085     std::cerr << XML_ErrorString(parser->XML_GetErrorCode()) << " at line "
1086              << parser->XML_GetCurrentLineNumber() << '\n';
1087 
1088     delete parser;
1089     return nullptr;
1090   }
1091   std::cout << "finished!" << std::endl;
1092   return parser;
1093 }
site_parser(std::string const & path)1094 bwm_io_config_parser*   bwm_site_mgr::site_parser(std::string const& path){
1095   return this->parse_config(path);
1096 }
1097 
write_vrml_header(std::ofstream & str)1098 static void write_vrml_header(std::ofstream& str)
1099 {
1100   str << "#VRML V2.0 utf8\n"
1101       << "Background {\n"
1102       << "  skyColor [ 0 0 0 ]\n"
1103       << "  groundColor [ 0 0 0 ]\n"
1104       << "}\n";
1105 }
1106 
write_vrml_points(std::ofstream & str,std::vector<vgl_point_3d<double>> const & pts3d,double rad=2.0)1107 static void write_vrml_points(std::ofstream& str,
1108                               std::vector<vgl_point_3d<double> > const& pts3d, double rad=2.0)
1109 {
1110   int n = pts3d.size();
1111   for (int i =0; i<n; i++)
1112     str << "Transform {\n"
1113         << "translation " << pts3d[i].x() << ' ' << pts3d[i].y() << ' '
1114         << ' ' << pts3d[i].z() << '\n'
1115         << "children [\n"
1116         << "Shape {\n"
1117         << " appearance Appearance{\n"
1118         << "   material Material\n"
1119         << "    {\n"
1120         << "      diffuseColor " << 0 << ' ' << 1.0 << ' ' << 0.0 << '\n'
1121         << "      transparency " << 0.0 << '\n'
1122         << "    }\n"
1123         << "  }\n"
1124         << " geometry Sphere\n"
1125         <<   "{\n"
1126         << "  radius " << rad << '\n'
1127         <<  "   }\n"
1128         <<  "  }\n"
1129         <<  " ]\n"
1130         << "}\n";
1131 }
1132 
1133 static void
write_vrml_cameras(std::ofstream & str,std::vector<vpgl_perspective_camera<double>> const & cams,double rad=2.0)1134 write_vrml_cameras(std::ofstream& str,
1135                    std::vector<vpgl_perspective_camera<double> > const& cams, double rad=2.0)
1136 {
1137   str << "#VRML V2.0 utf8\n"
1138       << "Background {\n"
1139       << "  skyColor [ 0 0 0 ]\n"
1140       << "  groundColor [ 0 0 0 ]\n"
1141       << "}\n";
1142   int n = cams.size();
1143   for (int i =0; i<n; i++) {
1144     vgl_point_3d<double> cent =  cams[i].get_camera_center();
1145     str << "Transform {\n"
1146         << "translation " << cent.x() << ' ' << cent.y() << ' '
1147         << ' ' << cent.z() << '\n'
1148         << "children [\n"
1149         << "Shape {\n"
1150         << " appearance Appearance{\n"
1151         << "   material Material\n"
1152         << "    {\n"
1153         << "      diffuseColor " << 1 << ' ' << 1.0 << ' ' << 0.0 << '\n'
1154         << "      transparency " << 0.0 << '\n'
1155         << "    }\n"
1156         << "  }\n"
1157         << " geometry Sphere\n"
1158         <<   "{\n"
1159         << "  radius " << rad << '\n'
1160         <<  "   }\n"
1161         <<  "  }\n"
1162         <<  " ]\n"
1163         << "}\n";
1164     vgl_vector_3d<double> r = cams[i].principal_axis();
1165     std::cout<<"principal axis :" <<r<<std::endl;
1166     vnl_double_3 yaxis(0.0, 1.0, 0.0), pvec(r.x(), r.y(), r.z());
1167     vgl_rotation_3d<double> rot(yaxis, pvec);
1168     vnl_quaternion<double> q = rot.as_quaternion();
1169 
1170     vnl_double_3 axis = q.axis();
1171     std::cout<<"quaternion "<<axis<< " angle "<<q.angle()<<"\n\n";
1172     double ang = q.angle();
1173     str <<  "Transform {\n"
1174         << " translation " << cent.x()+6*rad*r.x() << ' ' << cent.y()+6*rad*r.y()
1175         << ' ' << cent.z()+6*rad*r.z() << '\n'
1176         << " rotation " << axis[0] << ' ' << axis[1] << ' ' << axis[2] << ' ' <<  ang << '\n'
1177         << "children [\n"
1178         << " Shape {\n"
1179         << " appearance Appearance{\n"
1180         << "  material Material\n"
1181         << "   {\n"
1182         << "     diffuseColor 1 0 0\n"
1183         << "     transparency 0\n"
1184         << "    }\n"
1185         << "  }\n"
1186         << " geometry Cylinder\n"
1187         << "{\n"
1188         << " radius "<<rad/3<<'\n'
1189         << " height " << 12*rad << '\n'
1190         << " }\n"
1191         << " }\n"
1192         << "]\n"
1193         << "}\n";
1194   }
1195 }
1196 
1197 #ifdef DEBUG
1198 static void
write_vrml_box(std::ofstream & str,vgl_box_3d<double> box)1199 write_vrml_box(std::ofstream& str,vgl_box_3d<double> box)
1200 {
1201   str << "#VRML V2.0 utf8\n"
1202       << "Background {\n"
1203       << "  skyColor [ 0 0 0 ]\n"
1204       << "  groundColor [ 0 0 0 ]\n"
1205       << "}\n"
1206       << "Transform {\n"
1207       << "translation " << box.centroid_x() << ' ' << box.centroid_y() << ' '
1208       << ' ' << box.centroid_z() << '\n'
1209       << "children [\n"
1210       << "Shape {\n"
1211       << " appearance Appearance{\n"
1212       << "   material Material\n"
1213       << "    {\n"
1214       << "      diffuseColor " << 1 << ' ' << 1.0 << ' ' << 0.0 << '\n'
1215       << "      transparency " << 0.0 << '\n'
1216     //<< "\t\tfilled FALSE\n"
1217       << "    }\n"
1218       << "  }\n"
1219       << " geometry Box\n"
1220       <<   "{\n"
1221       << "  size " << box.width() <<' '<<box.depth()<<' '<<box.height()<< '\n'
1222       <<  "   }\n"
1223       <<  "  }\n"
1224       <<  " ]\n"
1225       << "}\n";
1226 }
1227 #endif
1228 
save_video_world_points_vrml_impl(std::ofstream & os)1229 static void save_video_world_points_vrml_impl(std::ofstream& os)
1230 {
1231   bool found = false;
1232   std::vector<bwm_observer_cam*> obsvs =
1233     bwm_observer_mgr::instance()->observers_cam();
1234   bwm_observer_video* obv = nullptr;
1235 
1236   for (std::vector<bwm_observer_cam*>::iterator oit = obsvs.begin();
1237        oit != obsvs.end()&&!found; ++oit)
1238     if ((*oit)->type_name()=="bwm_observer_video")
1239     {
1240       obv = static_cast<bwm_observer_video*>(*oit);
1241       found =true;
1242     }
1243 
1244   if (!found)
1245   {
1246     std::cerr << "In bwm_site_mgr::save_video_world_points_vrml() - no observer of type video\n";
1247     return;
1248   }
1249   std::vector<vgl_point_3d<double> > pts;
1250   std::vector<bwm_video_corr_sptr> corrs = obv->corrs();
1251   for (std::vector<bwm_video_corr_sptr>::iterator cit = corrs.begin();
1252        cit!= corrs.end(); ++cit)
1253   {
1254     bwm_video_corr_sptr corr = *cit;
1255     if (!corr || !corr->world_pt_valid()) continue;
1256     vgl_point_3d<double> pt = corr->world_pt();
1257     pts.push_back(pt);
1258   }
1259   if (!pts.size())
1260     return;
1261   write_vrml_header(os);
1262   write_vrml_points(os, pts);
1263 }
1264 
save_video_world_points_vrml_impl(std::ofstream & os,vgl_box_3d<double> & box,double res)1265 static void save_video_world_points_vrml_impl(std::ofstream& os, vgl_box_3d<double> & box, double res)
1266 {
1267   bool found = false;
1268   std::vector<bwm_observer_cam*> obsvs =
1269     bwm_observer_mgr::instance()->observers_cam();
1270   bwm_observer_video* obv = nullptr;
1271 
1272   for (std::vector<bwm_observer_cam*>::iterator oit = obsvs.begin();
1273        oit != obsvs.end()&&!found; ++oit)
1274     if ((*oit)->type_name()=="bwm_observer_video")
1275     {
1276       obv = static_cast<bwm_observer_video*>(*oit);
1277       found =true;
1278     }
1279 
1280   if (!found)
1281   {
1282     std::cerr << "In bwm_site_mgr::save_video_world_points_vrml() - no observer of type video\n";
1283     return;
1284   }
1285   std::vector<vgl_point_3d<double> > pts;
1286   std::vector<bwm_video_corr_sptr> corrs = obv->corrs();
1287   int cnt=0;
1288   for (std::vector<bwm_video_corr_sptr>::iterator cit = corrs.begin();
1289        cit!= corrs.end(); ++cit)
1290   {
1291     if ((++cnt)%10==0)
1292     {
1293       bwm_video_corr_sptr corr = *cit;
1294       if (!corr || !corr->world_pt_valid()) continue;
1295       vgl_point_3d<double> pt = corr->world_pt();
1296       if (box.contains(pt))
1297         pts.push_back(pt);
1298     }
1299   }
1300   if (!pts.size())
1301     return;
1302   write_vrml_header(os);
1303   write_vrml_points(os, pts,res);
1304 }
1305 
save_video_world_points_vrml()1306 void bwm_site_mgr::save_video_world_points_vrml()
1307 {
1308   std::string ext = ".wrl";
1309   std::string path;
1310   vgui_dialog vrml_dialog("Write World Points");
1311   vrml_dialog.file("VRML file", ext, path);
1312   if (!vrml_dialog.ask())
1313     return;
1314   std::ofstream os(path.c_str());
1315   save_video_world_points_vrml_impl(os);
1316 }
1317 
save_video_cameras_vrml_impl(std::ofstream & os)1318 static void save_video_cameras_vrml_impl(std::ofstream& os)
1319 {
1320   bool found = false;
1321   std::vector<bwm_observer_cam*> obsvs =
1322     bwm_observer_mgr::instance()->observers_cam();
1323   bwm_observer_video* obv = nullptr;
1324 
1325   for (std::vector<bwm_observer_cam*>::iterator oit = obsvs.begin();
1326        oit != obsvs.end()&&!found; ++oit)
1327     if ((*oit)->type_name()=="bwm_observer_video")
1328     {
1329       obv = static_cast<bwm_observer_video*>(*oit);
1330       found =true;
1331     }
1332 
1333   if (!found)
1334   {
1335     std::cerr << "In bwm_site_mgr::save_video_cameras_vrml() - no observer of type video\n";
1336     return;
1337   }
1338   bwm_video_cam_istream_sptr cam_istr = obv->camera_stream();
1339   if (!cam_istr||!cam_istr->is_valid()||!cam_istr->is_seekable()) {
1340     std::cerr << "Invalid or non-seekable camera stream\n";
1341     return;
1342   }
1343   //to return to starting state
1344   unsigned cam_number = cam_istr->camera_number();
1345   cam_istr->seek_camera(0);
1346   std::vector<vpgl_perspective_camera<double> > cams;
1347   while (true) {
1348     vpgl_perspective_camera<double>* cam = cam_istr->current_camera();
1349     cams.push_back(*cam);
1350     if (!cam_istr->advance())
1351       break;
1352   }
1353   //restore the camera stream to initial position
1354   cam_istr->seek_camera(cam_number);
1355   if (!cams.size())
1356     return;
1357   write_vrml_cameras(os, cams);
1358 }
1359 
save_video_cameras_vrml_impl(std::ofstream & os,vgl_box_3d<double> box,double res)1360 static void save_video_cameras_vrml_impl(std::ofstream& os, vgl_box_3d<double> box, double res)
1361 {
1362   bool found = false;
1363   std::vector<bwm_observer_cam*> obsvs =
1364     bwm_observer_mgr::instance()->observers_cam();
1365   bwm_observer_video* obv = nullptr;
1366 
1367   for (std::vector<bwm_observer_cam*>::iterator oit = obsvs.begin();
1368        oit != obsvs.end()&&!found; ++oit)
1369     if ((*oit)->type_name()=="bwm_observer_video")
1370     {
1371       obv = static_cast<bwm_observer_video*>(*oit);
1372       found =true;
1373     }
1374 
1375   if (!found)
1376   {
1377     std::cerr << "In bwm_site_mgr::save_video_cameras_vrml() - no observer of type video\n";
1378     return;
1379   }
1380   bwm_video_cam_istream_sptr cam_istr = obv->camera_stream();
1381   if (!cam_istr||!cam_istr->is_valid()||!cam_istr->is_seekable()) {
1382     std::cerr << "Invalid or non-seekable camera stream\n";
1383     return;
1384   }
1385   //to return to starting state
1386   unsigned cam_number = cam_istr->camera_number();
1387   cam_istr->seek_camera(0);
1388   std::vector<vpgl_perspective_camera<double> > cams;
1389   int cnt=0;
1390   while (true) {
1391     vpgl_perspective_camera<double>* cam = cam_istr->current_camera();
1392     std::cout<<cam->get_camera_center();
1393     if (cnt++>170 )
1394       if (box.contains(cam->get_camera_center()))
1395         cams.push_back(*cam);
1396 
1397     if (!cam_istr->advance())
1398       break;
1399   }
1400   //restore the camera stream to initial position
1401   cam_istr->seek_camera(cam_number);
1402   if (!cams.size())
1403     return;
1404   write_vrml_cameras(os, cams, res);
1405 }
1406 
save_video_cameras_vrml()1407 void bwm_site_mgr::save_video_cameras_vrml()
1408 {
1409   std::string ext = ".wrl";
1410   std::string path;
1411   vgui_dialog vrml_dialog("Write World Points");
1412   vrml_dialog.file("VRML file", ext, path);
1413   if (!vrml_dialog.ask())
1414     return;
1415   std::ofstream os(path.c_str());
1416   write_vrml_header(os);
1417   save_video_cameras_vrml_impl(os);
1418 }
1419 
save_video_cams_and_world_pts_vrml()1420 void bwm_site_mgr::save_video_cams_and_world_pts_vrml()
1421 {
1422   std::string ext = ".wrl";
1423   std::string path;
1424   vgui_dialog vrml_dialog("Write World Points");
1425   vrml_dialog.file("VRML file", ext, path);
1426   vrml_dialog.checkbox("Default Params for saving ", defaultparam_);
1427   vrml_dialog.field("X min:", xmin_);
1428   vrml_dialog.field("X max:", xmax_);
1429   vrml_dialog.field("Y min:", ymin_);
1430   vrml_dialog.field("Y max:", ymax_);
1431   vrml_dialog.field("Z min:", zmin_);
1432   vrml_dialog.field("Z max:", zmax_);
1433   vrml_dialog.field("Resolution", res_);
1434 
1435   if (!vrml_dialog.ask())
1436     return;
1437   vgl_box_3d<double> box(xmin_,ymin_,zmin_,xmax_,ymax_,zmax_);
1438   std::ofstream os(path.c_str());
1439   write_vrml_header(os);
1440   if (defaultparam_)
1441   {
1442     save_video_world_points_vrml_impl(os);
1443     save_video_cameras_vrml_impl(os);
1444   }
1445   else
1446   {
1447     save_video_world_points_vrml_impl(os,box,res_);
1448     save_video_cameras_vrml_impl(os,box,res_*5);
1449 #ifdef DEBUG
1450     write_vrml_box(os, box);
1451 #endif
1452   }
1453 }
1454 
1455 //: compute 3-d parameters, site bounding box and GSD
compute_3d_world_params()1456 void bwm_site_mgr::compute_3d_world_params()
1457 {
1458   std::string path = "";
1459   std::string ext = "*.txt";
1460   vgui_dialog par_dlg("World Params");
1461   par_dlg.file("Param File", ext, path);
1462   if (!par_dlg.ask())
1463     return;
1464   vgl_box_3d<double> bb;
1465   double gsd = 0;
1466 
1467   bool found = false;
1468   std::vector<bwm_observer_cam*> obsvs =
1469     bwm_observer_mgr::instance()->observers_cam();
1470   bwm_observer_video* obv = nullptr;
1471 
1472   for (std::vector<bwm_observer_cam*>::iterator oit = obsvs.begin();
1473        oit != obsvs.end()&&!found; ++oit)
1474     if ((*oit)->type_name()=="bwm_observer_video")
1475     {
1476       obv = static_cast<bwm_observer_video*>(*oit);
1477       found =true;
1478     }
1479 
1480   if (!found)
1481   {
1482     std::cerr << "In bwm_site_mgr::compute_world_params() - no observer of type video\n";
1483     return;
1484   }
1485   std::vector<bwm_video_corr_sptr> corrs = obv->corrs();
1486   if (!corrs.size()) {
1487     std::cerr << "In bwm_site_mgr::compute_world_params() - no correspondences\n";
1488     return;
1489   }
1490   bwm_video_cam_istream_sptr cam_istr = obv->camera_stream();
1491   if (!cam_istr || !cam_istr->is_valid() || !cam_istr->is_seekable()) {
1492     std::cerr << "In bwm_site_mgr::compute_world_params() - no correspondences\n";
1493     return;
1494   }
1495   //Add world points to bounding box
1496   std::vector<bwm_video_corr_sptr>::iterator cit = corrs.begin();
1497   for (; cit != corrs.end(); ++cit)
1498   {
1499     bwm_video_corr_sptr c = *cit;
1500     if (!c) continue;
1501     if (c->world_pt_valid())
1502       bb.add(c->world_pt());
1503   }
1504   //to restore cam stream state
1505   unsigned cam_number = cam_istr->camera_number();
1506   cam_istr->seek_camera(0);
1507   vpgl_perspective_camera<double>* cam = cam_istr->current_camera();
1508   //project the bounding box
1509   vgl_box_2d<double> bb_2d = bpgl_project::project_bounding_box(*cam, bb);
1510   //get the number of pixels on the diagonal
1511   double w = bb_2d.width(), h = bb_2d.height();
1512   double diag2 = std::sqrt(w*w + h*h);
1513   //get the length of the 3-d bb diagonal
1514   double w3 = bb.width(), h3 = bb.height(), d3 = bb.depth();
1515   double diag3 = std::sqrt(w3*w3 + h3*h3 + d3*d3);
1516   gsd = diag3/diag2;
1517   std::ofstream os(path.c_str());
1518   if (!os.is_open()) {
1519     std::cerr << "In bwm_site_mgr::compute_world_params() - invalid parameter output path\n";
1520     return;
1521   }
1522   os << "World Bounding Box\n"
1523      << bb << '\n'
1524      << "Ground Sample Distance(GSD): " << gsd << '\n'
1525      << "Bounding box size in GSD units\n"
1526      << "Xsize:" << static_cast<unsigned>(bb.width()/gsd)
1527      << " Ysize:" << static_cast<unsigned>(bb.height()/gsd)
1528      << " Zsize:" << static_cast<unsigned>(bb.depth()/gsd) << '\n';
1529   os.close();
1530   //restore camera stream state
1531   cam_istr->seek_camera(cam_number);
1532 }
1533 
load_depth_map_scene()1534 void bwm_site_mgr::load_depth_map_scene()
1535 {
1536   std::string path = bwm_utils::select_file();
1537   std::string dir = vul_file::dirname(path);
1538   depth_map_scene scene;
1539   vsl_b_ifstream is(path.c_str());
1540   if (!is) {
1541     std::cout << "invalid binary stream for path " << path << std::endl;
1542     return;
1543   }
1544   scene.b_read(is);
1545   std::string name = "depth_map";
1546   std::string ifile = scene.image_path();
1547   std::string ipath;
1548   if (!vul_file::exists(ifile)) {
1549     // loaded depth_map_scene doesn't have image path, use the jpg having same name instead
1550     std::cerr << "\n WARNING: loaded depth_map_scene does not have image path" << std::endl;
1551     std::string temp = vul_file::strip_extension(vul_file::strip_directory(path.c_str())) + ".jpg";
1552     scene.set_image_path(temp);
1553     ipath = dir + '/' + temp;
1554   }
1555   else
1556     ipath = ifile;
1557   bwm_io_tab_config* tab = new bwm_io_tab_config_cam(name, true, ipath , "not_needed" , "perspective");
1558   active_tableaus_.push_back(tab);
1559   bwm_tableau_img*  t = tableau_factory_.create_tableau(tab);
1560   bwm_tableau_mgr::instance()->add_tableau(t, name);
1561   bwm_tableau_cam* tc = reinterpret_cast<bwm_tableau_cam*>(t);
1562   vpgl_camera<double>* cam = new vpgl_perspective_camera<double>(scene.cam());
1563   tc->observer()->set_camera(cam, "");
1564   tc->observer()->set_depth_map_scene(scene);
1565   tc->observer()->display_depth_map_scene();
1566 }
1567 
save_depth_map_scene()1568 void bwm_site_mgr::save_depth_map_scene()
1569 {
1570   std::cerr << "bwm_site_mgr::save_depth_map_scene() not yet implemented!!!\n";
1571 }
1572