Developer Documentation
OMPropertyVisualizerT_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 
45 #define OM_PROPERTY_VISUALIZER_CC
46 
47 #include "OMPropertyVisualizer.hh"
48 
49 
50 
51 namespace {
52 
53 template <typename EntityType, typename Handle, typename MeshT>
54 QString getPropertyText__(Handle handle, MeshT mesh, const PropertyInfo& propInfo)
55 {
56  EntityType prop;
57 
58  if ( !mesh->get_property_handle(prop, propInfo.propName() ) )
59  return QObject::tr("Error: No property with name ").append(propInfo.propName().c_str());
60 
61  return PropertyVisualizer::toStr(mesh->property(prop, handle));
62 }
63 
64 }
65 
66 
67 template <typename MeshT>
68 template <typename InnerType>
69 QString OMPropertyVisualizer<MeshT>::getPropertyText_(unsigned int index)
70 {
72  if (PropertyVisualizer::propertyInfo.isFaceProp())
73  return getPropertyText__<OpenMesh::FPropHandleT< InnerType > >(mesh->face_handle(index),OMPropertyVisualizer<MeshT>::mesh, PropertyVisualizer::propertyInfo);
74  else if (PropertyVisualizer::propertyInfo.isEdgeProp())
75  return getPropertyText__<OpenMesh::EPropHandleT< InnerType > >(mesh->edge_handle(index),OMPropertyVisualizer<MeshT>::mesh, PropertyVisualizer::propertyInfo);
76  else if (PropertyVisualizer::propertyInfo.isHalfedgeProp())
77  return getPropertyText__<OpenMesh::HPropHandleT< InnerType > >(mesh->halfedge_handle(index),OMPropertyVisualizer<MeshT>::mesh, PropertyVisualizer::propertyInfo);
78  else //if (propertyInfo.isVertexProp())
79  return getPropertyText__<OpenMesh::VPropHandleT< InnerType > >(mesh->vertex_handle(index),OMPropertyVisualizer<MeshT>::mesh, PropertyVisualizer::propertyInfo);
80 }
81 
82 
83 template<typename MeshT>
84 template<typename PropHandle>
86  PropHandle propHandle;
87  if (!mesh->get_property_handle(propHandle, propertyInfo.propName())) return;
88  mesh->remove_property(propHandle);
89 }
90 
91 template<typename MeshT>
92 template<typename PropType>
94  if (propertyInfo.isEdgeProp())
95  removeProperty_stage2<OpenMesh::EPropHandleT<PropType> >();
96  else if (propertyInfo.isVertexProp())
97  removeProperty_stage2<OpenMesh::VPropHandleT<PropType> >();
98  else if (propertyInfo.isFaceProp())
99  removeProperty_stage2<OpenMesh::FPropHandleT<PropType> >();
100  else if (propertyInfo.isHalfedgeProp())
101  removeProperty_stage2<OpenMesh::HPropHandleT<PropType> >();
102 }
103 
104 
105 template<typename MeshT>
106 template<typename PropHandle, typename Iterator>
107 inline void OMPropertyVisualizer<MeshT>::duplicateProperty_stage2(Iterator first, Iterator last) {
108  PropHandle propHandle;
109  if (!mesh->get_property_handle(propHandle, propertyInfo.propName())) return;
110 
111  std::string newPropertyName;
112  for (int i = 1;; ++i) {
113  std::ostringstream oss;
114  oss << propertyInfo.propName() << " Copy " << i;
115  newPropertyName = oss.str();
116 
117  PropHandle tmp;
118  if (!mesh->get_property_handle(tmp, newPropertyName)) break;
119  }
120 
121  PropHandle newProperty;
122  mesh->add_property(newProperty, newPropertyName);
123  std::for_each(first, last, CopyProperty<PropHandle>(newProperty, propHandle, mesh));
124 }
125 
126 template<typename MeshT>
127 template<typename PropType>
129  if (propertyInfo.isEdgeProp())
130  duplicateProperty_stage2<OpenMesh::EPropHandleT<PropType> >(mesh->edges_begin(), mesh->edges_end());
131  else if (propertyInfo.isVertexProp())
132  duplicateProperty_stage2<OpenMesh::VPropHandleT<PropType> >( mesh->vertices_begin(), mesh->vertices_end());
133  else if (propertyInfo.isFaceProp())
134  duplicateProperty_stage2<OpenMesh::FPropHandleT<PropType> >(mesh->faces_begin(), mesh->faces_end());
135  else if (propertyInfo.isHalfedgeProp())
136  duplicateProperty_stage2<OpenMesh::HPropHandleT<PropType> >(mesh->halfedges_begin(), mesh->halfedges_end());
137 }
138 
139 
140 
141 template <typename MeshT>
143 {
144  return "";
145 }
146 
147 
148 template <typename MeshT>
149 void OMPropertyVisualizer<MeshT>::setPropertyFromText(unsigned int index, QString text)
150 {
151  if (propertyInfo.isFaceProp())
152  setFacePropertyFromText(index, text);
153  else if (propertyInfo.isEdgeProp())
154  setEdgePropertyFromText(index, text);
155  else if (propertyInfo.isHalfedgeProp())
156  setHalfedgePropertyFromText(index, text);
157  else //if (propertyInfo.isVertexProp())
158  setVertexPropertyFromText(index, text);
159 }
160 
161 template <typename MeshT>
163 {
164  if (propertyInfo.isFaceProp())
165  return mesh->n_faces();
166  else if (propertyInfo.isEdgeProp())
167  return mesh->n_edges();
168  else if (propertyInfo.isHalfedgeProp())
169  return mesh->n_halfedges();
170  else //if (propertyInfo.isVertexProp())
171  return mesh->n_vertices();
172 }
173 
174 template <typename MeshT>
176 {
177  //Header: headerVersion, numberOfEntities, typeOfEntities, typeOfProperty, propertyName
178 
179  QString header = QObject::tr("1"); //version
180  header.append(QObject::tr(", %1").arg(getEntityCount())); //number of entities
181  header.append(QObject::tr(", %1").arg(propertyInfo.entityType())); //type of entities
182  header.append(", ").append(propertyInfo.friendlyTypeName()); //type of property
183  header.append(", ").append(propertyInfo.propName().c_str()); // name of property
184  return header;
185 }
186 
187 
199 template <typename MeshT>
200 unsigned int OMPropertyVisualizer<MeshT>::getClosestPrimitiveId(unsigned int _face, ACG::Vec3d& _hitPoint)
201 {
202  if (propertyInfo.isFaceProp())
203  return getClosestFaceId(_face, _hitPoint);
204  else if (propertyInfo.isEdgeProp())
205  return getClosestEdgeId(_face, _hitPoint);
206  else if (propertyInfo.isHalfedgeProp())
207  return getClosestHalfedgeId(_face, _hitPoint);
208  else //if (propertyInfo.isVertexProp())
209  return getClosestVertexId(_face, _hitPoint);
210 }
211 
212 template <typename MeshT>
213 unsigned int OMPropertyVisualizer<MeshT>::getClosestFaceId(unsigned int _face, ACG::Vec3d& _hitPoint)
214 {
215  return _face;
216 }
217 
218 template <typename MeshT>
219 unsigned int OMPropertyVisualizer<MeshT>::getClosestEdgeId(unsigned int _face, ACG::Vec3d& _hitPoint)
220 {
221  unsigned int closest_halfedge_id = getClosestHalfedgeId(_face, _hitPoint);
222  typename MeshT::HalfedgeHandle heh;
223  heh = mesh->halfedge_handle(closest_halfedge_id);
224 
225  typename MeshT::EdgeHandle eh;
226  eh = mesh->edge_handle(heh);
227 
228  return eh.idx();
229 }
230 
231 template <typename MeshT>
232 unsigned int OMPropertyVisualizer<MeshT>::getClosestHalfedgeId(unsigned int _face, ACG::Vec3d& _hitPoint)
233 {
234  typename MeshT::FaceHalfedgeIter fh_it;
235 
236  int closest_h_idx = 0;
237  double dist = DBL_MAX;
238 
239  ACG::Vec3d vTemp = ACG::Vec3d(0.0, 0.0, 0.0);
240  typename MeshT::Point p;
241 
242  for (fh_it = mesh->fh_iter(mesh->face_handle(_face)); fh_it.is_valid(); ++fh_it){
243 
244  typename MeshT::HalfedgeHandle heh;
245  heh = *fh_it;
246 
247  typename MeshT::VertexHandle v1;
248  v1 = mesh->to_vertex_handle(heh);
249  typename MeshT::VertexHandle v2;
250  v2 = mesh->from_vertex_handle(heh);
251 
252  p = 0.5* (mesh->point( v1 ) + mesh->point( v2 ));
253 
254  // Find closest vertex to selection
255  vTemp = ACG::Vec3d(p[0], p[1], p[2]);
256  const double temp_dist = (vTemp - _hitPoint).length();
257 
258  if (temp_dist < dist) {
259  dist = temp_dist;
260  closest_h_idx = fh_it->idx();
261  }
262 
263  }
264  return closest_h_idx;
265 }
266 
267 template <typename MeshT>
268 unsigned int OMPropertyVisualizer<MeshT>::getClosestVertexId(unsigned int _face, ACG::Vec3d& _hitPoint)
269 {
270  typename MeshT::FaceVertexIter fv_it;
271 
272  int closest_v_idx = 0;
273  double dist = DBL_MAX;
274 
275  ACG::Vec3d vTemp = ACG::Vec3d(0.0, 0.0, 0.0);
276  typename MeshT::Point p;
277 
278  for (fv_it = mesh->fv_iter(mesh->face_handle(_face)); fv_it.is_valid(); ++fv_it){
279 
280  p = mesh->point( *fv_it );
281 
282  // Find closest vertex to selection
283  vTemp = ACG::Vec3d(p[0], p[1], p[2]);
284  const double temp_dist = (vTemp - _hitPoint).length();
285 
286  if (temp_dist < dist) {
287  dist = temp_dist;
288  closest_v_idx = fv_it->idx();
289  }
290 
291  }
292  return closest_v_idx;
293 }
294 
302 template <typename MeshT>
303 void OMPropertyVisualizer<MeshT>::visualize(bool _setDrawMode, QWidget* _widget)
304 {
305  QWidget* tmp;
306  if (_widget)
307  {
308  tmp = widget;
309  widget = _widget;
310  }
311 
312  if (propertyInfo.isFaceProp())
313  visualizeFaceProp(_setDrawMode);
314  else if (propertyInfo.isEdgeProp())
315  visualizeEdgeProp(_setDrawMode);
316  else if (propertyInfo.isHalfedgeProp())
317  visualizeHalfedgeProp(_setDrawMode);
318  else if (propertyInfo.isVertexProp())
319  visualizeVertexProp(_setDrawMode);
320 
321  if (_widget)
322  {
323  widget = tmp;
324  }
325 }
326 
332 template <typename MeshT>
334 {
335  if (propertyInfo.isFaceProp())
336  clearFaceProp();
337  else if (propertyInfo.isEdgeProp())
338  clearEdgeProp();
339  else if (propertyInfo.isHalfedgeProp())
340  clearHalfedgeProp();
341  else if (propertyInfo.isVertexProp())
342  clearVertexProp();
343 }
344 
345 template <typename MeshT>
346 void OMPropertyVisualizer<MeshT>::visualizeFaceProp(bool /*_setDrawMode*/)
347 {
348  emit log(LOGERR, "Visualizing FaceProp not implemented");
349 }
350 
351 template <typename MeshT>
352 void OMPropertyVisualizer<MeshT>::visualizeEdgeProp(bool /*_setDrawMode*/)
353 {
354  emit log(LOGERR, "Visualizing EdgeProp not implemented");
355 }
356 
357 template <typename MeshT>
358 void OMPropertyVisualizer<MeshT>::visualizeHalfedgeProp(bool /*_setDrawMode*/)
359 {
360  emit log(LOGERR, "Visualizing HalfedgeProp not implemented");
361 }
362 
363 template <typename MeshT>
364 void OMPropertyVisualizer<MeshT>::visualizeVertexProp(bool /*_setDrawMode*/)
365 {
366  emit log(LOGERR, "Visualizing VertexProp not implemented");
367 }
368 
369 template <typename MeshT>
371 {
372  if ( mesh->has_face_colors() )
373  OMPropertyVisualizer<MeshT>::mesh->release_face_colors();
374 }
375 
376 template <typename MeshT>
378 {
379  if ( mesh->has_edge_colors() )
380  OMPropertyVisualizer<MeshT>::mesh->release_edge_colors();
381 }
382 
383 template <typename MeshT>
385 {
386  if ( mesh->has_halfedge_colors() )
387  OMPropertyVisualizer<MeshT>::mesh->release_halfedge_colors();
388 }
389 
390 template <typename MeshT>
392 {
393  if ( mesh->has_vertex_colors() )
394  OMPropertyVisualizer<MeshT>::mesh->release_vertex_colors();
395 }
396 
397 template <typename MeshT>
398 void OMPropertyVisualizer<MeshT>::setFacePropertyFromText(unsigned int index, QString text)
399 {
400  emit log(LOGERR, "Setting face property not implemented");
401 }
402 
403 template <typename MeshT>
404 void OMPropertyVisualizer<MeshT>::setEdgePropertyFromText(unsigned int index, QString text)
405 {
406  emit log(LOGERR, "Settingedge property not implemented");
407 }
408 
409 template <typename MeshT>
410 void OMPropertyVisualizer<MeshT>::setHalfedgePropertyFromText(unsigned int index, QString text)
411 {
412  emit log(LOGERR, "Setting halfedge property not implemented");
413 }
414 
415 template <typename MeshT>
416 void OMPropertyVisualizer<MeshT>::setVertexPropertyFromText(unsigned int index, QString text)
417 {
418  emit log(LOGERR, "Setting vertex property not implemented");
419 }
420 
421 
422 template<typename MeshT>
423 template<typename Type>
425  using PV = OMPropertyVisualizer<MeshT>;
426  const std::string &prop_name = PV::propertyInfo.propName();
427 
428  // ugly repetition ahead. In C++14, we could use a generic lambda,
429  // in C++11 the cleanest solution would be to add another templated member function - not worth it.
430  switch (PropertyVisualizer::propertyInfo.entityType()) {
431  case PropertyInfo::EF_FACE:
432  {
433  OpenMesh::FPropHandleT<Type> prop_handle;
434  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
435  PropertyVisualizer::template showHistogramT<Type>(
436  histogramWidget,
437  PV::mesh->property(prop_handle).data_vector());
438  break;
439  }
440  case PropertyInfo::EF_EDGE:
441  {
442  OpenMesh::EPropHandleT<Type> prop_handle;
443  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
444  PropertyVisualizer::template showHistogramT<Type>(
445  histogramWidget,
446  PV::mesh->property(prop_handle).data_vector());
447  break;
448  }
449  case PropertyInfo::EF_HALFEDGE:
450  {
451  OpenMesh::HPropHandleT<Type> prop_handle;
452  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
453  PropertyVisualizer::template showHistogramT<Type>(
454  histogramWidget,
455  PV::mesh->property(prop_handle).data_vector());
456  break;
457  }
458  case PropertyInfo::EF_VERTEX:
459  {
460  OpenMesh::VPropHandleT<Type> prop_handle;
461  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
462  PropertyVisualizer::template showHistogramT<Type>(
463  histogramWidget,
464  PV::mesh->property(prop_handle).data_vector());
465  break;
466  }
467  default:
468  assert(false);
469  }
470 }
unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint)
Returns the ID of the closest primitive.
virtual void setPropertyFromText(unsigned int index, QString text)
Returns the value of a property in text form.
virtual QString getHeader()
Returns the header for saving.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
virtual void clear()
Clears the property.
virtual void visualize(bool _setDrawMode, QWidget *_widget)
Visualizes the property.
virtual int getEntityCount()
Returns the number of entities.
Cellection of information about a property.
Definition: Utils.hh:109
virtual QString getPropertyText(unsigned int index)
Returns the value of a property in text form.