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_(false),
90 adaptive_mode_ =
true;
93 VDPMSynthesizerViewerWidget::~VDPMSynthesizerViewerWidget()
99 VDPMSynthesizerViewerWidget::
100 draw_scene(
const std::string &_draw_mode)
102 if (adaptive_mode_ ==
true)
104 adaptive_refinement();
111 VDPMSynthesizerViewerWidget::
112 adaptive_refinement()
114 update_viewing_parameters();
116 VDPMMesh::HalfedgeHandle v0v1;
118 float fovy = viewing_parameters_.fovy();
120 float tolerance_square = viewing_parameters_.tolerance_square();
121 float tan_value = tanf(fovy / 2.0f);
123 kappa_square_ = 4.0f * tan_value * tan_value * tolerance_square;
127 for ( vfront_.begin(); !vfront_.end(); )
130 node_handle = vfront_.node_handle(),
131 parent_handle = vhierarchy_.parent_handle(node_handle);
133 if (vhierarchy_.is_leaf_node(node_handle) !=
true &&
134 qrefine(node_handle) ==
true)
136 force_vsplit(node_handle);
138 else if (vhierarchy_.is_root_node(node_handle) !=
true &&
139 ecol_legal(parent_handle, v0v1) ==
true &&
140 qrefine(parent_handle) !=
true)
142 ecol(parent_handle, v0v1);
151 mesh_.garbage_collection(
false,
true,
true);
157 VDPMSynthesizerViewerWidget::
161 Vec3f p = mesh_.point(node.vertex_handle());
162 Vec3f eye_dir = p - viewing_parameters_.eye_pos();;
164 float distance = eye_dir.
length();
165 float distance2 = distance * distance;
166 float product_value = dot(eye_dir, node.normal());
168 if (outside_view_frustum(p, node.radius()) ==
true)
171 if (oriented_away(node.sin_square(), distance2, product_value) ==
true)
174 if (screen_space_error(node.mue_square(),
177 product_value) ==
true)
185 VDPMSynthesizerViewerWidget::
190 get_active_cuts(node_handle, vl, vr);
194 force_vsplit(mesh_.data(vl).vhierarchy_node_handle());
195 get_active_cuts(node_handle, vl, vr);
198 vsplit(node_handle, vl, vr);
204 VDPMSynthesizerViewerWidget::
211 lchild_handle = vhierarchy_.lchild_handle(_node_handle),
212 rchild_handle = vhierarchy_.rchild_handle(_node_handle);
218 mesh_.set_normal(v0, vhierarchy_.normal(lchild_handle));
219 mesh_.set_normal(v1, vhierarchy_.normal(rchild_handle));
220 mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
221 mesh_.data(v1).set_vhierarchy_node_handle(rchild_handle);
222 mesh_.status(v0).set_deleted(
false);
223 mesh_.status(v1).set_deleted(
false);
225 vfront_.remove(_node_handle);
226 vfront_.add(lchild_handle);
227 vfront_.add(rchild_handle);
232 VDPMSynthesizerViewerWidget::
236 lchild_handle = vhierarchy_.lchild_handle(_node_handle),
237 rchild_handle = vhierarchy_.rchild_handle(_node_handle);
243 mesh_.collapse(v0v1);
244 mesh_.set_normal(v1, vhierarchy_.normal(_node_handle));
245 mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
246 mesh_.data(v1).set_vhierarchy_node_handle(_node_handle);
247 mesh_.status(v0).set_deleted(
false);
248 mesh_.status(v1).set_deleted(
false);
250 vfront_.add(_node_handle);
251 vfront_.remove(lchild_handle);
252 vfront_.remove(rchild_handle);
257 VDPMSynthesizerViewerWidget::
261 lchild_handle = vhierarchy_.lchild_handle(_parent_handle),
262 rchild_handle = vhierarchy_.rchild_handle(_parent_handle);
265 if ( vfront_.is_active(lchild_handle) !=
true ||
266 vfront_.is_active(rchild_handle) !=
true)
271 v0 = vhierarchy_.vertex_handle(lchild_handle);
272 v1 = vhierarchy_.vertex_handle(rchild_handle);
274 v0v1 = mesh_.find_halfedge(v0, v1);
276 return mesh_.is_collapse_ok(v0v1);
280 VDPMSynthesizerViewerWidget::
289 fund_lcut_index = vhierarchy_.fund_lcut_index(_node_handle),
290 fund_rcut_index = vhierarchy_.fund_rcut_index(_node_handle);
292 vl = VDPMMesh::InvalidVertexHandle;
293 vr = VDPMMesh::InvalidVertexHandle;
295 for (vv_it=mesh_.vv_iter(vhierarchy_.vertex_handle(_node_handle));
296 vv_it.is_valid(); ++vv_it)
298 nnode_handle = mesh_.data(*vv_it).vhierarchy_node_handle();
299 nnode_index = vhierarchy_.node_index(nnode_handle);
301 if (vl == VDPMMesh::InvalidVertexHandle &&
302 vhierarchy_.is_ancestor(nnode_index, fund_lcut_index) ==
true)
305 if (vr == VDPMMesh::InvalidVertexHandle &&
306 vhierarchy_.is_ancestor(nnode_index, fund_rcut_index) ==
true)
314 if (vl != VDPMMesh::InvalidVertexHandle &&
315 vr != VDPMMesh::InvalidVertexHandle)
322 VDPMSynthesizerViewerWidget::
323 outside_view_frustum(
const Vec3f &pos,
float radius)
327 (frustum_plane_[0].signed_distance(pos) < -radius) ||
328 (frustum_plane_[1].signed_distance(pos) < -radius) ||
329 (frustum_plane_[2].signed_distance(pos) < -radius) ||
330 (frustum_plane_[3].signed_distance(pos) < -radius);
335 viewing_parameters_.frustum_planes(frustum_plane);
337 for (
int i = 0; i < 4; i++) {
338 if (frustum_plane[i].singed_distance(pos) < -radius)
346 VDPMSynthesizerViewerWidget::
347 oriented_away(
float sin_square,
float distance_square,
float product_value)
350 return (product_value > 0)
351 && ((product_value * product_value) > (distance_square * sin_square));
353 if (product_value > 0 &&
354 product_value * product_value > distance_square * sin_square)
363 VDPMSynthesizerViewerWidget::
364 screen_space_error(
float mue_square,
float sigma_square,
365 float distance_square,
float product_value)
368 float ks_ds = kappa_square_ * distance_square;
369 float pv_pv = product_value * product_value;
370 return (mue_square >= ks_ds)
371 || (sigma_square*( distance_square - pv_pv) >= ks_ds*distance_square);
373 if ((mue_square >= kappa_square_ * distance_square) ||
374 (sigma_square * (distance_square - product_value * product_value) >= kappa_square_ * distance_square * distance_square))
382 VDPMSynthesizerViewerWidget::
383 open_vd_prog_mesh(
const char* _filename)
390 float radius, sin_square, mue_square, sigma_square;
391 VHierarchyNodeHandleContainer roots;
399 std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
401 std::ifstream ifs(_filename, std::ios::binary);
405 std::cerr <<
"read error\n";
410 bool swap = Endian::local() != Endian::LSB;
413 ifs.read(fileformat, 10); fileformat[10] =
'\0';
414 if (std::string(fileformat) != std::string(
"VDProgMesh"))
416 std::cerr <<
"Wrong file format.\n";
421 IO::restore(ifs, n_base_vertices_, swap);
422 IO::restore(ifs, n_base_faces_, swap);
423 IO::restore(ifs, n_details_, swap);
429 vhierarchy_.set_num_roots(n_base_vertices_);
432 for (i=0; i<n_base_vertices_; ++i)
434 IO::restore(ifs, p, swap);
435 IO::restore(ifs, radius, swap);
436 IO::restore(ifs, normal, swap);
437 IO::restore(ifs, sin_square, swap);
438 IO::restore(ifs, mue_square, swap);
439 IO::restore(ifs, sigma_square, swap);
442 node_index = vhierarchy_.generate_node_index(i, 1);
443 node_handle = vhierarchy_.add_node();
447 node.set_index(node_index);
448 node.set_vertex_handle(vertex_handle);
449 mesh_.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
451 node.set_radius(radius);
452 node.set_normal(normal);
453 node.set_sin_square(sin_square);
454 node.set_mue_square(mue_square);
455 node.set_sigma_square(sigma_square);
456 mesh_.set_normal(vertex_handle, normal);
458 index2handle_map[node_index] = node_handle;
459 roots.push_back(node_handle);
461 vfront_.init(roots, n_details_);
463 for (i=0; i<n_base_faces_; ++i)
465 IO::restore(ifs, fvi[0], swap);
466 IO::restore(ifs, fvi[1], swap);
467 IO::restore(ifs, fvi[2], swap);
469 mesh_.add_face(mesh_.vertex_handle(fvi[0]),
470 mesh_.vertex_handle(fvi[1]),
471 mesh_.vertex_handle(fvi[2]));
475 for (i=0; i<n_details_; ++i)
478 IO::restore(ifs, p, swap);
481 IO::restore(ifs, value, swap);
484 IO::restore(ifs, value, swap);
487 IO::restore(ifs, value, swap);
491 node_handle = index2handle_map[node_index];
492 vhierarchy_.make_children(node_handle);
498 node.set_fund_lcut(fund_lcut_index);
499 node.set_fund_rcut(fund_rcut_index);
502 lchild.set_vertex_handle(vertex_handle);
503 rchild.set_vertex_handle(node.vertex_handle());
505 index2handle_map[lchild.node_index()] = node.
lchild_handle();
506 index2handle_map[rchild.node_index()] = node.
rchild_handle();
509 IO::restore(ifs, radius, swap);
510 IO::restore(ifs, normal, swap);
511 IO::restore(ifs, sin_square, swap);
512 IO::restore(ifs, mue_square, swap);
513 IO::restore(ifs, sigma_square, swap);
514 lchild.set_radius(radius);
515 lchild.set_normal(normal);
516 lchild.set_sin_square(sin_square);
517 lchild.set_mue_square(mue_square);
518 lchild.set_sigma_square(sigma_square);
520 IO::restore(ifs, radius, swap);
521 IO::restore(ifs, normal, swap);
522 IO::restore(ifs, sin_square, swap);
523 IO::restore(ifs, mue_square, swap);
524 IO::restore(ifs, sigma_square, swap);
525 rchild.set_radius(radius);
526 rchild.set_normal(normal);
527 rchild.set_sin_square(sin_square);
528 rchild.set_mue_square(mue_square);
529 rchild.set_sigma_square(sigma_square);
538 VDPMMesh::ConstVertexIter
539 vIt(mesh_.vertices_begin()),
540 vEnd(mesh_.vertices_end());
544 bbMin = bbMax = mesh_.point(*vIt);
545 for (; vIt!=vEnd; ++vIt)
547 bbMin.minimize(mesh_.point(*vIt));
548 bbMax.maximize(mesh_.point(*vIt));
552 set_scene_pos(0.5f*(bbMin + bbMax), 0.5*(bbMin - bbMax).norm());
555 std::cerr << mesh_.n_vertices() <<
" vertices, " 556 << mesh_.n_edges() <<
" edge, " 557 << mesh_.n_faces() <<
" faces, " 558 << n_details_ <<
" detail vertices\n";
564 void VDPMSynthesizerViewerWidget::keyPressEvent(QKeyEvent* _event)
566 switch (_event->key())
577 viewing_parameters_.increase_tolerance();
578 std::cout <<
"Scree-space error tolerance^2 is increased by " 579 << viewing_parameters_.tolerance_square() << std::endl;
584 viewing_parameters_.decrease_tolerance();
585 std::cout <<
"Screen-space error tolerance^2 is decreased by " 586 << viewing_parameters_.tolerance_square() << std::endl;
591 adaptive_mode_ = !(adaptive_mode_);
592 std::cout <<
"Adaptive refinement mode is " 593 << (adaptive_mode_ ?
"on" :
"off") << std::endl;
598 qFilename_ = QFileDialog::getOpenFileName(0,
"",
"",
"*.spm");
599 open_vd_prog_mesh( qFilename_.toStdString().c_str() );
603 MeshViewerWidget::keyPressEvent( _event );
613 VDPMSynthesizerViewerWidget::
614 update_viewing_parameters()
616 viewing_parameters_.set_modelview_matrix(modelview_matrix());
617 viewing_parameters_.set_aspect((
float) width()/ (
float) height());
618 viewing_parameters_.set_fovy(fovy());
620 viewing_parameters_.update_viewing_configurations();
Kernel::VertexVertexIter VertexVertexIter
Circulator.
VHierarchyNodeHandle rchild_handle()
Returns handle to right child.
Kernel::Point Point
Coordinate type.
Handle for a vertex entity.
HalfedgeHandle vertex_split(Point _v0_point, VertexHandle _v1, VertexHandle _vl, VertexHandle _vr)
Vertex Split: inverse operation to collapse().
VHierarchyNodeHandle lchild_handle()
Returns handle to left child.
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
void update_face_normals()
Update normal vectors for all faces.
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.