53 # pragma warning(disable: 4267 4311) 60 #include <QApplication> 62 #include <QFileDialog> 63 #include <QDataStream> 65 #include <OpenMesh/Core/IO/MeshIO.hh> 66 #include <OpenMesh/Core/IO/BinaryHelper.hh> 67 #include <OpenMesh/Core/Utils/Endian.hh> 69 #include <OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh> 80 VDPMSynthesizerViewerWidget::VDPMSynthesizerViewerWidget(QWidget* _parent,
const char* _name)
83 adaptive_mode_ =
true;
86 VDPMSynthesizerViewerWidget::~VDPMSynthesizerViewerWidget()
92 VDPMSynthesizerViewerWidget::
93 draw_scene(
const std::string &_draw_mode)
95 if (adaptive_mode_ ==
true)
97 adaptive_refinement();
104 VDPMSynthesizerViewerWidget::
105 adaptive_refinement()
107 update_viewing_parameters();
109 VDPMMesh::HalfedgeHandle v0v1;
111 float fovy = viewing_parameters_.fovy();
113 float tolerance_square = viewing_parameters_.tolerance_square();
114 float tan_value = tanf(fovy / 2.0f);
116 kappa_square_ = 4.0f * tan_value * tan_value * tolerance_square;
120 for ( vfront_.begin(); !vfront_.end(); )
123 node_handle = vfront_.node_handle(),
124 parent_handle = vhierarchy_.parent_handle(node_handle);
126 if (vhierarchy_.is_leaf_node(node_handle) !=
true &&
127 qrefine(node_handle) ==
true)
129 force_vsplit(node_handle);
131 else if (vhierarchy_.is_root_node(node_handle) !=
true &&
132 ecol_legal(parent_handle, v0v1) ==
true &&
133 qrefine(parent_handle) !=
true)
135 ecol(parent_handle, v0v1);
144 mesh_.garbage_collection(
false,
true,
true);
150 VDPMSynthesizerViewerWidget::
154 Vec3f p = mesh_.point(node.vertex_handle());
155 Vec3f eye_dir = p - viewing_parameters_.eye_pos();;
157 float distance = eye_dir.
length();
158 float distance2 = distance * distance;
159 float product_value = dot(eye_dir, node.normal());
161 if (outside_view_frustum(p, node.radius()) ==
true)
164 if (oriented_away(node.sin_square(), distance2, product_value) ==
true)
167 if (screen_space_error(node.mue_square(),
170 product_value) ==
true)
178 VDPMSynthesizerViewerWidget::
183 get_active_cuts(node_handle, vl, vr);
187 force_vsplit(mesh_.data(vl).vhierarchy_node_handle());
188 get_active_cuts(node_handle, vl, vr);
191 vsplit(node_handle, vl, vr);
197 VDPMSynthesizerViewerWidget::
204 lchild_handle = vhierarchy_.lchild_handle(_node_handle),
205 rchild_handle = vhierarchy_.rchild_handle(_node_handle);
211 mesh_.set_normal(v0, vhierarchy_.normal(lchild_handle));
212 mesh_.set_normal(v1, vhierarchy_.normal(rchild_handle));
213 mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
214 mesh_.data(v1).set_vhierarchy_node_handle(rchild_handle);
215 mesh_.status(v0).set_deleted(
false);
216 mesh_.status(v1).set_deleted(
false);
218 vfront_.remove(_node_handle);
219 vfront_.add(lchild_handle);
220 vfront_.add(rchild_handle);
225 VDPMSynthesizerViewerWidget::
229 lchild_handle = vhierarchy_.lchild_handle(_node_handle),
230 rchild_handle = vhierarchy_.rchild_handle(_node_handle);
236 mesh_.collapse(v0v1);
237 mesh_.set_normal(v1, vhierarchy_.normal(_node_handle));
238 mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
239 mesh_.data(v1).set_vhierarchy_node_handle(_node_handle);
240 mesh_.status(v0).set_deleted(
false);
241 mesh_.status(v1).set_deleted(
false);
243 vfront_.add(_node_handle);
244 vfront_.remove(lchild_handle);
245 vfront_.remove(rchild_handle);
250 VDPMSynthesizerViewerWidget::
254 lchild_handle = vhierarchy_.lchild_handle(_parent_handle),
255 rchild_handle = vhierarchy_.rchild_handle(_parent_handle);
258 if ( vfront_.is_active(lchild_handle) !=
true ||
259 vfront_.is_active(rchild_handle) !=
true)
264 v0 = vhierarchy_.vertex_handle(lchild_handle);
265 v1 = vhierarchy_.vertex_handle(rchild_handle);
267 v0v1 = mesh_.find_halfedge(v0, v1);
269 return mesh_.is_collapse_ok(v0v1);
273 VDPMSynthesizerViewerWidget::
282 fund_lcut_index = vhierarchy_.fund_lcut_index(_node_handle),
283 fund_rcut_index = vhierarchy_.fund_rcut_index(_node_handle);
285 vl = VDPMMesh::InvalidVertexHandle;
286 vr = VDPMMesh::InvalidVertexHandle;
288 for (vv_it=mesh_.vv_iter(vhierarchy_.vertex_handle(_node_handle));
289 vv_it.is_valid(); ++vv_it)
291 nnode_handle = mesh_.data(*vv_it).vhierarchy_node_handle();
292 nnode_index = vhierarchy_.node_index(nnode_handle);
294 if (vl == VDPMMesh::InvalidVertexHandle &&
295 vhierarchy_.is_ancestor(nnode_index, fund_lcut_index) ==
true)
298 if (vr == VDPMMesh::InvalidVertexHandle &&
299 vhierarchy_.is_ancestor(nnode_index, fund_rcut_index) ==
true)
307 if (vl != VDPMMesh::InvalidVertexHandle &&
308 vr != VDPMMesh::InvalidVertexHandle)
315 VDPMSynthesizerViewerWidget::
316 outside_view_frustum(
const Vec3f &pos,
float radius)
320 (frustum_plane_[0].signed_distance(pos) < -radius) ||
321 (frustum_plane_[1].signed_distance(pos) < -radius) ||
322 (frustum_plane_[2].signed_distance(pos) < -radius) ||
323 (frustum_plane_[3].signed_distance(pos) < -radius);
328 viewing_parameters_.frustum_planes(frustum_plane);
330 for (
int i = 0; i < 4; i++) {
331 if (frustum_plane[i].singed_distance(pos) < -radius)
339 VDPMSynthesizerViewerWidget::
340 oriented_away(
float sin_square,
float distance_square,
float product_value)
343 return (product_value > 0)
344 && ((product_value * product_value) > (distance_square * sin_square));
346 if (product_value > 0 &&
347 product_value * product_value > distance_square * sin_square)
356 VDPMSynthesizerViewerWidget::
357 screen_space_error(
float mue_square,
float sigma_square,
358 float distance_square,
float product_value)
361 float ks_ds = kappa_square_ * distance_square;
362 float pv_pv = product_value * product_value;
363 return (mue_square >= ks_ds)
364 || (sigma_square*( distance_square - pv_pv) >= ks_ds*distance_square);
366 if ((mue_square >= kappa_square_ * distance_square) ||
367 (sigma_square * (distance_square - product_value * product_value) >= kappa_square_ * distance_square * distance_square))
375 VDPMSynthesizerViewerWidget::
376 open_vd_prog_mesh(
const char* _filename)
383 float radius, sin_square, mue_square, sigma_square;
384 VHierarchyNodeHandleContainer roots;
392 std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
394 std::ifstream ifs(_filename, std::ios::binary);
398 std::cerr <<
"read error\n";
403 bool swap = Endian::local() != Endian::LSB;
406 ifs.read(fileformat, 10); fileformat[10] =
'\0';
407 if (std::string(fileformat) != std::string(
"VDProgMesh"))
409 std::cerr <<
"Wrong file format.\n";
414 IO::restore(ifs, n_base_vertices_, swap);
415 IO::restore(ifs, n_base_faces_, swap);
416 IO::restore(ifs, n_details_, swap);
422 vhierarchy_.set_num_roots(n_base_vertices_);
425 for (i=0; i<n_base_vertices_; ++i)
427 IO::restore(ifs, p, swap);
428 IO::restore(ifs, radius, swap);
429 IO::restore(ifs, normal, swap);
430 IO::restore(ifs, sin_square, swap);
431 IO::restore(ifs, mue_square, swap);
432 IO::restore(ifs, sigma_square, swap);
435 node_index = vhierarchy_.generate_node_index(i, 1);
436 node_handle = vhierarchy_.add_node();
440 node.set_index(node_index);
441 node.set_vertex_handle(vertex_handle);
442 mesh_.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
444 node.set_radius(radius);
445 node.set_normal(normal);
446 node.set_sin_square(sin_square);
447 node.set_mue_square(mue_square);
448 node.set_sigma_square(sigma_square);
449 mesh_.set_normal(vertex_handle, normal);
451 index2handle_map[node_index] = node_handle;
452 roots.push_back(node_handle);
454 vfront_.init(roots, n_details_);
456 for (i=0; i<n_base_faces_; ++i)
458 IO::restore(ifs, fvi[0], swap);
459 IO::restore(ifs, fvi[1], swap);
460 IO::restore(ifs, fvi[2], swap);
462 mesh_.add_face(mesh_.vertex_handle(fvi[0]),
463 mesh_.vertex_handle(fvi[1]),
464 mesh_.vertex_handle(fvi[2]));
468 for (i=0; i<n_details_; ++i)
471 IO::restore(ifs, p, swap);
474 IO::restore(ifs, value, swap);
477 IO::restore(ifs, value, swap);
480 IO::restore(ifs, value, swap);
484 node_handle = index2handle_map[node_index];
485 vhierarchy_.make_children(node_handle);
491 node.set_fund_lcut(fund_lcut_index);
492 node.set_fund_rcut(fund_rcut_index);
495 lchild.set_vertex_handle(vertex_handle);
496 rchild.set_vertex_handle(node.vertex_handle());
498 index2handle_map[lchild.node_index()] = node.
lchild_handle();
499 index2handle_map[rchild.node_index()] = node.
rchild_handle();
502 IO::restore(ifs, radius, swap);
503 IO::restore(ifs, normal, swap);
504 IO::restore(ifs, sin_square, swap);
505 IO::restore(ifs, mue_square, swap);
506 IO::restore(ifs, sigma_square, swap);
507 lchild.set_radius(radius);
508 lchild.set_normal(normal);
509 lchild.set_sin_square(sin_square);
510 lchild.set_mue_square(mue_square);
511 lchild.set_sigma_square(sigma_square);
513 IO::restore(ifs, radius, swap);
514 IO::restore(ifs, normal, swap);
515 IO::restore(ifs, sin_square, swap);
516 IO::restore(ifs, mue_square, swap);
517 IO::restore(ifs, sigma_square, swap);
518 rchild.set_radius(radius);
519 rchild.set_normal(normal);
520 rchild.set_sin_square(sin_square);
521 rchild.set_mue_square(mue_square);
522 rchild.set_sigma_square(sigma_square);
531 VDPMMesh::ConstVertexIter
532 vIt(mesh_.vertices_begin()),
533 vEnd(mesh_.vertices_end());
537 bbMin = bbMax = mesh_.point(*vIt);
538 for (; vIt!=vEnd; ++vIt)
540 bbMin.minimize(mesh_.point(*vIt));
541 bbMax.maximize(mesh_.point(*vIt));
545 set_scene_pos(0.5f*(bbMin + bbMax), 0.5*(bbMin - bbMax).norm());
548 std::cerr << mesh_.n_vertices() <<
" vertices, " 549 << mesh_.n_edges() <<
" edge, " 550 << mesh_.n_faces() <<
" faces, " 551 << n_details_ <<
" detail vertices\n";
557 void VDPMSynthesizerViewerWidget::keyPressEvent(QKeyEvent* _event)
559 switch (_event->key())
570 viewing_parameters_.increase_tolerance();
571 std::cout <<
"Scree-space error tolerance^2 is increased by " 572 << viewing_parameters_.tolerance_square() << std::endl;
577 viewing_parameters_.decrease_tolerance();
578 std::cout <<
"Screen-space error tolerance^2 is decreased by " 579 << viewing_parameters_.tolerance_square() << std::endl;
584 adaptive_mode_ = !(adaptive_mode_);
585 std::cout <<
"Adaptive refinement mode is " 586 << (adaptive_mode_ ?
"on" :
"off") << std::endl;
591 qFilename_ = QFileDialog::getOpenFileName(0,
"",
"",
"*.spm");
592 open_vd_prog_mesh( qFilename_.toStdString().c_str() );
596 MeshViewerWidget::keyPressEvent( _event );
606 VDPMSynthesizerViewerWidget::
607 update_viewing_parameters()
609 viewing_parameters_.set_modelview_matrix(modelview_matrix());
610 viewing_parameters_.set_aspect((
float) width()/ (
float) height());
611 viewing_parameters_.set_fovy(fovy());
613 viewing_parameters_.update_viewing_configurations();
VHierarchyNodeHandle lchild_handle()
Returns handle to left child.
Handle for a vertex entity.
VHierarchyNodeHandle rchild_handle()
Returns handle to right child.
Kernel::Point Point
Coordinate type.
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
virtual void draw_scene(const std::string &_draw_mode)
inherited drawing method
HalfedgeHandle vertex_split(Point _v0_point, VertexHandle _v1, VertexHandle _vl, VertexHandle _vr)
Vertex Split: inverse operation to collapse().
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Kernel::VertexVertexIter VertexVertexIter
Circulator.
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
void update_face_normals()
Update normal vectors for all faces.