Developer Documentation
OMPropertyVisualizerVectorT_impl.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
44 #define OM_PROPERTY_VISUALIZER_VECTOR_CC
45 
46 #include "OMPropertyVisualizerVector.hh"
47 #include <ACG/Utils/ColorConversion.hh>
48 
49 template <typename MeshT>
50 OMPropertyVisualizerVector<MeshT>::OMPropertyVisualizerVector(MeshT* _mesh, int _objectID, const PropertyInfo& _propertyInfo)
51  : OMPropertyVisualizer<MeshT>(_mesh, _objectID, _propertyInfo)
52 {
53  if (PropertyVisualizer::widget) delete PropertyVisualizer::widget;
54  VectorWidget* w = new VectorWidget();
55  w->paramVector->setTitle(QString("3D Vector Parameters of ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
56  PropertyVisualizer::widget = w;
57 
58  BaseObjectData *bod;
59  PluginFunctions::getObject(_objectID, bod);
60 
61  lineNode = new ACG::SceneGraph::LineNode( ACG::SceneGraph::LineNode::LineSegmentsMode, bod->baseNode());
62 
63  if (!_propertyInfo.isFaceProp())
64  {
65  w->vectors_edges_rb->hide();
66  }
67  this->connect(w->lineWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
68  [this](double value) {lineNode->set_line_width(value);});
69 }
70 
71 template <typename MeshT>
73 {
74  lineNode->clear();
76 }
77 
78 template <typename MeshT>
80 {
81  return OMPropertyVisualizer<MeshT>::template getPropertyText_<typename MeshT::Point>(index);
82 }
83 
84 
85 namespace {
86 
87 template<typename PROPTYPE, typename MeshT, typename ENTITY_IT, typename PROPINFO_TYPE>
88 void visualizeVectorAsColorForEntity(MeshT *mesh, const ENTITY_IT e_begin, const ENTITY_IT e_end,
89  const PROPINFO_TYPE &propinfo, bool normalized) {
90  PROPTYPE prop;
91  if (!mesh->get_property_handle(prop, propinfo.propName()))
92  throw VizException("Getting PropHandle from mesh for selected property failed.");
93  for (ENTITY_IT e_it = e_begin; e_it != e_end; ++e_it) {
94  using point_t = typename MeshT::Point;
95  point_t v = mesh->property(prop, *e_it);
96  if (normalized)
97  v = v.normalized() * 0.5 + point_t(0.5);
98  else
99  v = v.min(point_t(1, 1, 1)).max(point_t(0, 0, 0));
100  mesh->set_color(*e_it, typename MeshT::Color(v[0], v[1], v[2], 1.0));
101  }
102 }
103 
104 template<typename PROPTYPE, typename MeshT, typename ENTITY_IT, typename PROPINFO_TYPE>
105 void visualizeVectorLengthAsColorForEntity(
106  MeshT *mesh, const ENTITY_IT e_begin, const ENTITY_IT e_end,
107  const PROPINFO_TYPE &propinfo) {
108  PROPTYPE prop;
109  if (!mesh->get_property_handle(prop, propinfo.propName()))
110  throw VizException("Getting PropHandle from mesh for selected "
111  "property failed.");
112 
113  double min = std::numeric_limits<double>::infinity();
114  double max = -std::numeric_limits<double>::infinity();
115 
116  for (ENTITY_IT e_it = e_begin; e_it != e_end; ++e_it) {
117  const double val = mesh->property(prop, *e_it).norm();
118  min = std::min(min, val);
119  max = std::max(max, val);
120  }
121 
122  ACG::ColorCoder color_coder(min, max);
123 
124  for (ENTITY_IT e_it = e_begin; e_it != e_end; ++e_it) {
125  mesh->set_color(*e_it, color_coder(mesh->property(prop, *e_it).norm()));
126  }
127 }
128 
129 }
130 
131 template <typename MeshT>
133 {
134  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
135  if (w->vectors_edges_rb->isChecked()) {
136  visualizeFacePropOnEdges();
137  } else if (w->vectors_colors_rb->isChecked() ||
138  w->vectors_length_color_rb->isChecked()) {
139  if ( !OMPropertyVisualizer<MeshT>::mesh->has_face_colors() )
140  OMPropertyVisualizer<MeshT>::mesh->request_face_colors();
141 
142  if (w->vectors_colors_rb->isChecked()) {
143  visualizeVectorAsColorForEntity<OpenMesh::FPropHandleT<typename MeshT::Point> >(
145  OMPropertyVisualizer<MeshT>::mesh->faces_begin(),
146  OMPropertyVisualizer<MeshT>::mesh->faces_end(),
147  PropertyVisualizer::propertyInfo,
148  w->normalize_colors->isChecked());
149  } else {
150  visualizeVectorLengthAsColorForEntity<OpenMesh::FPropHandleT<typename MeshT::Point> >(
152  OMPropertyVisualizer<MeshT>::mesh->faces_begin(),
153  OMPropertyVisualizer<MeshT>::mesh->faces_end(),
154  PropertyVisualizer::propertyInfo);
155  }
156  if (_setDrawMode)
158  }
159  else visualizeFacePropAsStrokes();
160 }
161 
162 template <typename MeshT>
164 {
165  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
166  if (w->vectors_colors_rb->isChecked() ||
167  w->vectors_length_color_rb->isChecked()) {
168  if ( !OMPropertyVisualizer<MeshT>::mesh->has_edge_colors() )
169  OMPropertyVisualizer<MeshT>::mesh->request_edge_colors();
170  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
171  if ( !mesh->has_edge_colors() )
172  mesh->request_edge_colors();
173  if (w->vectors_colors_rb->isChecked()) {
174  visualizeVectorAsColorForEntity<
176  mesh,
177  mesh->edges_begin(),
178  mesh->edges_end(),
179  PropertyVisualizer::propertyInfo,
180  w->normalize_colors->isChecked());
181  } else {
182  visualizeVectorLengthAsColorForEntity<
184  mesh,
185  mesh->edges_begin(),
186  mesh->edges_end(),
187  PropertyVisualizer::propertyInfo);
188  }
189  if (_setDrawMode)
191  }
192  else visualizeEdgePropAsStrokes();
193 }
194 
195 template <typename MeshT>
197 {
198  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
199  if (w->vectors_colors_rb->isChecked() ||
200  w->vectors_length_color_rb->isChecked()) {
201  if ( !OMPropertyVisualizer<MeshT>::mesh->has_halfedge_colors() )
202  OMPropertyVisualizer<MeshT>::mesh->request_halfedge_colors();
203  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
204  if ( ! mesh->has_halfedge_colors() )
205  mesh->request_halfedge_colors();
206 
207  if (w->vectors_colors_rb->isChecked()) {
208  visualizeVectorAsColorForEntity<
210  mesh,
211  mesh->halfedges_begin(),
212  mesh->halfedges_end(),
213  PropertyVisualizer::propertyInfo,
214  w->normalize_colors->isChecked());
215  } else {
216  visualizeVectorLengthAsColorForEntity<
218  mesh,
219  mesh->halfedges_begin(),
220  mesh->halfedges_end(),
221  PropertyVisualizer::propertyInfo);
222  }
223 
224  if (_setDrawMode)
225  this->setDrawMode(
227  }
228  else visualizeHalfedgePropAsStrokes();
229 }
230 
231 template <typename MeshT>
233 {
234  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
235  if (w->vectors_colors_rb->isChecked() ||
236  w->vectors_length_color_rb->isChecked()) {
237  if ( !OMPropertyVisualizer<MeshT>::mesh->has_vertex_colors() )
238  OMPropertyVisualizer<MeshT>::mesh->request_vertex_colors();
239 
240  if (w->vectors_colors_rb->isChecked()) {
241  visualizeVectorAsColorForEntity<
244  OMPropertyVisualizer<MeshT>::mesh->vertices_begin(),
245  OMPropertyVisualizer<MeshT>::mesh->vertices_end(),
246  PropertyVisualizer::propertyInfo,
247  w->normalize_colors->isChecked());
248  } else {
249  visualizeVectorLengthAsColorForEntity<
252  OMPropertyVisualizer<MeshT>::mesh->vertices_begin(),
253  OMPropertyVisualizer<MeshT>::mesh->vertices_end(),
254  PropertyVisualizer::propertyInfo);
255  }
256  if (_setDrawMode)
257  this->setDrawMode(
259  }
260  else visualizeVertexPropAsStrokes();
261 }
262 
263 template <typename MeshT>
265 
266  VectorWidget* w = (VectorWidget*)PropertyVisualizer::widget;
267  MeshT* _mesh = OMPropertyVisualizer<MeshT>::mesh;
268 
269 
270  const double thresh_1 = w->vectors_edges_alpha->value();
271  const double thresh_2 = std::min(thresh_1, w->vectors_edges_alpha->value());
272 
274  if (!_mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName()))
275  throw VizException("Getting PropHandle from mesh for selected property failed.");
276 
277  if (!_mesh->has_edge_colors())
278  _mesh->request_edge_colors();
279  const ACG::Vec4f cold(0, 0, 0, 1.0), hot(0, 1, 0, 1.0), degen(1, 1, 0, 1.0);
280  for (typename MeshT::EdgeIter e_it = _mesh->edges_begin(), e_end = _mesh->edges_end();
281  e_it != e_end; ++e_it) {
282  typename MeshT::Point p1 = _mesh->property(prop, _mesh->face_handle(_mesh->halfedge_handle(*e_it, 0)));
283  typename MeshT::Point p2 = _mesh->property(prop, _mesh->face_handle(_mesh->halfedge_handle(*e_it, 1)));
284 
285  ACG::Vec4f color;
286 
287  const char degenerate = ((p1.sqrnorm() < 1e-6) ? 1 : 0) | ((p2.sqrnorm() < 1e-6) ? 2 : 0);
288  if (degenerate == 3) {
289  color = cold;
290  } else if (degenerate == 0) {
291  p1.normalize(); p2.normalize();
292  const double alpha = std::min(1.0, std::abs(p1 | p2));
293  if (alpha < thresh_1)
294  color = hot;
295  else if (alpha > thresh_2)
296  color = cold;
297  else {
298  const double beta = (alpha - thresh_1) / (thresh_2 - thresh_1);
299  color = cold * beta + hot * (1.0 - beta);
300  }
301  } else {
302  color = degen;
303  }
304  _mesh->set_color(*e_it, color);
305  }
307 }
308 
309 template <typename MeshT>
311  {
312  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
313 
314  lineNode->clear();
315 
316  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
317 
319 
320  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
321  return;
322 
323  for (typename MeshT::FaceIter f_it = OMPropertyVisualizer<MeshT>::mesh->faces_begin() ; f_it != OMPropertyVisualizer<MeshT>::mesh->faces_end() ; ++f_it){
324 
325  typename MeshT::Point center(0.0, 0.0, 0.0);
326  int vCount = 0;
327 
328  for (typename MeshT::FaceVertexIter fv_it(*(OMPropertyVisualizer<MeshT>::mesh),*f_it); fv_it.is_valid(); ++fv_it){
329  vCount++;
330  center += OMPropertyVisualizer<MeshT>::mesh->point(*fv_it);
331  }
332 
333  center /= vCount;
334 
335  typename MeshT::Point v = (OMPropertyVisualizer<MeshT>::mesh->property(prop, *f_it));
336 
337  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
338  v.normalize();
339 
340  if(vectorWidget->scale->isChecked())
341  v *= vectorWidget->scaleBox->value();
342 
343  lineNode->add_line( center, (center+v) );
344  lineNode->add_color(color);
345  }
346 }
347 
348 template <typename MeshT>
350 {
351  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
352 
353  lineNode->clear();
354 
355  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
356 
357  //TODO check if this also works if the property is Vec3f
359 
360  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
361  return;
362 
363  for (typename MeshT::EdgeIter e_it = OMPropertyVisualizer<MeshT>::mesh->edges_begin() ; e_it != OMPropertyVisualizer<MeshT>::mesh->edges_end() ; ++e_it){
364 
365  typename MeshT::HalfedgeHandle hh = OMPropertyVisualizer<MeshT>::mesh->halfedge_handle( *e_it, 0 );
366 
367  typename MeshT::VertexHandle vh0 = OMPropertyVisualizer<MeshT>::mesh->from_vertex_handle( hh );
368  typename MeshT::VertexHandle vh1 = OMPropertyVisualizer<MeshT>::mesh->to_vertex_handle( hh );
369 
370  typename MeshT::Point v1 = OMPropertyVisualizer<MeshT>::mesh->point(vh0) + 0.5 * (OMPropertyVisualizer<MeshT>::mesh->point(vh1) - OMPropertyVisualizer<MeshT>::mesh->point(vh0));
371  typename MeshT::Point v = OMPropertyVisualizer<MeshT>::mesh->property(prop, *e_it);
372 
373  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
374  v.normalize();
375 
376  if(vectorWidget->scale->isChecked())
377  v *= vectorWidget->scaleBox->value();
378 
379  lineNode->add_line( v1, (v1+v) );
380  lineNode->add_color(color);
381  }
382 }
383 
384 template <typename MeshT>
386 {
387  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
388 
389  lineNode->clear();
390 
391  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
392 
393  //TODO check if this also works if the property is Vec3f
395 
396  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
397  return;
398 
399  for (typename MeshT::HalfedgeIter he_it = OMPropertyVisualizer<MeshT>::mesh->halfedges_begin() ; he_it != OMPropertyVisualizer<MeshT>::mesh->halfedges_end() ; ++he_it){
400 
401  typename MeshT::VertexHandle vh0 = OMPropertyVisualizer<MeshT>::mesh->from_vertex_handle( *he_it );
402  typename MeshT::VertexHandle vh1 = OMPropertyVisualizer<MeshT>::mesh->to_vertex_handle( *he_it );
403 
404  typename MeshT::Point v1 = OMPropertyVisualizer<MeshT>::mesh->point(vh0) + 0.5 * (OMPropertyVisualizer<MeshT>::mesh->point(vh1) - OMPropertyVisualizer<MeshT>::mesh->point(vh0));
405  typename MeshT::Point v = OMPropertyVisualizer<MeshT>::mesh->property(prop, *he_it);
406 
407  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
408  v.normalize();
409 
410  if(vectorWidget->scale->isChecked())
411  v *= vectorWidget->scaleBox->value();
412 
413  lineNode->add_line( v1, (v1+v) );
414  lineNode->add_color(color);
415  }
416 }
417 
418 template <typename MeshT>
420 {
421  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
422 
423  lineNode->clear();
424 
425  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
426 
427  //TODO check if this also works if the property is Vec3f
429 
430  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
431  return;
432 
433  for (typename MeshT::VertexIter v_it = OMPropertyVisualizer<MeshT>::mesh->vertices_begin() ; v_it != OMPropertyVisualizer<MeshT>::mesh->vertices_end() ; ++v_it){
434 
435  typename MeshT::Point v1 = OMPropertyVisualizer<MeshT>::mesh->point( *v_it );
436  typename MeshT::Point v = OMPropertyVisualizer<MeshT>::mesh->property(prop, *v_it);
437 
438  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
439  v.normalize();
440 
441  if(vectorWidget->scale->isChecked())
442  v *= vectorWidget->scaleBox->value();
443 
444  lineNode->add_line( v1, (v1+v) );
445  lineNode->add_color(color);
446  }
447 }
448 
449 template <typename MeshT>
450 void OMPropertyVisualizerVector<MeshT>::setFacePropertyFromText(unsigned int index, QString text)
451 {
453  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
454 
455  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
456  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
457 
458 
459  typename MeshT::FaceHandle fh = mesh->face_handle(index);
460 
461  mesh->property(prop, fh) = this->strToVec3d(text);
462 }
463 
464 template <typename MeshT>
465 void OMPropertyVisualizerVector<MeshT>::setEdgePropertyFromText(unsigned int index, QString text)
466 {
468  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
469 
470  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
471  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
472 
473 
474  typename MeshT::EdgeHandle eh = mesh->edge_handle(index);
475 
476  mesh->property(prop, eh) = this->strToVec3d(text);
477 }
478 
479 template <typename MeshT>
480 void OMPropertyVisualizerVector<MeshT>::setHalfedgePropertyFromText(unsigned int index, QString text)
481 {
483  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
484 
485  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
486  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
487 
488 
489  typename MeshT::HalfedgeHandle heh = mesh->halfedge_handle(index);
490 
491  mesh->property(prop, heh) = this->strToVec3d(text);
492 }
493 
494 template <typename MeshT>
495 void OMPropertyVisualizerVector<MeshT>::setVertexPropertyFromText(unsigned int index, QString text)
496 {
498  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
499 
500  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
501  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
502 
503 
504  typename MeshT::VertexHandle vh = mesh->vertex_handle(index);
505 
506  mesh->property(prop, vh) = this->strToVec3d(text);
507 }
508 
509 
510 template<typename MeshT>
512 {
513  OMPropertyVisualizer<MeshT>::template removeProperty_stage1<typename MeshT::Point>();
514 }
515 
516 template<typename MeshT>
518 {
519  OMPropertyVisualizer<MeshT>::template duplicateProperty_stage1<typename MeshT::Point>();
520 }
521 
void removeProperty() override
Removes the property.
SeparatorNode * baseNode()
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
QString getPropertyText(unsigned int index) override
Returns the value of a property in text form.
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:83
DrawMode HALFEDGES_COLORED
draw halfedges with colors (without shading)
Definition: DrawModes.cc:103
DrawMode SOLID_POINTS_COLORED
draw colored, but not lighted faces using interpolated vertex colors
Definition: DrawModes.cc:85
Cellection of information about a property.
Definition: Utils.hh:109
virtual void clear()
Clears the property.
void duplicateProperty() override
Duplicates the property.
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:81
DrawMode SOLID_FACES_COLORED
draw colored, but not lighted faces using face colors
Definition: DrawModes.cc:84
DrawMode EDGES_COLORED
draw edges with colors (without shading)
Definition: DrawModes.cc:77
virtual void clear() override
Clears the property.
Class for generating nice colors for doubles.
Definition: ColorCoder.hh:68
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:453