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