58 # pragma warning(disable: 4267 4311)
65 #include <QApplication>
67 #include <QFileDialog>
68 #include <QDataStream>
77 #include <OpenMesh/Core/IO/MeshIO.hh>
78 #include <OpenMesh/Core/IO/BinaryHelper.hh>
79 #include <OpenMesh/Core/Utils/Endian.hh>
81 #include <OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh>
92 VDPMSynthesizerViewerWidget::VDPMSynthesizerViewerWidget(QWidget* _parent,
const char* _name)
95 adaptive_mode_ =
true;
98 VDPMSynthesizerViewerWidget::~VDPMSynthesizerViewerWidget()
104 VDPMSynthesizerViewerWidget::
105 draw_scene(
const std::string &_draw_mode)
107 if (adaptive_mode_ ==
true)
109 adaptive_refinement();
116 VDPMSynthesizerViewerWidget::
117 adaptive_refinement()
119 update_viewing_parameters();
121 VDPMMesh::HalfedgeHandle v0v1;
123 float fovy = viewing_parameters_.fovy();
125 float tolerance_square = viewing_parameters_.tolerance_square();
126 float tan_value = tanf(fovy / 2.0f);
128 kappa_square_ = 4.0f * tan_value * tan_value * tolerance_square;
132 for ( vfront_.begin(); !vfront_.end(); )
135 node_handle = vfront_.node_handle(),
136 parent_handle = vhierarchy_.parent_handle(node_handle);
138 if (vhierarchy_.is_leaf_node(node_handle) !=
true &&
139 qrefine(node_handle) ==
true)
141 force_vsplit(node_handle);
143 else if (vhierarchy_.is_root_node(node_handle) !=
true &&
144 ecol_legal(parent_handle, v0v1) ==
true &&
145 qrefine(parent_handle) !=
true)
147 ecol(parent_handle, v0v1);
156 mesh_.garbage_collection(
false,
true,
true);
162 VDPMSynthesizerViewerWidget::
163 qrefine(VHierarchyNodeHandle _node_handle)
165 VHierarchyNode &node = vhierarchy_.node(_node_handle);
166 Vec3f p = mesh_.point(node.vertex_handle());
167 Vec3f eye_dir = p - viewing_parameters_.eye_pos();;
169 float distance = eye_dir.length();
170 float distance2 = distance * distance;
171 float product_value =
dot(eye_dir, node.normal());
173 if (outside_view_frustum(p, node.radius()) ==
true)
176 if (oriented_away(node.sin_square(), distance2, product_value) ==
true)
179 if (screen_space_error(node.mue_square(),
182 product_value) ==
true)
190 VDPMSynthesizerViewerWidget::
191 force_vsplit(VHierarchyNodeHandle node_handle)
193 VDPMMesh::VertexHandle vl, vr;
195 get_active_cuts(node_handle, vl, vr);
199 force_vsplit(mesh_.data(vl).vhierarchy_node_handle());
200 get_active_cuts(node_handle, vl, vr);
203 vsplit(node_handle, vl, vr);
209 VDPMSynthesizerViewerWidget::
210 vsplit(VHierarchyNodeHandle _node_handle,
211 VDPMMesh::VertexHandle vl,
212 VDPMMesh::VertexHandle vr)
216 lchild_handle = vhierarchy_.lchild_handle(_node_handle),
217 rchild_handle = vhierarchy_.rchild_handle(_node_handle);
219 VDPMMesh::VertexHandle v0 = vhierarchy_.vertex_handle(lchild_handle);
220 VDPMMesh::VertexHandle v1 = vhierarchy_.vertex_handle(rchild_handle);
223 mesh_.set_normal(v0, vhierarchy_.normal(lchild_handle));
224 mesh_.set_normal(v1, vhierarchy_.normal(rchild_handle));
225 mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
226 mesh_.data(v1).set_vhierarchy_node_handle(rchild_handle);
227 mesh_.status(v0).set_deleted(
false);
228 mesh_.status(v1).set_deleted(
false);
230 vfront_.remove(_node_handle);
231 vfront_.add(lchild_handle);
232 vfront_.add(rchild_handle);
237 VDPMSynthesizerViewerWidget::
238 ecol(VHierarchyNodeHandle _node_handle,
const VDPMMesh::HalfedgeHandle& v0v1)
241 lchild_handle = vhierarchy_.lchild_handle(_node_handle),
242 rchild_handle = vhierarchy_.rchild_handle(_node_handle);
244 VDPMMesh::VertexHandle v0 = vhierarchy_.vertex_handle(lchild_handle);
245 VDPMMesh::VertexHandle v1 = vhierarchy_.vertex_handle(rchild_handle);
248 mesh_.collapse(v0v1);
249 mesh_.set_normal(v1, vhierarchy_.normal(_node_handle));
250 mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
251 mesh_.data(v1).set_vhierarchy_node_handle(_node_handle);
252 mesh_.status(v0).set_deleted(
false);
253 mesh_.status(v1).set_deleted(
false);
255 vfront_.add(_node_handle);
256 vfront_.remove(lchild_handle);
257 vfront_.remove(rchild_handle);
262 VDPMSynthesizerViewerWidget::
263 ecol_legal(VHierarchyNodeHandle _parent_handle, VDPMMesh::HalfedgeHandle& v0v1)
266 lchild_handle = vhierarchy_.lchild_handle(_parent_handle),
267 rchild_handle = vhierarchy_.rchild_handle(_parent_handle);
270 if ( vfront_.is_active(lchild_handle) !=
true ||
271 vfront_.is_active(rchild_handle) !=
true)
274 VDPMMesh::VertexHandle v0, v1;
276 v0 = vhierarchy_.vertex_handle(lchild_handle);
277 v1 = vhierarchy_.vertex_handle(rchild_handle);
279 v0v1 = mesh_.find_halfedge(v0, v1);
281 return mesh_.is_collapse_ok(v0v1);
285 VDPMSynthesizerViewerWidget::
286 get_active_cuts(
const VHierarchyNodeHandle _node_handle,
287 VDPMMesh::VertexHandle &vl, VDPMMesh::VertexHandle &vr)
289 VDPMMesh::VertexVertexIter vv_it;
290 VHierarchyNodeHandle nnode_handle;
294 fund_lcut_index = vhierarchy_.fund_lcut_index(_node_handle),
295 fund_rcut_index = vhierarchy_.fund_rcut_index(_node_handle);
297 vl = VDPMMesh::InvalidVertexHandle;
298 vr = VDPMMesh::InvalidVertexHandle;
300 for (vv_it=mesh_.vv_iter(vhierarchy_.vertex_handle(_node_handle));
301 vv_it.is_valid(); ++vv_it)
303 nnode_handle = mesh_.data(*vv_it).vhierarchy_node_handle();
304 nnode_index = vhierarchy_.node_index(nnode_handle);
306 if (vl == VDPMMesh::InvalidVertexHandle &&
307 vhierarchy_.is_ancestor(nnode_index, fund_lcut_index) ==
true)
310 if (vr == VDPMMesh::InvalidVertexHandle &&
311 vhierarchy_.is_ancestor(nnode_index, fund_rcut_index) ==
true)
319 if (vl != VDPMMesh::InvalidVertexHandle &&
320 vr != VDPMMesh::InvalidVertexHandle)
327 VDPMSynthesizerViewerWidget::
328 outside_view_frustum(
const Vec3f &pos,
float radius)
332 (frustum_plane_[0].signed_distance(pos) < -radius) ||
333 (frustum_plane_[1].signed_distance(pos) < -radius) ||
334 (frustum_plane_[2].signed_distance(pos) < -radius) ||
335 (frustum_plane_[3].signed_distance(pos) < -radius);
338 Plane3d frustum_plane[4];
340 viewing_parameters_.frustum_planes(frustum_plane);
342 for (
int i = 0; i < 4; i++) {
343 if (frustum_plane[i].singed_distance(pos) < -radius)
351 VDPMSynthesizerViewerWidget::
352 oriented_away(
float sin_square,
float distance_square,
float product_value)
355 return (product_value > 0)
356 && ((product_value * product_value) > (distance_square * sin_square));
358 if (product_value > 0 &&
359 product_value * product_value > distance_square * sin_square)
368 VDPMSynthesizerViewerWidget::
369 screen_space_error(
float mue_square,
float sigma_square,
370 float distance_square,
float product_value)
373 float ks_ds = kappa_square_ * distance_square;
374 float pv_pv = product_value * product_value;
375 return (mue_square >= ks_ds)
376 || (sigma_square*( distance_square - pv_pv) >= ks_ds*distance_square);
378 if ((mue_square >= kappa_square_ * distance_square) ||
379 (sigma_square * (distance_square - product_value * product_value) >= kappa_square_ * distance_square * distance_square))
387 VDPMSynthesizerViewerWidget::
388 open_vd_prog_mesh(
const char* _filename)
395 float radius, sin_square, mue_square, sigma_square;
396 VHierarchyNodeHandleContainer roots;
398 VHierarchyNodeIndex node_index;
399 VHierarchyNodeIndex lchild_node_index, rchild_node_index;
400 VHierarchyNodeIndex fund_lcut_index, fund_rcut_index;
401 VHierarchyNodeHandle node_handle;
402 VHierarchyNodeHandle lchild_node_handle, rchild_node_handle;
404 std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
406 std::ifstream ifs(_filename, std::ios::binary);
410 std::cerr <<
"read error\n";
415 bool swap = Endian::local() != Endian::LSB;
418 ifs.read(fileformat, 10); fileformat[10] =
'\0';
419 if (std::string(fileformat) != std::string(
"VDProgMesh"))
421 std::cerr <<
"Wrong file format.\n";
426 IO::restore(ifs, n_base_vertices_, swap);
427 IO::restore(ifs, n_base_faces_, swap);
428 IO::restore(ifs, n_details_, swap);
434 vhierarchy_.set_num_roots(n_base_vertices_);
437 for (i=0; i<n_base_vertices_; ++i)
439 IO::restore(ifs, p, swap);
440 IO::restore(ifs, radius, swap);
441 IO::restore(ifs, normal, swap);
442 IO::restore(ifs, sin_square, swap);
443 IO::restore(ifs, mue_square, swap);
444 IO::restore(ifs, sigma_square, swap);
447 node_index = vhierarchy_.generate_node_index(i, 1);
448 node_handle = vhierarchy_.add_node();
450 VHierarchyNode &node = vhierarchy_.node(node_handle);
452 node.set_index(node_index);
453 node.set_vertex_handle(vertex_handle);
454 mesh_.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
456 node.set_radius(radius);
457 node.set_normal(normal);
458 node.set_sin_square(sin_square);
459 node.set_mue_square(mue_square);
460 node.set_sigma_square(sigma_square);
461 mesh_.set_normal(vertex_handle, normal);
463 index2handle_map[node_index] = node_handle;
464 roots.push_back(node_handle);
466 vfront_.init(roots, n_details_);
468 for (i=0; i<n_base_faces_; ++i)
470 IO::restore(ifs, fvi[0], swap);
471 IO::restore(ifs, fvi[1], swap);
472 IO::restore(ifs, fvi[2], swap);
474 mesh_.add_face(mesh_.vertex_handle(fvi[0]),
475 mesh_.vertex_handle(fvi[1]),
476 mesh_.vertex_handle(fvi[2]));
480 for (i=0; i<n_details_; ++i)
483 IO::restore(ifs, p, swap);
486 IO::restore(ifs, value, swap);
487 node_index = VHierarchyNodeIndex(value);
489 IO::restore(ifs, value, swap);
490 fund_lcut_index = VHierarchyNodeIndex(value);
492 IO::restore(ifs, value, swap);
493 fund_rcut_index = VHierarchyNodeIndex(value);
496 node_handle = index2handle_map[node_index];
497 vhierarchy_.make_children(node_handle);
499 VHierarchyNode &node = vhierarchy_.node(node_handle);
500 VHierarchyNode &lchild = vhierarchy_.node(node.lchild_handle());
501 VHierarchyNode &rchild = vhierarchy_.node(node.rchild_handle());
503 node.set_fund_lcut(fund_lcut_index);
504 node.set_fund_rcut(fund_rcut_index);
507 lchild.set_vertex_handle(vertex_handle);
508 rchild.set_vertex_handle(node.vertex_handle());
510 index2handle_map[lchild.node_index()] = node.lchild_handle();
511 index2handle_map[rchild.node_index()] = node.rchild_handle();
514 IO::restore(ifs, radius, swap);
515 IO::restore(ifs, normal, swap);
516 IO::restore(ifs, sin_square, swap);
517 IO::restore(ifs, mue_square, swap);
518 IO::restore(ifs, sigma_square, swap);
519 lchild.set_radius(radius);
520 lchild.set_normal(normal);
521 lchild.set_sin_square(sin_square);
522 lchild.set_mue_square(mue_square);
523 lchild.set_sigma_square(sigma_square);
525 IO::restore(ifs, radius, swap);
526 IO::restore(ifs, normal, swap);
527 IO::restore(ifs, sin_square, swap);
528 IO::restore(ifs, mue_square, swap);
529 IO::restore(ifs, sigma_square, swap);
530 rchild.set_radius(radius);
531 rchild.set_normal(normal);
532 rchild.set_sin_square(sin_square);
533 rchild.set_mue_square(mue_square);
534 rchild.set_sigma_square(sigma_square);
543 VDPMMesh::ConstVertexIter
544 vIt(mesh_.vertices_begin()),
545 vEnd(mesh_.vertices_end());
549 bbMin = bbMax = mesh_.point(*vIt);
550 for (; vIt!=vEnd; ++vIt)
552 bbMin.minimize(mesh_.point(*vIt));
553 bbMax.maximize(mesh_.point(*vIt));
557 set_scene_pos(0.5f*(bbMin + bbMax), 0.5*(bbMin - bbMax).norm());
560 std::cerr << mesh_.n_vertices() <<
" vertices, "
561 << mesh_.n_edges() <<
" edge, "
562 << mesh_.n_faces() <<
" faces, "
563 << n_details_ <<
" detail vertices\n";
569 void VDPMSynthesizerViewerWidget::keyPressEvent(QKeyEvent* _event)
571 switch (_event->key())
582 viewing_parameters_.increase_tolerance();
583 std::cout <<
"Scree-space error tolerance^2 is increased by "
584 << viewing_parameters_.tolerance_square() << std::endl;
589 viewing_parameters_.decrease_tolerance();
590 std::cout <<
"Screen-space error tolerance^2 is decreased by "
591 << viewing_parameters_.tolerance_square() << std::endl;
596 adaptive_mode_ = !(adaptive_mode_);
597 std::cout <<
"Adaptive refinement mode is "
598 << (adaptive_mode_ ?
"on" :
"off") << std::endl;
603 qFilename_ = QFileDialog::getOpenFileName(0,
"",
"",
"*.spm");
604 open_vd_prog_mesh( qFilename_.toStdString().c_str() );
608 MeshViewerWidget::keyPressEvent( _event );
618 VDPMSynthesizerViewerWidget::
619 update_viewing_parameters()
621 viewing_parameters_.set_modelview_matrix(modelview_matrix());
622 viewing_parameters_.set_aspect((
float) width()/ (
float) height());
623 viewing_parameters_.set_fovy(fovy());
625 viewing_parameters_.update_viewing_configurations();
void swap(VectorT< Scalar, DIM > &_v1, VectorT< Scalar, DIM > &_v2) noexcept(noexcept(_v1.swap(_v2)))
Scalar dot(const VectorT< Scalar, N > &_v1, const VectorT< Scalar, N > &_v2)
Kernel::Point Point
Coordinate type.
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Handle for a vertex entity.
void update_face_normals()
Update normal vectors for all faces.
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().