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