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>
150 {
151  BaseObjectData* object;
152  if (PluginFunctions::getObject(mObjectID, object))
153  object->setObjectDrawMode(_mode);
154 }
155 
156 
157 
158 template <typename MeshT>
159 void OMPropertyVisualizer<MeshT>::setPropertyFromText(unsigned int index, QString text)
160 {
161  if (propertyInfo.isFaceProp())
162  setFacePropertyFromText(index, text);
163  else if (propertyInfo.isEdgeProp())
164  setEdgePropertyFromText(index, text);
165  else if (propertyInfo.isHalfedgeProp())
166  setHalfedgePropertyFromText(index, text);
167  else //if (propertyInfo.isVertexProp())
168  setVertexPropertyFromText(index, text);
169 }
170 
171 template <typename MeshT>
173 {
174  if (propertyInfo.isFaceProp())
175  return mesh->n_faces();
176  else if (propertyInfo.isEdgeProp())
177  return mesh->n_edges();
178  else if (propertyInfo.isHalfedgeProp())
179  return mesh->n_halfedges();
180  else //if (propertyInfo.isVertexProp())
181  return mesh->n_vertices();
182 }
183 
184 template <typename MeshT>
186 {
187  //Header: headerVersion, numberOfEntities, typeOfEntities, typeOfProperty, propertyName
188 
189  QString header = QObject::tr("1"); //version
190  header.append(QObject::tr(", %1").arg(getEntityCount())); //number of entities
191  header.append(QObject::tr(", %1").arg(propertyInfo.entityType())); //type of entities
192  header.append(", ").append(propertyInfo.friendlyTypeName()); //type of property
193  header.append(", ").append(propertyInfo.propName().c_str()); // name of property
194  return header;
195 }
196 
197 
209 template <typename MeshT>
210 unsigned int OMPropertyVisualizer<MeshT>::getClosestPrimitiveId(unsigned int _face, ACG::Vec3d& _hitPoint)
211 {
212  if (propertyInfo.isFaceProp())
213  return getClosestFaceId(_face, _hitPoint);
214  else if (propertyInfo.isEdgeProp())
215  return getClosestEdgeId(_face, _hitPoint);
216  else if (propertyInfo.isHalfedgeProp())
217  return getClosestHalfedgeId(_face, _hitPoint);
218  else //if (propertyInfo.isVertexProp())
219  return getClosestVertexId(_face, _hitPoint);
220 }
221 
222 template <typename MeshT>
223 unsigned int OMPropertyVisualizer<MeshT>::getClosestFaceId(unsigned int _face, ACG::Vec3d& _hitPoint)
224 {
225  return _face;
226 }
227 
228 template <typename MeshT>
229 unsigned int OMPropertyVisualizer<MeshT>::getClosestEdgeId(unsigned int _face, ACG::Vec3d& _hitPoint)
230 {
231  unsigned int closest_halfedge_id = getClosestHalfedgeId(_face, _hitPoint);
232  typename MeshT::HalfedgeHandle heh;
233  heh = mesh->halfedge_handle(closest_halfedge_id);
234 
235  typename MeshT::EdgeHandle eh;
236  eh = mesh->edge_handle(heh);
237 
238  return eh.idx();
239 }
240 
241 template <typename MeshT>
242 unsigned int OMPropertyVisualizer<MeshT>::getClosestHalfedgeId(unsigned int _face, ACG::Vec3d& _hitPoint)
243 {
244  typename MeshT::FaceHalfedgeIter fh_it;
245 
246  int closest_h_idx = 0;
247  double dist = DBL_MAX;
248 
249  ACG::Vec3d vTemp = ACG::Vec3d(0.0, 0.0, 0.0);
250  typename MeshT::Point p;
251 
252  for (fh_it = mesh->fh_iter(mesh->face_handle(_face)); fh_it.is_valid(); ++fh_it){
253 
254  typename MeshT::HalfedgeHandle heh;
255  heh = *fh_it;
256 
257  typename MeshT::VertexHandle v1;
258  v1 = mesh->to_vertex_handle(heh);
259  typename MeshT::VertexHandle v2;
260  v2 = mesh->from_vertex_handle(heh);
261 
262  p = 0.5* (mesh->point( v1 ) + mesh->point( v2 ));
263 
264  // Find closest vertex to selection
265  vTemp = ACG::Vec3d(p[0], p[1], p[2]);
266  const double temp_dist = (vTemp - _hitPoint).length();
267 
268  if (temp_dist < dist) {
269  dist = temp_dist;
270  closest_h_idx = fh_it->idx();
271  }
272 
273  }
274  return closest_h_idx;
275 }
276 
277 template <typename MeshT>
278 unsigned int OMPropertyVisualizer<MeshT>::getClosestVertexId(unsigned int _face, ACG::Vec3d& _hitPoint)
279 {
280  typename MeshT::FaceVertexIter fv_it;
281 
282  int closest_v_idx = 0;
283  double dist = DBL_MAX;
284 
285  ACG::Vec3d vTemp = ACG::Vec3d(0.0, 0.0, 0.0);
286  typename MeshT::Point p;
287 
288  for (fv_it = mesh->fv_iter(mesh->face_handle(_face)); fv_it.is_valid(); ++fv_it){
289 
290  p = mesh->point( *fv_it );
291 
292  // Find closest vertex to selection
293  vTemp = ACG::Vec3d(p[0], p[1], p[2]);
294  const double temp_dist = (vTemp - _hitPoint).length();
295 
296  if (temp_dist < dist) {
297  dist = temp_dist;
298  closest_v_idx = fv_it->idx();
299  }
300 
301  }
302  return closest_v_idx;
303 }
304 
312 template <typename MeshT>
313 void OMPropertyVisualizer<MeshT>::visualize(bool _setDrawMode, QWidget* _widget)
314 {
315  QWidget* tmp;
316  if (_widget)
317  {
318  tmp = widget;
319  widget = _widget;
320  }
321 
322  if (propertyInfo.isFaceProp())
323  visualizeFaceProp(_setDrawMode);
324  else if (propertyInfo.isEdgeProp())
325  visualizeEdgeProp(_setDrawMode);
326  else if (propertyInfo.isHalfedgeProp())
327  visualizeHalfedgeProp(_setDrawMode);
328  else if (propertyInfo.isVertexProp())
329  visualizeVertexProp(_setDrawMode);
330 
331  if (_widget)
332  {
333  widget = tmp;
334  }
335 }
336 
342 template <typename MeshT>
344 {
345  if (propertyInfo.isFaceProp())
346  clearFaceProp();
347  else if (propertyInfo.isEdgeProp())
348  clearEdgeProp();
349  else if (propertyInfo.isHalfedgeProp())
350  clearHalfedgeProp();
351  else if (propertyInfo.isVertexProp())
352  clearVertexProp();
353 }
354 
355 template <typename MeshT>
356 void OMPropertyVisualizer<MeshT>::visualizeFaceProp(bool /*_setDrawMode*/)
357 {
358  emit log(LOGERR, "Visualizing FaceProp not implemented");
359 }
360 
361 template <typename MeshT>
362 void OMPropertyVisualizer<MeshT>::visualizeEdgeProp(bool /*_setDrawMode*/)
363 {
364  emit log(LOGERR, "Visualizing EdgeProp not implemented");
365 }
366 
367 template <typename MeshT>
368 void OMPropertyVisualizer<MeshT>::visualizeHalfedgeProp(bool /*_setDrawMode*/)
369 {
370  emit log(LOGERR, "Visualizing HalfedgeProp not implemented");
371 }
372 
373 template <typename MeshT>
374 void OMPropertyVisualizer<MeshT>::visualizeVertexProp(bool /*_setDrawMode*/)
375 {
376  emit log(LOGERR, "Visualizing VertexProp not implemented");
377 }
378 
379 template <typename MeshT>
381 {
382  if ( mesh->has_face_colors() )
383  OMPropertyVisualizer<MeshT>::mesh->release_face_colors();
384 }
385 
386 template <typename MeshT>
388 {
389  if ( mesh->has_edge_colors() )
390  OMPropertyVisualizer<MeshT>::mesh->release_edge_colors();
391 }
392 
393 template <typename MeshT>
395 {
396  if ( mesh->has_halfedge_colors() )
397  OMPropertyVisualizer<MeshT>::mesh->release_halfedge_colors();
398 }
399 
400 template <typename MeshT>
402 {
403  if ( mesh->has_vertex_colors() )
404  OMPropertyVisualizer<MeshT>::mesh->release_vertex_colors();
405 }
406 
407 template <typename MeshT>
408 void OMPropertyVisualizer<MeshT>::setFacePropertyFromText(unsigned int index, QString text)
409 {
410  emit log(LOGERR, "Setting face property not implemented");
411 }
412 
413 template <typename MeshT>
414 void OMPropertyVisualizer<MeshT>::setEdgePropertyFromText(unsigned int index, QString text)
415 {
416  emit log(LOGERR, "Settingedge property not implemented");
417 }
418 
419 template <typename MeshT>
420 void OMPropertyVisualizer<MeshT>::setHalfedgePropertyFromText(unsigned int index, QString text)
421 {
422  emit log(LOGERR, "Setting halfedge property not implemented");
423 }
424 
425 template <typename MeshT>
426 void OMPropertyVisualizer<MeshT>::setVertexPropertyFromText(unsigned int index, QString text)
427 {
428  emit log(LOGERR, "Setting vertex property not implemented");
429 }
430 
431 
432 template<typename MeshT>
433 template<typename Type>
435  using PV = OMPropertyVisualizer<MeshT>;
436  const std::string &prop_name = PV::propertyInfo.propName();
437 
438  // ugly repetition ahead. In C++14, we could use a generic lambda,
439  // in C++11 the cleanest solution would be to add another templated member function - not worth it.
440  switch (PropertyVisualizer::propertyInfo.entityType()) {
441  case PropertyInfo::EF_FACE:
442  {
443  OpenMesh::FPropHandleT<Type> prop_handle;
444  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
445  PropertyVisualizer::template showHistogramT<Type>(
446  histogramWidget,
447  PV::mesh->property(prop_handle).data_vector());
448  break;
449  }
450  case PropertyInfo::EF_EDGE:
451  {
452  OpenMesh::EPropHandleT<Type> prop_handle;
453  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
454  PropertyVisualizer::template showHistogramT<Type>(
455  histogramWidget,
456  PV::mesh->property(prop_handle).data_vector());
457  break;
458  }
459  case PropertyInfo::EF_HALFEDGE:
460  {
461  OpenMesh::HPropHandleT<Type> prop_handle;
462  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
463  PropertyVisualizer::template showHistogramT<Type>(
464  histogramWidget,
465  PV::mesh->property(prop_handle).data_vector());
466  break;
467  }
468  case PropertyInfo::EF_VERTEX:
469  {
470  OpenMesh::VPropHandleT<Type> prop_handle;
471  if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break;
472  PropertyVisualizer::template showHistogramT<Type>(
473  histogramWidget,
474  PV::mesh->property(prop_handle).data_vector());
475  break;
476  }
477  default:
478  assert(false);
479  }
480 }
unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint)
Returns the ID of the closest primitive.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
virtual void visualize(bool _setDrawMode, QWidget *_widget)
Visualizes the property.
virtual void setPropertyFromText(unsigned int index, QString text)
Returns the value of a property in text form.
void setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, const bool &_force=false)
Set the draw mode for the object.
virtual int getEntityCount()
Returns the number of entities.
Cellection of information about a property.
Definition: Utils.hh:109
virtual void clear()
Clears the property.
virtual QString getHeader()
Returns the header for saving.
virtual QString getPropertyText(unsigned int index)
Returns the value of a property in text form.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121