1 #include <iostream>
2 #include <sstream>
3 #include "bwm_observable_mesh.h"
4 #include "bwm_world.h"
5 //:
6 // \file
7 #include "bwm_def.h"
8 #include "algo/bwm_algo.h"
9 
10 #include <cassert>
11 #ifdef _MSC_VER
12 #  include "vcl_msvc_warnings.h"
13 #endif
14 #include "vnl/vnl_math.h"
15 
16 #include "vgl/vgl_point_3d.h"
17 #include "vgl/vgl_vector_3d.h"
18 #include "vgl/vgl_plane_3d.h"
19 #include "vgl/vgl_box_3d.h"
20 #include <vgl/algo/vgl_h_matrix_3d.h>
21 #include "vgl/vgl_closest_point.h"
22 #include "vgl/vgl_line_3d_2_points.h"
23 #include "vgl/vgl_homg_point_3d.h"
24 #include <vgl/algo/vgl_fit_plane_3d.h>
25 #include "vgl/vgl_distance.h"
26 #include "vgl/vgl_intersection.h"
27 
28 #include <vpgl/algo/vpgl_ray.h>
29 #include <vpgl/algo/vpgl_backproject.h>
30 
31 #include <vsol/vsol_point_3d.h>
32 #include <vsol/vsol_line_3d.h>
33 #include <vsol/vsol_polygon_2d.h>
34 #include <vsol/vsol_polygon_3d.h>
35 #include <vsol/vsol_box_3d.h>
36 
37 #include <bmsh3d/bmsh3d_textured_mesh_mc.h>
38 #include <bmsh3d/algo/bmsh3d_fileio.h>
39 #include <bmsh3d/algo/bmsh3d_mesh_triangulate.h>
40 
bwm_observable_mesh()41 bwm_observable_mesh::bwm_observable_mesh()
42   : object_(nullptr)
43 {
44   //bwm_world::instance()->add(this);
45 }
46 
bwm_observable_mesh(BWM_MESH_TYPES type)47 bwm_observable_mesh::bwm_observable_mesh(BWM_MESH_TYPES type)
48   : object_(nullptr), mesh_type_(type)
49 {
50   //bwm_world::instance()->add(this);
51 }
52 
bwm_observable_mesh(bmsh3d_mesh_mc * object)53 bwm_observable_mesh::bwm_observable_mesh(bmsh3d_mesh_mc* object)
54   : object_(object)
55 {
56   //bwm_world::instance()->add(this);
57 }
58 
bwm_observable_mesh(vsol_polygon_3d_sptr poly)59 bwm_observable_mesh::bwm_observable_mesh(vsol_polygon_3d_sptr poly)
60 {
61   // create a single face mesh
62   object_ = new bmsh3d_mesh_mc;
63   bmsh3d_face_mc* face = create_face(poly);
64   object_->_add_face (face);
65   object_->orient_face_normals();
66   // add yourself to The World
67   //bwm_world::instance()->add(this);
68   notify_observers("new");
69 }
70 
71 //: create a mesh from a 3D box
bwm_observable_mesh(vgl_box_3d<double> box)72 bwm_observable_mesh::bwm_observable_mesh(vgl_box_3d<double> box)
73 {
74   // get the bottom polygon
75   vgl_point_3d<double> min=box.min_point();
76   vgl_point_3d<double> max=box.max_point();
77   vgl_point_3d<double> p1(max.x(), min.y(), min.z());
78   vgl_point_3d<double> p2(min.x(), max.y(), min.z());
79   vgl_point_3d<double> p3(max.x(), max.y(), min.z());
80   std::vector<vsol_point_3d_sptr> v;
81   v.push_back(new vsol_point_3d(min));
82   v.push_back(new vsol_point_3d(p1));
83   v.push_back(new vsol_point_3d(p3));
84   v.push_back(new vsol_point_3d(p2));
85   vsol_polygon_3d_sptr poly = new vsol_polygon_3d(v);
86 
87   // create the mesh
88   object_ = new bmsh3d_mesh_mc;
89   bmsh3d_face_mc* face = create_face(poly);
90   object_->_add_face (face);
91   object_->orient_face_normals();
92 
93   // extrude the bottom till top
94   this->extrude(0, max.z()-min.z());
95   notify_observers("new");
96 }
97 
~bwm_observable_mesh()98 bwm_observable_mesh::~bwm_observable_mesh()
99 {
100 #if 0
101   notify_observers("delete");
102   std::vector<vgui_observer*> observers;
103   get_observers(observers);
104   for (unsigned i=0; i<observers.size(); i++) {
105     detach(observers[i]);
106   }
107 #endif // 0
108   remove();
109 }
110 
operator =(bwm_observable_mesh & m)111 bwm_observable_mesh& bwm_observable_mesh::operator=(bwm_observable_mesh& m)
112 {
113   bmsh3d_mesh_mc *o=m.get_object();
114   object_=o->clone();
115   notify_observers("new");
116   return *this;
117 }
118 
remove()119 void bwm_observable_mesh::remove()
120 {
121   if (object_) {
122     notify_observers("delete");
123   }
124 
125   std::vector<vgui_observer*> observers;
126   get_observers(observers);
127   for (unsigned i=0; i<observers.size(); i++) {
128     detach(observers[i]);
129   }
130   // remove the object from world
131   //bwm_world::instance()->remove(this);
132 }
133 
notify_observers(std::string message_type)134 void bwm_observable_mesh::notify_observers(std::string message_type)
135 {
136   vgui_message msg;
137   msg.from = this;
138   msg.data = new std::string(message_type);
139   this->notify(msg);
140 }
141 
bounding_box()142 vgl_box_3d<double> bwm_observable_mesh::bounding_box()
143 {
144   vgl_box_3d<double> bb;
145   detect_bounding_box(object_, bb);
146   return bb;
147 }
148 
get_face_label(unsigned face_id)149 BWM_FACE_LABEL bwm_observable_mesh::get_face_label(unsigned face_id)
150 {
151   std::map<unsigned, BWM_FACE_LABEL>::iterator it = labels_.find(face_id);
152   if (it != labels_.end())
153     return it->second;
154   return None;
155 }
156 
send_update()157 void bwm_observable_mesh::send_update()
158 {
159   if (object_)
160     notify_observers("update");
161 }
162 
translate(vgl_vector_3d<double> T)163 void bwm_observable_mesh::translate(vgl_vector_3d<double> T)
164 {
165   std::map<int, bmsh3d_vertex*> v_map = object_->vertexmap();
166   std::map<int, bmsh3d_vertex*>::iterator iter = v_map.begin();
167   while (iter != v_map.end()) {
168     bmsh3d_vertex* v = (bmsh3d_vertex*) iter->second;
169     v->set_pt (vgl_point_3d<double> (v->get_pt().x() + T.x() ,
170                                      v->get_pt().y() + T.y(),
171                                      v->get_pt().z() + T.z()));
172     std::cout << v->get_pt() << std::endl;
173     iter++;
174   }
175   notify_observers("move");
176 }
177 
178 bool bwm_observable_mesh::
single_face_with_vertices(unsigned face_id,vsol_polygon_3d_sptr & poly,std::vector<bmsh3d_vertex * > & verts)179 single_face_with_vertices(unsigned face_id,
180                           vsol_polygon_3d_sptr& poly,
181                           std::vector<bmsh3d_vertex*>& verts)
182 {
183   bmsh3d_face_mc* face = (bmsh3d_face_mc*)object_->facemap(face_id);
184   if (face && (object_->facemap().size() == 1)) {
185     bmsh3d_face_mc* face = (bmsh3d_face_mc*) object_->facemap(face_id);
186     poly = this->extract_face(face, verts);
187     return true;
188   }
189   else
190     return false;
191 }
192 
transform(vgl_h_matrix_3d<double> T_)193 bwm_observable_sptr bwm_observable_mesh::transform(vgl_h_matrix_3d<double> T_)
194 {
195   bmsh3d_mesh_mc* M_copy = object_->clone();
196   std::map<int, bmsh3d_vertex*> vertices = M_copy->vertexmap();
197   for (unsigned i=0; i<vertices.size(); i++) {
198     bmsh3d_vertex* v = vertices[i];
199     vgl_point_3d<double> p = v->get_pt();
200     vgl_homg_point_3d<double> tp = T_(vgl_homg_point_3d<double>(p));
201     v->set_pt (tp);
202   }
203   return new bwm_observable_mesh(M_copy);
204 }
205 
206 // Move the polygon along the rays through its vertices.
207 // The polygon shape will change as it moves, but the
208 // projection of the polygon in the camera is invariant motion along the rays
move_poly_in_optical_cone(vpgl_camera<double> * cam,unsigned face_id,double da)209 bool bwm_observable_mesh::move_poly_in_optical_cone(vpgl_camera<double> * cam,
210                                                     unsigned face_id,
211                                                     double da)
212 {
213   if (!cam) return false;
214   vsol_polygon_3d_sptr poly_3d;
215   std::vector<bmsh3d_vertex*> verts;
216   if (!this->single_face_with_vertices(face_id,poly_3d,verts))
217   {
218     std::cerr << "In bwm_observable_mesh::move_poly_in_optical_cone - "
219              << "meshes with more than one face not allowed\n";
220     return false;
221   }
222   // extract the 3-d plane of the mesh face
223   vgl_plane_3d<double> plane(poly_3d->plane());
224   // an arbitrary vertex to generate the movement vector
225   vgl_point_3d<double> pg3d= verts[0]->pt();
226   //get the direction of a ray
227   vgl_vector_3d<double> ray_dir;
228   if (!vpgl_ray::ray(cam, pg3d, ray_dir))
229   {
230     std::cerr << "In bwm_observable_mesh::move_poly_in_optical_cone - "
231              << "ray direction computation failed\n";
232     return false;
233   }
234   ray_dir /= ray_dir.length();
235   ray_dir *= da;  // ray_dir is now the motion vector
236 
237   //extract the plane coefficients
238   double a = plane.a(), b = plane.b(), c = plane.c(), d = plane.d();
239   vgl_vector_3d<double> normal(a, b, c);
240   double mag = normal.length();
241   // normalize the plane so that the normal is a unit vector
242   normal /= mag;
243   d /= mag;
244   // translate the plane by the motion vector
245   d += dot_product(normal, ray_dir);
246   // -d now corresponds to the translated  plane distance from the origin
247   plane.set(normal.x(), normal.y(), normal.z(), d);
248 
249   // intersect rays through each vertex to
250   // get the vertices translated and scaled in the cone
251   for (std::vector<bmsh3d_vertex*>::iterator vit = verts.begin();
252        vit != verts.end(); ++vit)
253   {
254     vgl_point_3d<double> pg= (*vit)->pt();
255     //get the direction of a ray
256     vgl_vector_3d<double> rdir;
257     if (!vpgl_ray::ray(cam, pg, rdir))
258     {
259       std::cerr << "In bwm_observable_mesh::translate_along_optical_cone - "
260                << "ray direction computation failed\n";
261       return false;
262     }
263     vgl_infinite_line_3d<double> l(pg, rdir);
264     vgl_point_3d<double> i_pt;
265     if (!vgl_intersection(l, plane, i_pt))
266     {
267       std::cerr << "In bwm_observable_mesh::translate_along_optical_cone - "
268                << "ray intersection computation failed\n";
269       return false;
270     }
271     (*vit)->set_pt(i_pt);
272   }
273   // the mesh face has now been transformed by the motion along the cone
274   // so notify all the observers of the new shape
275   this->notify_observers("move");
276   return true;
277 }
278 
extrude(int face_id)279 void bwm_observable_mesh::extrude(int face_id)
280 {
281   this->extrude(face_id, 0.01);
282 #if 0 // commented out
283   if (object_ != 0) {
284     bmsh3d_face_mc* face = (bmsh3d_face_mc*)object_->facemap(face_id);
285     if (face) {
286       if (object_->facemap().size() == 1) {
287         bmsh3d_face_mc* face = (bmsh3d_face_mc*) object_->facemap(face_id);
288         std::vector<bmsh3d_vertex*> vertices;
289         vsol_polygon_3d_sptr poly = this->extract_face(face, vertices);
290         std::map<int, vsol_polygon_3d_sptr> inner_faces = this->extract_inner_faces(face);
291         delete object_;
292         object_ = new bmsh3d_mesh_mc();
293         // the first polygon is always the outer one
294         create_mesh_HE(poly, 0.01, inner_faces);
295       }
296       else {
297         current_extr_face = extrude_face(object_, face);
298       }
299       notify_observers("update");
300     }
301     else
302       current_extr_face = 0;
303   }
304   std::cout << "FACES====>" << std::endl;
305   this->print_faces();
306 #endif // 0
307 }
308 
extrude(int face_id,double dist)309 void bwm_observable_mesh::extrude(int face_id, double dist)
310 {
311   if (object_ != nullptr) {
312     bmsh3d_face_mc* face = (bmsh3d_face_mc*)object_->facemap(face_id);
313     if (face) {
314       if (object_->facemap().size() == 1) {
315         bmsh3d_face_mc* face = (bmsh3d_face_mc*) object_->facemap(face_id);
316         std::vector<bmsh3d_vertex*> vertices;
317         vsol_polygon_3d_sptr poly = this->extract_face(face, vertices);
318         std::map<int, vsol_polygon_3d_sptr> inner_faces = this->extract_inner_faces(face);
319         delete object_;
320         object_ = new bmsh3d_mesh_mc();
321         // the first polygon is always the outer one
322         create_mesh_HE(poly, dist, inner_faces);
323       }
324       else {
325         current_extr_face = extrude_face(object_, face);
326         move_extr_face(dist);
327       }
328       notify_observers("update");
329     }
330     else
331       current_extr_face = nullptr;
332   }
333 #if 0
334   std::cout << "FACES====>" << std::endl;
335   this->print_faces();
336 #endif
337 }
338 
set_object(bmsh3d_mesh_mc * obj)339 void bwm_observable_mesh::set_object(bmsh3d_mesh_mc* obj)
340 {
341   std::string msg = "";
342   if (object_ == nullptr)
343     msg = "new";
344   else {
345     msg = "update";
346     delete object_;
347   }
348 
349   object_ = obj;
350   //object_->orient_face_normals();
351   notify_observers(msg);
352 }
353 
set_object(vsol_polygon_3d_sptr poly,double z)354 void bwm_observable_mesh::set_object(vsol_polygon_3d_sptr poly, double z)
355 {
356   std::string msg = "";
357   if (object_ == nullptr)
358     msg = "new";
359   else {
360     msg = "update";
361     delete object_;
362   }
363 
364   object_ = new bmsh3d_mesh_mc;
365   std::map<int, vsol_polygon_3d_sptr> inner_faces;
366   create_mesh_HE(poly, z, inner_faces);
367   //object_->orient_face_normals();
368   notify_observers(msg);
369 }
370 
set_object(vsol_polygon_3d_sptr poly)371 void bwm_observable_mesh::set_object(vsol_polygon_3d_sptr poly)
372 {
373   if (!poly || poly->size()==0)
374     return;
375 
376   std::string msg = "";
377   if (object_ == nullptr)
378     msg = "new";
379   else {
380     msg = "update";
381     delete object_;
382   }
383   object_ = new bmsh3d_mesh_mc;
384   bmsh3d_face_mc* face = create_face(poly);
385   object_->_add_face (face);
386   //object_->orient_face_normals();
387   notify_observers(msg);
388 }
389 
replace(bmsh3d_mesh_mc * obj)390 void bwm_observable_mesh::replace(bmsh3d_mesh_mc* obj)
391 {
392   std::string msg="";
393   if (object_) {
394     delete object_;
395     msg = "update";
396   }
397   else
398     msg = "new";
399   object_ = obj;
400   //object_->orient_face_normals();
401   notify_observers(msg);
402 }
403 
404 //: Returns a list of polygons.
405 //  If there are inner faces, there are more than one polygon,
406 //  otherwise it is always one.
extract_face(bmsh3d_face_mc * face,std::vector<bmsh3d_vertex * > & vertices)407 vsol_polygon_3d_sptr bwm_observable_mesh::extract_face(bmsh3d_face_mc* face,
408                                                        std::vector<bmsh3d_vertex*> &vertices)
409 {
410   std::vector<vsol_point_3d_sptr> v_list;
411   bmsh3d_halfedge* cur_he = (bmsh3d_halfedge*) face->halfedge();
412 #if 0
413   //open
414   bwm_algo::move_points_to_plane(face);
415 #endif
416   do {
417     bmsh3d_halfedge* next_he = (bmsh3d_halfedge*) cur_he->next();
418     bmsh3d_vertex* vertex = (bmsh3d_vertex*) Es_sharing_V  (cur_he->edge(), next_he->edge());
419 
420     vertices.push_back(vertex);
421     //std::cout << "vertex " << vertex->id() << " between "
422     //         << cur_he->edge()->id() << " and "
423     //         << next_he->edge()->id() << std::endl;
424     vgl_point_3d<double> p = vertex->get_pt();
425     v_list.push_back(new vsol_point_3d (p.x(), p.y(), p.z()));
426     cur_he = (bmsh3d_halfedge*) cur_he->next();
427   }
428   while (cur_he != face->halfedge());
429 
430   vsol_polygon_3d_sptr poly3d = new vsol_polygon_3d(v_list);
431   return poly3d;
432 }
433 
434 std::map<int, vsol_polygon_3d_sptr>
extract_inner_faces(bmsh3d_face_mc * face)435 bwm_observable_mesh::extract_inner_faces(bmsh3d_face_mc* face)
436 {
437   // now, add the inner polygons
438   std::map<int, bmsh3d_halfedge*> set_he = face->get_mc_halfedges();
439   std::map<int, vsol_polygon_3d_sptr> polygons;
440   std::map<int, bmsh3d_halfedge*>::iterator it = set_he.begin();
441   while (it != set_he.end())
442   {
443     bmsh3d_halfedge* he = it->second;
444     bmsh3d_halfedge* HE = he;
445     std::vector<vsol_point_3d_sptr> v_list;
446 
447     do {
448       bmsh3d_halfedge* next_he = (bmsh3d_halfedge*) HE->next();
449       bmsh3d_vertex* vertex = (bmsh3d_vertex*) Es_sharing_V  (HE->edge(), next_he->edge());
450       //vertices.push_back(vertex);
451       vgl_point_3d<double> p = vertex->get_pt();
452       v_list.push_back(new vsol_point_3d (p.x(), p.y(), p.z()));
453       HE = next_he;
454     }
455     while (HE != he);
456 
457     vsol_polygon_3d_sptr poly3d = new vsol_polygon_3d(v_list);
458     polygons[it->first] = poly3d;
459     it++;
460   }
461   return polygons;
462 }
463 
464 std::map<int, vsol_polygon_3d_sptr>
extract_inner_faces(int face_id)465 bwm_observable_mesh::extract_inner_faces(int face_id)
466 {
467   bmsh3d_face_mc* face = (bmsh3d_face_mc*)object_->facemap(face_id);
468   std::map<int, vsol_polygon_3d_sptr> polys;
469   if (face) {
470     polys = extract_inner_faces(face);
471   }
472   return polys;
473 }
474 
extract_face(unsigned i)475 vsol_polygon_3d_sptr bwm_observable_mesh::extract_face(unsigned i)
476 {
477   bmsh3d_face_mc* face = (bmsh3d_face_mc*) object_->facemap(i);
478   std::vector<bmsh3d_vertex*> vertices;
479   vsol_polygon_3d_sptr poly = extract_face(face, vertices);
480   return poly;
481 }
482 
extract_bottom_face()483 vsol_polygon_3d_sptr bwm_observable_mesh::extract_bottom_face()
484 {
485   std::map<int, bmsh3d_face*>::iterator it = object_->facemap().begin();
486   std::map<int, vsol_polygon_3d_sptr> faces;
487   double min_z=1e6;
488   vsol_polygon_3d_sptr bottom;
489   for (; it != object_->facemap().end(); it++) {
490     bmsh3d_face_mc* face = (bmsh3d_face_mc*) (*it).second;
491     //std::cout << "face " << face->id() << std::endl;
492     std::vector<bmsh3d_vertex*> vertices;
493     vsol_polygon_3d_sptr poly = this->extract_face(face, vertices);
494     vsol_box_3d_sptr bb = poly->get_bounding_box();
495     if (min_z > bb->get_min_z()) {
496       min_z = bb->get_min_z();
497       bottom = poly;
498     }
499   }
500   return bottom;
501 }
502 
extract_faces()503 std::map<int, vsol_polygon_3d_sptr> bwm_observable_mesh::extract_faces()
504 {
505   std::map<int, bmsh3d_face*>::iterator it = object_->facemap().begin();
506   std::map<int, vsol_polygon_3d_sptr> faces;
507 
508   for (; it != object_->facemap().end(); it++) {
509     bmsh3d_face_mc* face = (bmsh3d_face_mc*) (*it).second;
510     //std::cout << "face " << face->id() << std::endl;
511     std::vector<bmsh3d_vertex*> vertices;
512     vsol_polygon_3d_sptr poly = this->extract_face(face, vertices);
513     faces[face->id()] = poly;
514   }
515   return faces;
516 }
517 
extract_edges()518 std::map<int, vsol_line_3d_sptr> bwm_observable_mesh::extract_edges()
519 {
520   std::map<int, bmsh3d_edge*>::iterator it = object_->edgemap().begin();
521   std::map<int, vsol_line_3d_sptr> edges;
522 
523   for (; it != object_->edgemap().end(); it++) {
524     bmsh3d_edge* edge = (bmsh3d_edge*) (*it).second;
525     bmsh3d_vertex* V0 = edge->vertices(0);
526     bmsh3d_vertex* V1 = edge->vertices(1);
527     vsol_point_3d_sptr v0 = new vsol_point_3d(V0->pt().x(),V0->pt().y(),V0->pt().z());
528     vsol_point_3d_sptr v1 = new vsol_point_3d(V1->pt().x(),V1->pt().y(),V1->pt().z());
529     vsol_line_3d_sptr e = new vsol_line_3d(v0, v1);
530     edges[edge->id()] = e;
531   }
532   return edges;
533 }
534 
extract_vertices()535 std::vector<vsol_point_3d_sptr> bwm_observable_mesh::extract_vertices()
536 {
537   std::vector<vsol_point_3d_sptr> vertices;
538   if (object_) {
539     std::map<int, bmsh3d_vertex*>::iterator it = object_->vertexmap().begin();
540     for (; it != object_->vertexmap().end(); it++) {
541       bmsh3d_vertex* V = (bmsh3d_vertex*) it->second;
542       vsol_point_3d_sptr pt = new vsol_point_3d(V->pt().x(),V->pt().y(),V->pt().z());
543       vertices.push_back(pt);
544     }
545   }
546   return vertices;
547 }
548 
create_interior()549 void bwm_observable_mesh::create_interior()
550 {
551   if (object_) {
552     bmsh3d_mesh_mc* interior = object_->clone();
553     //double l = object_->edgemap(0)->length();
554     shrink_mesh(interior, 0);//l/10.);
555     //merge_mesh(object_, interior);
556     object_=interior;
557     this->notify_observers("update");
558   }
559 }
560 
move(vsol_polygon_3d_sptr poly)561 void bwm_observable_mesh::move(vsol_polygon_3d_sptr poly)
562 {
563   if (!object_) {
564     std::cerr << "mesh object id null\n";
565     return;
566   }
567 
568   if (object_->facemap().size() == 1) {
569     std::map<int, bmsh3d_face*>::iterator it = object_->facemap().begin();
570     bmsh3d_face_mc* face = (bmsh3d_face_mc*) (*it).second;
571     std::vector<bmsh3d_vertex*> vertices;
572     vsol_polygon_3d_sptr old_poly = extract_face(face, vertices);
573 
574     for (unsigned i=0; i<poly->size(); i++) {
575       bmsh3d_vertex* v = (bmsh3d_vertex*) vertices[i];
576       vsol_point_3d_sptr p = poly->vertex(i);
577       v->set_pt (vgl_point_3d<double> (p->x(), p->y(), p->z()));
578     }
579     notify_observers("move");
580   }
581 }
582 
move_normal_dir(double dist)583 void bwm_observable_mesh::move_normal_dir(double dist)
584 {
585   if (object_->facemap().size() == 1) {
586     std::map<int, bmsh3d_face*>::iterator it = object_->facemap().begin();
587     bmsh3d_face_mc* face = (bmsh3d_face_mc*) (*it).second;
588     //vgl_vector_3d<double> normal = face->compute_normal();
589     //normal /= normal.length();
590 
591     std::vector<bmsh3d_vertex*> vertices;
592     vsol_polygon_3d_sptr poly = extract_face(face, vertices);
593     vgl_vector_3d<double> normal = poly->normal();
594     //normal /= normal.length();
595     for (unsigned i=0; i<poly->size(); i++) {
596       bmsh3d_vertex* v = (bmsh3d_vertex*) vertices[i];
597       vsol_point_3d_sptr p = poly->vertex(i);
598       v->set_pt (vgl_point_3d<double> (v->get_pt().x() + dist*normal.x() ,
599                                        v->get_pt().y() + dist*normal.y(),
600                                        v->get_pt().z() + dist*normal.z()));
601     }
602     notify_observers("move");
603   }
604 }
605 
move_extr_face(double z)606 void bwm_observable_mesh::move_extr_face(double z)
607 {
608   if (current_extr_face) {
609     std::vector<bmsh3d_vertex*> vertices;
610     vsol_polygon_3d_sptr polygon = extract_face(current_extr_face, vertices);
611     // at this point, the halfedges already sorted in extract_face
612 
613     for (unsigned i=0; i<vertices.size(); i++) {
614       bmsh3d_vertex* v = vertices[i];
615       //vgl_vector_3d<double> normal = current_extr_face->compute_normal(edge, v);
616       vsol_point_3d_sptr p = polygon->vertex(i);
617       //vgl_vector_3d<double> normal = polygon->normal_at_point(p);
618 #if 0
619       v->set_pt (vgl_point_3d<double> (v->get_pt().x() + z*normal.x()/1000. ,
620                                        v->get_pt().y() + z*normal.y()/1000.,
621                                        v->get_pt().z() + z*normal.z()));
622 #endif // 0
623       v->set_pt (vgl_point_3d<double> (v->get_pt().x(), v->get_pt().y(), v->get_pt().z()+z));
624       //just use the z value as the new height
625 
626       //std::cout << "new v=" << v->get_pt() << std::endl;
627     }
628     // FIX THIS , uncomment
629     //bwm_algo::move_points_to_plane(current_extr_face);
630     notify_observers("update");
631   }
632 }
633 
divide_face(unsigned face_id,vgl_point_3d<double> l1,vgl_point_3d<double> l2,vgl_point_3d<double> p1,vgl_point_3d<double> l3,vgl_point_3d<double> l4,vgl_point_3d<double> p2)634 void bwm_observable_mesh::divide_face(unsigned face_id,
635                                       vgl_point_3d<double> l1, vgl_point_3d<double> l2,
636                                       vgl_point_3d<double> p1,
637                                       vgl_point_3d<double> l3, vgl_point_3d<double> l4,
638                                       vgl_point_3d<double> p2)
639 {
640   bmsh3d_face_mc* face = (bmsh3d_face_mc*) object_->facemap(face_id);
641   std::vector<bmsh3d_halfedge *> halfedges;
642   if (face == nullptr) {
643     print_faces();
644     std::cerr << "Face " << face_id << " is not found in the facemap\n";
645   }
646   face->get_incident_HEs(halfedges);
647   std::vector<bmsh3d_vertex *> vertices;
648   extract_face(face, vertices);
649   // create 2 new vertices
650   bmsh3d_vertex* v1 = (bmsh3d_vertex*) object_->_new_vertex ();
651   v1->get_pt().set(p1.x(), p1.y(), p1.z());
652   object_->_add_vertex(v1);
653 
654   bmsh3d_vertex* v2 = (bmsh3d_vertex*) object_->_new_vertex ();
655   v2->get_pt().set(p2.x(), p2.y(), p2.z());
656   object_->_add_vertex(v2);
657 
658   // find the halfedges corresponding to edge segments
659   bmsh3d_edge* edge1=nullptr;
660   bmsh3d_edge* edge2=nullptr;
661 
662 #ifdef DEBUG
663   std::cout << "p1=" << p1 << " p2=" << p2 << '\n'
664            << "l1=" << l1 << '\n'
665            << "l2=" << l2 << '\n'
666            << "l3=" << l3 << '\n'
667            << "l4=" << l4 << std::endl;
668 #endif
669   double min_d1=1e23, min_d2=1e23;
670   unsigned min_index1=0, min_index2=0;
671   for (unsigned i=0; i<halfedges.size(); i++) {
672     bmsh3d_halfedge* he = (bmsh3d_halfedge*) halfedges[i];
673     bmsh3d_edge* edge = he->edge();
674     bmsh3d_vertex* s = (bmsh3d_vertex*) edge->sV();
675     bmsh3d_vertex* e = (bmsh3d_vertex*) edge->eV();
676     vgl_point_3d<double> sp(s->get_pt());
677     vgl_point_3d<double> ep(e->get_pt());
678 
679     vgl_line_3d_2_points<double> line(sp, ep);
680     //std::cout << "edge" << edge->id() << " s=" << s->get_pt() << "e =" << e->get_pt() << std::endl;
681 
682     double d1 = vgl_distance(vgl_point_3d<double>(l1), line);
683     double d2 = vgl_distance(vgl_point_3d<double>(l2), line);
684     double d3 = vgl_distance(vgl_point_3d<double>(l3), line);
685     double d4 = vgl_distance(vgl_point_3d<double>(l4), line);
686 
687     // we are checking if the points l1, l2, l3 or l4 are on the line
688     if ((d1+d2) < min_d1) {
689       min_d1 = d1+d2;
690       min_index1 = i;
691     }
692 
693     if ((d3+d4) < min_d2) {
694       min_d2 = d3+d4;
695       min_index2 = i;
696     }
697 
698 #if 0 // commented out
699     if (collinear(line, vgl_point_3d<double>(l1)) &&
700         collinear(line, vgl_point_3d<double>(l2)))
701       edge1 = edge;
702 
703     if (collinear(line, vgl_point_3d<double>(l3)) &&
704         collinear(line, vgl_point_3d<double>(l4)))
705       edge2 = edge;
706 #endif // 0
707   }
708   bmsh3d_halfedge* he1 = (bmsh3d_halfedge*) halfedges[min_index1];
709   edge1 = he1->edge();
710 
711   bmsh3d_halfedge* he2 = (bmsh3d_halfedge*) halfedges[min_index2];
712   edge2 = he2->edge();
713 
714   if (edge1 == nullptr || edge2 == nullptr) {
715     std::cerr << "bwm_observable_mesh::divide_face -- edges are not found in polygon\n";
716     return;
717   }
718 
719   bmsh3d_face_mc *f1, *f2;
720   mesh_break_face(object_, face, edge1, edge2, v1, v2, f1, f2);
721   //int num_faces = object_->face_id_counter();
722   object_->orient_face_normals();
723   notify_observers("update");
724 }
725 
726 //: Creates an inner face
create_inner_face(vsol_polygon_3d_sptr polygon)727 bmsh3d_face* bwm_observable_mesh::create_inner_face(vsol_polygon_3d_sptr polygon)
728 {
729   polygon = bwm_algo::move_points_to_plane(polygon);
730   unsigned n = polygon->size();
731   bmsh3d_face* inner_face = new bmsh3d_face();
732   // create vertices
733   bmsh3d_vertex* prev_v = nullptr;
734   bmsh3d_vertex* v_first;
735   for (unsigned i=0; i<n; i++) {
736     double x = polygon->vertex(i)->x();
737     double y = polygon->vertex(i)->y();
738     double z = polygon->vertex(i)->z();
739     bmsh3d_vertex* v = (bmsh3d_vertex*) object_->_new_vertex ();
740     v->get_pt().set(x, y, z);
741     object_->_add_vertex(v); //??? do we add this vertex to the mesh
742     if (prev_v != nullptr) {
743 #if 0
744       object_->add_new_edge(v, prev_v);
745 #endif
746       bmsh3d_edge* edge = new  bmsh3d_edge(prev_v, v, 100);
747       bmsh3d_halfedge *he = new bmsh3d_halfedge (edge, inner_face);
748       inner_face->_connect_HE_to_end(he);
749     }
750     else {
751       v_first = v;
752     }
753     prev_v = v;
754   }
755   // add an edge between vertices (0, n-1)
756   bmsh3d_edge* edge = new  bmsh3d_edge(v_first, prev_v, 100);
757   bmsh3d_halfedge *he = new bmsh3d_halfedge (edge, inner_face);
758   inner_face->_connect_HE_to_end(he);
759 
760   return inner_face;
761 }
762 
763 //: Creates a polygon from the given vertex list and adds it to the mesh
create_face(vsol_polygon_3d_sptr polygon)764 bmsh3d_face_mc* bwm_observable_mesh::create_face(vsol_polygon_3d_sptr polygon)
765 {
766   polygon = bwm_algo::move_points_to_plane(polygon);
767   unsigned n = polygon->size();
768 
769   // create vertices
770   bmsh3d_vertex* prev_v = nullptr;
771   for (unsigned i=0; i<n; i++) {
772     double x = polygon->vertex(i)->x();
773     double y = polygon->vertex(i)->y();
774     double z = polygon->vertex(i)->z();
775     bmsh3d_vertex* v = (bmsh3d_vertex*) object_->_new_vertex ();
776     v->get_pt().set(x, y, z);
777     object_->_add_vertex(v);
778     if (prev_v != nullptr)
779       object_->add_new_edge (v, prev_v);
780     prev_v = v;
781   }
782   // add an edge between vertices (0, n-1)
783   object_->add_new_edge ((bmsh3d_vertex*) object_->vertexmap(0), (bmsh3d_vertex*) object_->vertexmap(n-1));
784 
785   // create a polygon, there is only one face
786   bmsh3d_face_mc* face = object_->_new_mc_face ();
787 #if 0
788   object_->_add_face(face);
789 #endif
790   for (unsigned i=0; i<n; i++) {
791     //bmsh3d_vertex* vertex = (bmsh3d_vertex*) object_->vertexmap(i);
792     _connect_F_E_end (face, object_->edgemap(i));
793   }
794   face->_sort_HEs_circular();
795   return face;
796 }
797 
798 // given a 3d point on the mesh, it finds the face that the point is on and returns the face index
799 // of that face. If the point is not close enough to the mesh, it returns -1.
find_closest_face(vgl_point_3d<double> point)800 int bwm_observable_mesh::find_closest_face(vgl_point_3d<double> point)
801 {
802   int index = -1;
803   double dmin = 1e26;
804   std::cout << "dmin=" << dmin << std::endl;
805   std::map<int, bmsh3d_face*>::iterator it = object_->facemap().begin();
806   std::map<int, vsol_polygon_3d_sptr> faces;
807 
808   for (; it != object_->facemap().end(); it++) {
809     bmsh3d_face_mc* face = (bmsh3d_face_mc*) (*it).second;
810     vgl_plane_3d<double> plane = get_plane(face->id());
811     double d = vgl_distance(vgl_point_3d<double> (point), plane);
812     if (d < dmin) {
813       dmin = d;
814       index = face->id();
815     }
816     std::cout << face->id() << " dmin=" << dmin << std::endl;
817   }
818   return index;
819 }
820 
create_mesh_HE(vsol_polygon_3d_sptr polygon,double dist,std::map<int,vsol_polygon_3d_sptr> inner_faces)821 void bwm_observable_mesh::create_mesh_HE(vsol_polygon_3d_sptr polygon,
822                                          double dist,
823                                          std::map<int, vsol_polygon_3d_sptr> inner_faces)
824 {
825   polygon = bwm_algo::move_points_to_plane(polygon);
826 
827   unsigned n = polygon->size();
828 
829   std::vector<bmsh3d_vertex* > v_list(2*n);
830   unsigned int next_index;
831   // unsigned int next_index_ext; // unused
832 
833   // first create the vertices
834   for (unsigned i=0; i<n; i++) {
835     bmsh3d_vertex* v = (bmsh3d_vertex*) object_->_new_vertex ();
836     v->set_pt (vgl_point_3d<double> (polygon->vertex(i)->x(),
837                                      polygon->vertex(i)->y(), polygon->vertex(i)->z()));
838     object_->_add_vertex (v);
839     v_list[i] = v;
840   }
841 
842   // create the extruded vertices
843   for (unsigned i=0; i<n; i++) {
844     bmsh3d_vertex* v = (bmsh3d_vertex*) object_->_new_vertex ();
845 #if 0 //JLM
846     vsol_point_3d p(v->get_pt());
847     vsol_point_3d_sptr p = polygon->vertex(i);
848     vgl_vector_3d<double> normal_at_point = polygon->normal_at_point(p);
849     vgl_vector_3d<double> normal = polygon->normal();
850     double fact = dist;
851     v->set_pt(vgl_point_3d<double>(polygon->vertex(i)->x() + fact*normal.x(),
852                                    polygon->vertex(i)->y() + fact*normal.y(),
853                                    polygon->vertex(i)->z() + fact*normal.z()));
854 #endif // 0
855     v->set_pt (vgl_point_3d<double> (polygon->vertex(i)->x(),
856                                      polygon->vertex(i)->y(),
857                                      polygon->vertex(i)->z()+ dist));
858     object_->_add_vertex (v);
859     v_list[n+i] = v;
860   }
861 
862   // create the edges of parallel faces
863   std::vector<bmsh3d_edge* > e_list(2*n);
864   for (unsigned i=0; i<2*n; i++) {
865     next_index = i + 1;
866     if (next_index == n)
867       next_index = 0;
868     else if (next_index == 2*n)
869       next_index = n;
870     bmsh3d_edge* e = object_->add_new_edge (v_list[i], v_list[next_index]);
871     e_list[i] = e;
872   }
873 
874   // create the first face for z=0
875   bmsh3d_face_mc* f0 = object_->_new_mc_face ();
876   object_->_add_face (f0);
877   for (unsigned i=0; i<n; i++) {
878     _connect_F_E_end(f0, e_list[i]);
879   }
880 
881   // re-attach the inner faces
882   std::map<int, vsol_polygon_3d_sptr>::iterator iter = inner_faces.begin();
883   while (iter != inner_faces.end()) {
884     attach_inner_face(f0->id(), iter->second);
885     iter++;
886   }
887 
888   // create the second face for z=ext_value
889   bmsh3d_face_mc* f1 = object_->_new_mc_face ();
890   object_->_add_face (f1);
891   for (unsigned i=n; i<2*n; i++) {
892     _connect_F_E_end (f1, e_list[i]);
893   }
894   current_extr_face = f1;
895 
896   // create the in between edges and faces
897   std::vector<bmsh3d_edge* > e_btw_list(n);
898   for (unsigned i=0; i<n; i++) {
899     bmsh3d_edge* e = object_->add_new_edge (v_list[i], v_list[n+i]);
900     e_btw_list[i] = e;
901   }
902 
903   for (unsigned i=0; i<n; i++) {
904     // create 2 new edges
905     if (i == n-1) {
906       next_index = 0;
907       // next_index_ext = n;
908     }
909     else {
910       next_index = i+1;
911       // next_index_ext = n+i+1;
912     }
913     bmsh3d_face_mc* f = object_->_new_mc_face ();
914     object_->_add_face (f);
915     _connect_F_E_end (f, e_list[i]);
916     _connect_F_E_end (f, e_btw_list[next_index]);
917     _connect_F_E_end (f, e_list[n+i]);
918     _connect_F_E_end (f, e_btw_list[i]);
919   }
920 
921   print_faces();
922 }
923 
create_mesh_surface(std::vector<vgl_point_3d<double>> vertices,std::vector<vgl_point_3d<int>> triangles)924 void bwm_observable_mesh::create_mesh_surface(std::vector<vgl_point_3d<double> > vertices,
925                                               std::vector<vgl_point_3d<int> > triangles)
926 {
927   object_ = new bmsh3d_mesh_mc();
928   // create vertices
929   std::vector<bmsh3d_vertex* > v_list(vertices.size());
930 
931   // first create the vertices
932   for (unsigned i=0; i<vertices.size(); i++) {
933     bmsh3d_vertex* v = (bmsh3d_vertex*) object_->_new_vertex ();
934     v->set_pt (vgl_point_3d<double> (vertices[i].x(), vertices[i].y(), vertices[i].z()));
935     object_->_add_vertex (v);
936     v_list[i] = v;
937   }
938 
939   // create the triangles and edges
940   for (unsigned i=0; i<triangles.size(); i++) {
941     int index1 = triangles[i].x();
942     int index2 = triangles[i].y();
943     int index3 = triangles[i].z();
944     bmsh3d_edge* e1 = E_sharing_2V (v_list[index1], v_list[index2]);
945     if (!e1) {
946       e1 = object_->add_new_edge(v_list[index1], v_list[index2]);
947     }
948 
949     bmsh3d_edge* e2 = E_sharing_2V (v_list[index2], v_list[index3]);
950     if (!e2) {
951       e2 = object_->add_new_edge(v_list[index2], v_list[index3]);
952     }
953 
954     bmsh3d_edge* e3 = E_sharing_2V (v_list[index3], v_list[index1]);
955     if (!e3) {
956       e3 = object_->add_new_edge(v_list[index3], v_list[index1]);
957     }
958     bmsh3d_face_mc* f0 = object_->_new_mc_face ();
959     _connect_F_E_end(f0, e1);
960     _connect_F_E_end(f0, e2);
961     _connect_F_E_end(f0, e3);
962     object_->_add_face (f0);
963     f0->_sort_HEs_circular();
964   }
965 
966   send_update();
967 }
968 
attach_inner_face(unsigned face_id,vsol_polygon_3d_sptr poly)969 void bwm_observable_mesh::attach_inner_face(unsigned face_id, vsol_polygon_3d_sptr poly)
970 {
971   bmsh3d_face* inner_face = create_inner_face(poly);
972   bmsh3d_face_mc* outer_face = (bmsh3d_face_mc*) object_->facemap(face_id);
973   if (outer_face != nullptr) {
974     bmsh3d_halfedge* he = (bmsh3d_halfedge*) inner_face->halfedge();
975     outer_face->add_mc_halfedge(he);
976     notify_observers("update");
977   }
978   else {
979     std::cerr << "bwm_observable_mesh::attach_inner_face() -- outer face id is not valid\n";
980   }
981 }
982 
extrude_face(bmsh3d_mesh_mc * M,bmsh3d_face_mc * F)983 bmsh3d_face_mc* bwm_observable_mesh::extrude_face(bmsh3d_mesh_mc* M, bmsh3d_face_mc* F)
984 {
985   F->_sort_HEs_circular();
986   bmsh3d_face_mc* cur_face = F;
987 #if 0 // commented out
988   vgl_point_3d<double> center = F->compute_center_pt();
989   if (M->facemap().size() > 1)
990   {
991     std::vector<bmsh3d_edge*> inc_edges;
992     F->get_incident_edges (inc_edges);
993     bmsh3d_edge* first_edge = inc_edges[0];
994     vgl_vector_3d<double> face_normal = cur_face->compute_normal(center, first_edge, first_edge->s_vertex());
995     face_normal /= face_normal.length();
996     std::vector<bmsh3d_face*> incident_faces;
997     for (unsigned i=0; i<inc_edges.size(); i++) {
998       bmsh3d_edge* edge = inc_edges[i];
999       std::vector<bmsh3d_face*> faces;
1000       edge->get_incident_faces(faces);
1001 
1002       for (unsigned j=0; j<faces.size(); j++) {
1003         bmsh3d_face_mc* pair_face = (bmsh3d_face_mc*) faces[j];
1004         if (pair_face!=F) {
1005           pair_face->_sort_halfedges_circular();
1006           vgl_point_3d<double> pair_center = pair_face->compute_center_pt();
1007           vgl_vector_3d<double> n = pair_face->compute_normal(pair_center, edge, edge->s_vertex());
1008           n /= n.length();
1009           double a = angle(face_normal, n);
1010           double ninety_deg = vnl_math::pi/2.0;
1011           incident_faces.push_back(pair_face);
1012 #if 0
1013           // if both faces are on the same plane, they are planar
1014           if ((a == 0) || (a == vnl_math::pi))
1015             incident_faces.push_back(pair_face);
1016           else if ((a <= ninety_deg-0.05) || (a >= ninety_deg+0.05))
1017             incident_faces.push_back(pair_face);
1018 #endif // inner "#if 0"
1019         }
1020       }
1021     }
1022 
1023     for (unsigned i=0; i<incident_faces.size(); i++) {
1024       bmsh3d_face_mc* inc_face = (bmsh3d_face_mc*) incident_faces[i];
1025       // check with all the edges, if the incident face share this edge,
1026       //trying to find the edge between the current face and the given face
1027       std::vector<bmsh3d_edge*> inc_edges;
1028       bmsh3d_edge* edge;
1029       cur_face->get_incident_edges (inc_edges);
1030       for (unsigned j=0; j<inc_edges.size(); j++) {
1031         if (inc_edges[j]->is_face_incident(inc_face)) {
1032           edge = inc_edges[j];
1033           break;
1034         }
1035       }
1036 
1037       if (edge == 0) {
1038         std::cerr << "ERROR: incident face is not found in extrude_face()\n";
1039         return 0;
1040       }
1041 
1042       bmsh3d_halfedge* he = edge->incident_halfedge(cur_face);
1043       bmsh3d_vertex* v0 = (bmsh3d_vertex*) M->_new_vertex ();
1044       bmsh3d_vertex* s = (bmsh3d_vertex*) edge->s_vertex();
1045       bmsh3d_vertex* e = (bmsh3d_vertex*) edge->e_vertex();
1046       vgl_point_3d<double> p1 = s->get_pt();
1047       v0->get_pt().set(p1.x(), p1.y(), p1.z());
1048       bmsh3d_vertex* v1 = (bmsh3d_vertex*) M->_new_vertex ();
1049       vgl_point_3d<double> p2 = e->get_pt();
1050       v1->get_pt().set(p2.x(), p2.y(), p2.z());
1051       bmsh3d_face_mc *f1, *f2;
1052       bmsh3d_edge* next =  cur_face->find_other_edge(e, edge);
1053       bmsh3d_edge* prev = cur_face->find_other_edge(s, edge);
1054       mesh_break_face(M, cur_face, prev, next, v0, v1,  f1, f2);
1055       if (f1->containing_vertex(s))
1056         cur_face = f2;
1057       else
1058         cur_face = f1;
1059       this->print_faces();
1060     }
1061     // there is only one face, so we will extrude iT anyway
1062   }
1063   else
1064   {
1065     std::vector<bmsh3d_edge*> inc_edges;
1066     cur_face->get_incident_edges (inc_edges);
1067     for (unsigned j=0; j<inc_edges.size(); j++) {
1068       bmsh3d_edge* edge = inc_edges[j];
1069       bmsh3d_halfedge* he = edge->halfedge();
1070       bmsh3d_vertex* v0 = (bmsh3d_vertex*) M->_new_vertex ();
1071       bmsh3d_vertex* s = (bmsh3d_vertex*) edge->s_vertex();
1072       bmsh3d_vertex* e = (bmsh3d_vertex*) edge->e_vertex();
1073       vgl_point_3d<double> p1 = s->get_pt();
1074       v0->get_pt().set(p1.x(), p1.y(), p1.z());
1075       bmsh3d_vertex* v1 = (bmsh3d_vertex*) M->_new_vertex ();
1076       vgl_point_3d<double> p2 = e->get_pt();
1077       v1->get_pt().set(p2.x(), p2.y(), p2.z());
1078       bmsh3d_face_mc *f1, *f2;
1079       bmsh3d_edge* next =  cur_face->find_other_edge(e, edge);
1080       bmsh3d_edge* prev = cur_face->find_other_edge(s, edge);
1081       mesh_break_face(M, cur_face, prev, next, v0, v1, f1, f2);
1082       if (f1->containing_vertex(s))
1083         cur_face = f2;
1084       else
1085         cur_face = f1;
1086     }
1087   }
1088 #endif // 0
1089   std::vector<bmsh3d_vertex*> v_list;
1090   std::vector<bmsh3d_edge*> e_vert_list;
1091   bmsh3d_halfedge* he = (bmsh3d_halfedge*) cur_face->halfedge();
1092   bmsh3d_vertex* s = he->s_vertex();
1093   bmsh3d_vertex* v0 = (bmsh3d_vertex*) M->_new_vertex ();
1094   vgl_point_3d<double> p1 = s->get_pt();
1095   v0->get_pt().set(p1.x(), p1.y(), p1.z());
1096   M->_add_vertex (v0);
1097   bmsh3d_edge* edge = M->_new_edge(s,v0);
1098   e_vert_list.push_back(edge);
1099   v_list.push_back(v0);
1100 #if 0
1101   bmsh3d_vertex* v1 = (bmsh3d_vertex*) M->_new_vertex ();
1102   vgl_point_3d<double> p2 = e->get_pt();
1103   v1->get_pt().set(p2.x(), p2.y(), p2.z());
1104   v_list.push_back(v1);
1105 #endif // 0
1106   bmsh3d_halfedge* next = he->next();
1107   while (next != he) {
1108     bmsh3d_vertex* v = next->s_vertex();
1109     bmsh3d_vertex* v1 = (bmsh3d_vertex*) M->_new_vertex ();
1110     vgl_point_3d<double> p2 = v->get_pt();
1111     v1->get_pt().set(p2.x(), p2.y(), p2.z());
1112     v_list.push_back(v1);
1113     M->_add_vertex (v1);
1114     bmsh3d_edge* edge = M->_new_edge(v,v1);
1115     e_vert_list.push_back(edge);
1116     next = next->next();
1117   }
1118 
1119   // create th new top face
1120   std::vector<bmsh3d_edge* > e_hor_list;
1121   bmsh3d_face_mc* new_face = M->_new_mc_face();
1122   M->_add_face (new_face);
1123   for (unsigned i=0; i < v_list.size(); i++) {
1124     unsigned int next_index = i + 1;
1125     if (next_index == v_list.size())
1126       next_index = 0;
1127     bmsh3d_edge* e = M->add_new_edge (v_list[i], v_list[next_index]);
1128     e_hor_list.push_back(e);
1129     _connect_F_E_end (new_face, e);
1130   }
1131 
1132   // create the in between faces
1133   he = cur_face->halfedge();
1134   next = he;
1135   unsigned int i = 0, next_i = 1;
1136   do {
1137     bmsh3d_face_mc* face = M->_new_mc_face();
1138     M->_add_face (face);
1139     bmsh3d_edge* e = next->edge();
1140     if (i+1 == e_vert_list.size())
1141       next_i=0;
1142     else
1143       next_i = i+1;
1144     _connect_F_E_end (face, e_vert_list[i]);
1145     _connect_F_E_end (face, e_hor_list[i]);
1146     _connect_F_E_end (face, e_vert_list[next_i]);
1147     _connect_F_E_end (face, e);
1148     next = next->next();
1149     ++i;
1150   } while (next != he);
1151 
1152   new_face->_sort_HEs_circular();
1153   std::ostringstream oss;
1154   new_face->getInfo(oss);
1155 
1156   std::cout << oss.str().c_str();
1157   return new_face;
1158 }
1159 
get_plane(unsigned face_id)1160 vgl_plane_3d<double> bwm_observable_mesh::get_plane(unsigned face_id)
1161 {
1162   bmsh3d_face* face = object_->facemap(face_id);
1163   std::vector<bmsh3d_vertex*> vertices;
1164   face->get_ordered_Vs(vertices);
1165 
1166   std::vector<vsol_point_3d_sptr> points;
1167   vgl_fit_plane_3d<double> fitter;
1168   for (unsigned i=0; i<vertices.size(); i++) {
1169     bmsh3d_vertex* v = (bmsh3d_vertex*) vertices[i];
1170     vgl_homg_point_3d<double> hp(v->get_pt().x(), v->get_pt().y(), v->get_pt().z());
1171     fitter.add_point(hp);
1172   }
1173 
1174   vgl_plane_3d<double> plane;
1175 #if 0
1176   if (face->vertices().size()==0)
1177     return plane;
1178 #endif
1179   if (fitter.fit(0.0001, &std::cerr)) {
1180     plane = fitter.get_plane();
1181   }
1182   else {
1183     std::cout << "NO FITTING" << std::endl;
1184   }
1185 
1186   return plane;
1187 }
1188 
print_faces()1189 void bwm_observable_mesh::print_faces()
1190 {
1191   std::ostringstream oss;
1192   std::map<int, bmsh3d_face*>::iterator it = object_->facemap().begin();
1193 
1194   for (; it != object_->facemap().end(); it++) {
1195     bmsh3d_face_mc* face = (bmsh3d_face_mc*) (*it).second;
1196     //face->_sort_halfedges_circular();
1197     face->getInfo(oss);
1198   }
1199   std::cout << oss.str().c_str();
1200 }
1201 
move_points_to_plane(bmsh3d_face_mc * face)1202 void bwm_observable_mesh::move_points_to_plane(bmsh3d_face_mc* face)
1203 {
1204   bmsh3d_face* temp = object_->facemap(face->id());
1205   if (temp->vertices().size()==0)
1206     return;
1207   vgl_plane_3d<double> plane = get_plane(face->id());
1208 
1209   // find the closest point on the plane and replace it for each point
1210   std::vector<vsol_point_3d_sptr> points;
1211   for (unsigned i=0; i<face->vertices().size(); i++) {
1212     bmsh3d_vertex* v = (bmsh3d_vertex*) face->vertices(i);
1213     vgl_point_3d<double> hp(v->get_pt().x(), v->get_pt().y(), v->get_pt().z());
1214     vgl_point_3d<double> p = vgl_closest_point(plane, hp);
1215     v->set_pt (vgl_point_3d<double> (p.x(), p.y(), p.z()));
1216   }
1217 }
1218 
shrink_mesh(bmsh3d_mesh_mc * mesh,double r)1219 void bwm_observable_mesh::shrink_mesh(bmsh3d_mesh_mc* mesh, double r)
1220 {
1221   mesh->orient_face_normals();
1222 
1223   std::map<int, bmsh3d_vertex* > vertices = mesh->vertexmap();
1224   std::vector<vgl_point_3d<double> > new_vertices;
1225   std::map<int, bmsh3d_vertex* >::iterator v_it = vertices.begin();
1226   while (v_it != vertices.end()) {
1227     bmsh3d_vertex* vertex = (bmsh3d_vertex*) v_it->second;
1228     vgl_point_3d<double> p(vertex->get_pt());
1229     std::cout << "old vertex->" << p << std::endl;
1230     // find the faces incident to this vertex
1231     std::set<bmsh3d_face*> inc_faces;
1232     vertex->get_incident_Fs(inc_faces);
1233     if (inc_faces.size() < 3) {
1234       std::cerr << "The number of planes < 3!!!!!!!!!!!\n";
1235     }
1236 
1237     std::set<bmsh3d_face*>::iterator it = inc_faces.begin();
1238 
1239     while (it != inc_faces.end()) {
1240       bmsh3d_face_mc* face1 = (bmsh3d_face_mc*) *it;
1241       vgl_vector_3d<double> n1 = face1->compute_normal();
1242       n1 /= n1.length();
1243       it++;
1244 
1245       bmsh3d_face* face2 = (bmsh3d_face_mc*) *it;
1246       vgl_vector_3d<double> n2 = face2->compute_normal();
1247       n2 /= n2.length();
1248       it++;
1249 
1250       bmsh3d_face* face3 = (bmsh3d_face_mc*) *it;
1251       vgl_vector_3d<double> n3 = face3->compute_normal();
1252       n3 /= n3.length();
1253       it++;
1254       vgl_point_3d<double> v = bwm_algo::fit_sphere_to_corner(p, -1*n1, p, -1*n2, p , -1*n3, r);
1255       std::cout << "New vertex->" << v << std::endl;
1256       new_vertices.push_back(v);
1257     }
1258     v_it++;
1259   }
1260 
1261   //update the vertex values
1262 #ifdef DEBUG
1263   assert(vertices.size() == new_vertices.size());
1264 #endif
1265   v_it = vertices.begin();
1266   unsigned i=0;
1267   while (v_it != vertices.end()) {
1268     bmsh3d_vertex* v1 = (bmsh3d_vertex*) v_it->second;
1269     v1->set_pt(new_vertices[i++]);
1270     v_it++;
1271   }
1272 }
1273 
triangulate()1274 void bwm_observable_mesh::triangulate()
1275 {
1276   //object_->build_IFS_mesh();
1277   bmsh3d_mesh* tri_mesh = generate_tri_mesh(object_);
1278   tri_mesh->IFS_to_MHE();
1279   bmsh3d_mesh_mc* tri_mesh_mc = new bmsh3d_mesh_mc(tri_mesh);
1280   delete object_;
1281   object_ = tri_mesh_mc;
1282   object_->orient_face_normals();
1283   //delete tri_mesh;
1284   notify_observers("update");
1285 }
1286 
global_to_local(vpgl_lvcs * lvcs,double & min_z)1287 bwm_observable_sptr bwm_observable_mesh::global_to_local(vpgl_lvcs* lvcs, double& min_z)
1288 {
1289   if (lvcs) {
1290     bmsh3d_mesh_mc* mesh = object_->clone();
1291     std::map<int, bmsh3d_vertex*>::iterator vit;
1292     for (vit = mesh->vertexmap().begin(); vit!= mesh->vertexmap().end(); vit++) {
1293       bmsh3d_vertex* v = (bmsh3d_vertex*)vit->second;
1294       double x,y,z;
1295       lvcs->global_to_local(v->pt().x(), v->pt().y(), v->pt().z(),
1296                             vpgl_lvcs::wgs84,x,y,z,
1297                             vpgl_lvcs::DEG,vpgl_lvcs::METERS);
1298       if (z < min_z) {
1299         min_z = z;
1300       }
1301     }
1302     return new bwm_observable_mesh(mesh);
1303   }
1304   return nullptr;
1305 }
1306 
1307 #if 0
1308 SoSeparator* bwm_observable_mesh::convert_coin3d(bool b_shape_hints,
1309                                                  float transp,
1310                                                  int colorcode)
1311 {
1312   if (! object_->is_MHE())
1313     object_->IFS_to_MHE();
1314   object_->orient_face_normals();
1315   object_->build_face_IFS ();
1316   SoSeparator* mesh = draw_M (object_, b_shape_hints, transp, colorcode);
1317   mesh->ref();
1318   return mesh;
1319 }
1320 #endif
1321 
load_from(std::string filename)1322 bool bwm_observable_mesh::load_from(std::string filename)
1323 {
1324   std::string msg = "new";
1325   if (object_) {
1326     delete object_;
1327     msg = "update";
1328   }
1329 
1330   object_ = new bmsh3d_mesh_mc();
1331   if (!bmsh3d_load_ply(object_,filename.data())) {
1332     std::cerr << "Error loading mesh from " << filename << '\n';
1333     return false;
1334   }
1335 
1336   // build half-edge structure
1337   object_->IFS_to_MHE();
1338   object_->orient_face_normals();
1339   notify_observers(msg);
1340   return true;
1341 }
1342 
save(const char * filename,vpgl_lvcs * lvcs)1343 void bwm_observable_mesh::save(const char* filename, vpgl_lvcs* lvcs)
1344 {
1345   object_->build_IFS_mesh();
1346   bmsh3d_mesh* mesh2 = object_->clone();
1347 
1348   if (!lvcs) {
1349     std::cerr << "error: lvcs == null\n";
1350     return;
1351   }
1352 
1353   std::map<int, bmsh3d_vertex*>::iterator it = mesh2->vertexmap().begin();
1354   for (; it != mesh2->vertexmap().end(); it++) {
1355     bmsh3d_vertex* V = (bmsh3d_vertex*) (*it).second;
1356     double x=0,y=0,z=0;
1357     lvcs->global_to_local(V->pt().x(),V->pt().y(),V->pt().z(),vpgl_lvcs::wgs84,x,y,z,vpgl_lvcs::DEG,vpgl_lvcs::METERS);
1358     vgl_point_3d<double> new_pt(x,y,z);
1359     std::cout << "converted global <"<<V->pt().x() <<", "<< V->pt().y()
1360              <<", "<< V->pt().z() <<"> to <" <<x<< ", "<<y<<" ,"<<z<<'>'<<std::endl;
1361     V->set_pt(new_pt);
1362   }
1363 
1364   mesh2->build_IFS_mesh();
1365   bmsh3d_save_ply2(mesh2, filename);
1366   return;
1367 }
1368 
save(const char * filename)1369 void bwm_observable_mesh::save(const char* filename)
1370 {
1371   //object_->build_IFS_mesh();
1372   bmsh3d_mesh* mesh2 = object_->clone();
1373 
1374   mesh2->build_IFS_mesh();
1375   std::string comment;
1376   if (this->mesh_type_ == BWM_MESH_FEATURE)
1377     comment = BWM_MESH_FEATURE_STR;
1378   else if (this->mesh_type_ == BWM_MESH_IMAGE_PROCESSING)
1379     comment = BWM_MESH_IMAGE_PROCESSING_STR;
1380   else if (this->mesh_type_ == BWM_MESH_TERRAIN)
1381     comment = BWM_MESH_TERRAIN_STR;
1382   else {
1383     comment = "";
1384     std::cerr << "Mesh type is invalid\n";
1385   }
1386 
1387   bmsh3d_save_ply(mesh2, filename, true, comment);
1388   return;
1389 }
1390