Developer Documentation
OVMPropertyVisualizerT_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 OVM_PROPERTY_VISUALIZER_CC
45 
46 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
48 #endif
49 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
51 #endif
52 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
54 #endif
55 
56 #include "OVMPropertyVisualizer.hh"
57 
58 #include <ACG/Utils/Histogram.hh>
59 
60 template <typename MeshT>
61 template <typename InnerType>
62 QString OVMPropertyVisualizer<MeshT>::getPropertyText_(unsigned int index)
63 {
64  if (PropertyVisualizer::propertyInfo.isCellProp())
65  {
67  return PropertyVisualizer::toStr(prop[OpenVolumeMesh::CellHandle(index)]);
68  }
69  else if (PropertyVisualizer::propertyInfo.isFaceProp())
70  {
72  return PropertyVisualizer::toStr(prop[OpenVolumeMesh::FaceHandle(index)]);
73  }
74  else if (PropertyVisualizer::propertyInfo.isHalffaceProp())
75  {
77  return PropertyVisualizer::toStr(prop[OpenVolumeMesh::HalfFaceHandle(index)]);
78  }
79  else if (PropertyVisualizer::propertyInfo.isEdgeProp())
80  {
82  return PropertyVisualizer::toStr(prop[OpenVolumeMesh::EdgeHandle(index)]);
83  }
84  else if (PropertyVisualizer::propertyInfo.isHalfedgeProp())
85  {
87  return PropertyVisualizer::toStr(prop[OpenVolumeMesh::HalfEdgeHandle(index)]);
88  }
89  else //if (propertyInfo.isVertexProp())
90  {
92  return PropertyVisualizer::toStr(prop[OpenVolumeMesh::VertexHandle(index)]);
93  }
94 }
95 
96 template <typename MeshT>
97 void OVMPropertyVisualizer<MeshT>::setPropertyFromText(unsigned int index, QString text)
98 {
99  if (propertyInfo.isCellProp())
100  setCellPropertyFromText(index, text);
101  else if (propertyInfo.isFaceProp())
102  setFacePropertyFromText(index, text);
103  else if (propertyInfo.isHalffaceProp())
104  setHalffacePropertyFromText(index, text);
105  else if (propertyInfo.isEdgeProp())
106  setEdgePropertyFromText(index, text);
107  else if (propertyInfo.isHalfedgeProp())
108  setHalfedgePropertyFromText(index, text);
109  else //if (propertyInfo.isVertexProp())
110  setVertexPropertyFromText(index, text);
111 }
112 
113 template <typename MeshT>
115 {
116  if (propertyInfo.isCellProp())
117  return mesh->n_cells();
118  if (propertyInfo.isFaceProp())
119  return mesh->n_faces();
120  if (propertyInfo.isHalffaceProp())
121  return mesh->n_halffaces();
122  else if (propertyInfo.isEdgeProp())
123  return mesh->n_edges();
124  else if (propertyInfo.isHalfedgeProp())
125  return mesh->n_halfedges();
126  else //if (propertyInfo.isVertexProp())
127  return mesh->n_vertices();
128 }
129 
130 template <typename MeshT>
132 {
133  //Header: headerVersion, numberOfEntities, typeOfEntites, typeOfProperty, propertyName
134 
135  QString header = QObject::tr("1"); //version
136  header.append(QObject::tr(", %1").arg(getEntityCount())); //number of entities
137  header.append(QObject::tr(", %1").arg(propertyInfo.entityType())); //type of entities
138  header.append(", ").append(propertyInfo.friendlyTypeName()); //type of property
139  header.append(", ").append(propertyInfo.propName().c_str()); // name of property
140  return header;
141 }
142 
143 template <typename MeshT>
144 unsigned int OVMPropertyVisualizer<MeshT>::getClosestPrimitiveId(unsigned int _face, ACG::Vec3d& _hitPoint)
145 {
146  if (propertyInfo.isHalffaceProp())
147  return getClosestHalffaceId(_face, _hitPoint);
148  else// if (propertyInfo.isHalfedgeProp())
149  return getClosestHalfedgeId(_face, _hitPoint);
150 }
151 
152 template <typename MeshT>
153 unsigned int OVMPropertyVisualizer<MeshT>::getClosestHalffaceId(unsigned int _face, ACG::Vec3d& _hitPoint)
154 {
156 
157  OpenVolumeMesh::HalfFaceHandle hfh = mesh->halfface_handle(OpenVolumeMesh::FaceHandle(_face), 0);
158  OpenVolumeMesh::HalfFaceVertexIter hfv_it = mesh->hfv_iter(hfh);
159  ACG::Vec3d p1 = mesh->vertex(*(hfv_it+0));
160  ACG::Vec3d p2 = mesh->vertex(*(hfv_it+1));
161  ACG::Vec3d p3 = mesh->vertex(*(hfv_it+2));
162 
163  ACG::Vec3d normal = (p2-p1)%(p3-p1);
164 
165  if ((direction | normal) < 0)
166  return hfh.idx();
167  else
168  return mesh->halfface_handle(OpenVolumeMesh::FaceHandle(_face), 1).idx();
169 }
170 
171 template <typename MeshT>
172 unsigned int OVMPropertyVisualizer<MeshT>::getClosestHalfedgeId(unsigned int _face, ACG::Vec3d& _hitPoint)
173 {
174  OpenVolumeMesh::HalfFaceHandle halfface = OpenVolumeMesh::HalfFaceHandle(getClosestHalffaceId(_face, _hitPoint));
175 
176  OpenVolumeMesh::OpenVolumeMeshFace face = mesh->halfface(halfface);
177 
178  const std::vector<OpenVolumeMesh::HalfEdgeHandle> & halfedges = face.halfedges();
179 
180  double min_distance = DBL_MAX;
181  OpenVolumeMesh::HalfEdgeHandle closestHalfEdgeHandle;
182 
183  for (std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator he_it = halfedges.begin(); he_it != halfedges.end(); ++he_it)
184  {
186  ACG::Vec3d v1 = mesh->vertex(edge.from_vertex());
187  ACG::Vec3d v2 = mesh->vertex(edge.to_vertex());
188  ACG::Vec3d p = 0.5 * (v1+v2);
189  double distance = (p-_hitPoint).length();
190  if (distance < min_distance)
191  {
192  min_distance = distance;
193  closestHalfEdgeHandle = *he_it;
194  }
195 
196  }
197 
198  return closestHalfEdgeHandle.idx();
199 }
200 
201 
202 template <typename MeshT>
203 void OVMPropertyVisualizer<MeshT>::visualize(bool _setDrawMode, QWidget* _widget)
204 {
205  QWidget* tmp;
206  if (_widget)
207  {
208  tmp = widget;
209  widget = _widget;
210  }
211 
212  if (propertyInfo.isCellProp())
213  visualizeCellProp(_setDrawMode);
214  else if (propertyInfo.isFaceProp())
215  visualizeFaceProp(_setDrawMode);
216  else if (propertyInfo.isHalffaceProp())
217  visualizeHalffaceProp(_setDrawMode);
218  else if (propertyInfo.isEdgeProp())
219  visualizeEdgeProp(_setDrawMode);
220  else if (propertyInfo.isHalfedgeProp())
221  visualizeHalfedgeProp(_setDrawMode);
222  else if (propertyInfo.isVertexProp())
223  visualizeVertexProp(_setDrawMode);
224 
225  if (_widget)
226  {
227  widget = tmp;
228  }
229 }
230 
231 template <typename MeshT>
232 void OVMPropertyVisualizer<MeshT>::visualizeFaceProp(bool /*_setDrawMode*/)
233 {
234  emit log(LOGERR, "Visualizing FaceProp not implemented");
235 }
236 
237 template <typename MeshT>
238 void OVMPropertyVisualizer<MeshT>::visualizeEdgeProp(bool /*_setDrawMode*/)
239 {
240  emit log(LOGERR, "Visualizing EdgeProp not implemented");
241 }
242 
243 template <typename MeshT>
244 void OVMPropertyVisualizer<MeshT>::visualizeHalfedgeProp(bool /*_setDrawMode*/)
245 {
246  emit log(LOGERR, "Visualizing HalfedgeProp not implemented");
247 }
248 
249 template <typename MeshT>
250 void OVMPropertyVisualizer<MeshT>::visualizeVertexProp(bool /*_setDrawMode*/)
251 {
252  emit log(LOGERR, "Visualizing VertexProp not implemented");
253 }
254 
255 template <typename MeshT>
256 void OVMPropertyVisualizer<MeshT>::visualizeCellProp(bool /*_setDrawMode*/)
257 {
258  emit log(LOGERR, "Visualizing CellProp not implemented");
259 }
260 
261 template <typename MeshT>
262 void OVMPropertyVisualizer<MeshT>::visualizeHalffaceProp(bool /*_setDrawMode*/)
263 {
264  emit log(LOGERR, "Visualizing HalffaceProp not implemented");
265 }
266 
267 template<typename MeshT>
268 template<typename PropType>
270  std::string newPropertyName;
271  for (int i = 1;; ++i) {
272  std::ostringstream oss;
273  oss << propertyInfo.propName() << " Copy " << i;
274  newPropertyName = oss.str();
275 
276  if (propertyInfo.isCellProp())
277  {
278  if(!mesh->template cell_property_exists<PropType>(newPropertyName)) break;
279  }
280  else if (propertyInfo.isFaceProp())
281  {
282  if(!mesh->template face_property_exists<PropType>(newPropertyName)) break;
283  }
284  else if (propertyInfo.isHalffaceProp())
285  {
286  if(!mesh->template halfface_property_exists<PropType>(newPropertyName)) break;
287  }
288  else if (propertyInfo.isEdgeProp())
289  {
290  if(!mesh->template edge_property_exists<PropType>(newPropertyName)) break;
291  }
292  else if (propertyInfo.isHalfedgeProp())
293  {
294  if(!mesh->template halfedge_property_exists<PropType>(newPropertyName)) break;
295  }
296  else if (propertyInfo.isVertexProp())
297  {
298  if(!mesh->template vertex_property_exists<PropType>(newPropertyName)) break;
299  }
300  }
301 
302  if (propertyInfo.isCellProp())
303  {
304  OpenVolumeMesh::CellPropertyT<PropType> prop = mesh->template request_cell_property<PropType>(OVMPropertyVisualizer<MeshT>::propertyInfo.propName());
305  OpenVolumeMesh::CellPropertyT<PropType> newProp = mesh->template request_cell_property< PropType >(newPropertyName);
306  mesh->set_persistent(newProp, true);
307  std::for_each(mesh->cells_begin(), mesh->cells_end(), CopyProperty<OpenVolumeMesh::CellPropertyT<PropType> >(newProp, prop, mesh));
308  }
309  else if (propertyInfo.isFaceProp())
310  {
311  OpenVolumeMesh::FacePropertyT<PropType> prop = mesh->template request_face_property<PropType>(OVMPropertyVisualizer<MeshT>::propertyInfo.propName());
312  OpenVolumeMesh::FacePropertyT<PropType> newProp = mesh->template request_face_property< PropType >(newPropertyName);
313  mesh->set_persistent(newProp, true);
314  std::for_each(mesh->faces_begin(), mesh->faces_end(), CopyProperty<OpenVolumeMesh::FacePropertyT<PropType> >(newProp, prop, mesh));
315  }
316  else if (propertyInfo.isHalffaceProp())
317  {
318  OpenVolumeMesh::HalfFacePropertyT<PropType> prop = mesh->template request_halfface_property<PropType>(OVMPropertyVisualizer<MeshT>::propertyInfo.propName());
319  OpenVolumeMesh::HalfFacePropertyT<PropType> newProp = mesh->template request_halfface_property< PropType >(newPropertyName);
320  mesh->set_persistent(newProp, true);
321  std::for_each(mesh->halffaces_begin(), mesh->halffaces_end(), CopyProperty<OpenVolumeMesh::HalfFacePropertyT<PropType> >(newProp, prop, mesh));
322  }
323  else if (propertyInfo.isEdgeProp())
324  {
325  OpenVolumeMesh::EdgePropertyT<PropType> prop = mesh->template request_edge_property<PropType>(OVMPropertyVisualizer<MeshT>::propertyInfo.propName());
326  OpenVolumeMesh::EdgePropertyT<PropType> newProp = mesh->template request_edge_property< PropType >(newPropertyName);
327  mesh->set_persistent(newProp, true);
328  std::for_each(mesh->edges_begin(), mesh->edges_end(), CopyProperty<OpenVolumeMesh::EdgePropertyT<PropType> >(newProp, prop, mesh));
329  }
330  else if (propertyInfo.isHalfedgeProp())
331  {
332  OpenVolumeMesh::HalfEdgePropertyT<PropType> prop = mesh->template request_halfedge_property<PropType>(OVMPropertyVisualizer<MeshT>::propertyInfo.propName());
333  OpenVolumeMesh::HalfEdgePropertyT<PropType> newProp = mesh->template request_halfedge_property< PropType >(newPropertyName);
334  mesh->set_persistent(newProp, true);
335  std::for_each(mesh->halfedges_begin(), mesh->halfedges_end(), CopyProperty<OpenVolumeMesh::HalfEdgePropertyT<PropType> >(newProp, prop, mesh));
336  }
337  else if (propertyInfo.isVertexProp())
338  {
339  OpenVolumeMesh::VertexPropertyT<PropType> prop = mesh->template request_vertex_property<PropType>(OVMPropertyVisualizer<MeshT>::propertyInfo.propName());
340  OpenVolumeMesh::VertexPropertyT<PropType> newProp = mesh->template request_vertex_property< PropType >(newPropertyName);
341  mesh->set_persistent(newProp, true);
342  std::for_each(mesh->vertices_begin(), mesh->vertices_end(), CopyProperty<OpenVolumeMesh::VertexPropertyT<PropType> >(newProp, prop, mesh));
343  }
344 }
345 
346 template <typename MeshT>
348 {
349  VolumeMeshObject<MeshT>* object;
351 
352  if (propertyInfo.isCellProp())
353  object->colors().clear_cell_colors();
354  else if (propertyInfo.isFaceProp())
355  object->colors().clear_face_colors();
356  else if (propertyInfo.isHalffaceProp())
357  object->colors().clear_halfface_colors();
358  else if (propertyInfo.isEdgeProp())
359  object->colors().clear_edge_colors();
360  else if (propertyInfo.isHalfedgeProp())
361  object->colors().clear_halfedge_colors();
362  else if (propertyInfo.isVertexProp())
363  object->colors().clear_vertex_colors();
364 
365  object->setObjectDrawMode(drawModes.cellsFlatShaded);
366 }
367 
368 template <typename MeshT>
369 void OVMPropertyVisualizer<MeshT>::setCellPropertyFromText(unsigned int /*index*/, QString /*text*/)
370 {
371  emit log(LOGERR, "Setting CellProp not implemented for this property type");
372 }
373 
374 template <typename MeshT>
375 void OVMPropertyVisualizer<MeshT>::setFacePropertyFromText(unsigned int /*index*/, QString /*text*/)
376 {
377  emit log(LOGERR, "Setting FaceProp not implemented for this property type");
378 }
379 
380 template <typename MeshT>
381 void OVMPropertyVisualizer<MeshT>::setHalffacePropertyFromText(unsigned int /*index*/, QString /*text*/)
382 {
383  emit log(LOGERR, "Setting HalffaceProp not implemented for this property type");
384 }
385 
386 template <typename MeshT>
387 void OVMPropertyVisualizer<MeshT>::setEdgePropertyFromText(unsigned int /*index*/, QString /*text*/)
388 {
389  emit log(LOGERR, "Setting EdgeProp not implemented for this property type");
390 }
391 
392 template <typename MeshT>
393 void OVMPropertyVisualizer<MeshT>::setHalfedgePropertyFromText(unsigned int /*index*/, QString /*text*/)
394 {
395  emit log(LOGERR, "Setting HalfedgeProp not implemented for this property type");
396 }
397 
398 template <typename MeshT>
399 void OVMPropertyVisualizer<MeshT>::setVertexPropertyFromText(unsigned int /*index*/, QString /*text*/)
400 {
401  emit log(LOGERR, "Setting VertexProp not implemented for this property type");
402 }
403 
404 template<typename MeshT>
405 template<typename Type>
407  using PV = OVMPropertyVisualizer<MeshT>;
408  const std::string &prop_name = PV::propertyInfo.propName();
409 
410  switch (PropertyVisualizer::propertyInfo.entityType()) {
411  case PropertyInfo::EF_CELL:
412  this->showHistogramT<Type>(
413  histogramWidget,
414  PV::mesh->template request_cell_property<Type>(prop_name));
415  break;
416  case PropertyInfo::EF_FACE:
417  this->showHistogramT<Type>(
418  histogramWidget,
419  PV::mesh->template request_face_property<Type>(prop_name));
420  break;
421  case PropertyInfo::EF_HALFFACE:
422  this->showHistogramT<Type>(
423  histogramWidget,
424  PV::mesh->template request_halfface_property<Type>(prop_name));
425  break;
426  case PropertyInfo::EF_EDGE:
427  this->showHistogramT<Type>(
428  histogramWidget,
429  PV::mesh->template request_edge_property<Type>(prop_name));
430  break;
431  case PropertyInfo::EF_HALFEDGE:
432  this->showHistogramT<Type>(
433  histogramWidget,
434  PV::mesh->template request_halfedge_property<Type>(prop_name));
435  break;
436  case PropertyInfo::EF_VERTEX:
437  this->showHistogramT<Type>(
438  histogramWidget,
439  PV::mesh->template request_vertex_property<Type>(prop_name));
440  break;
441  case PropertyInfo::EF_ANY:
442  assert(false);
443  }
444 }
445 
virtual QString getHeader()
Returns the header for saving.
virtual void clear()
Clears a property.
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up, int _viewer)
Set the viewing direction.
virtual int getEntityCount()
Returns the number of entities.
virtual void setPropertyFromText(unsigned int index, QString text)
Returns the value of a property in text form.
const ColorAttrib & colors() const
return a pointer to the mesh
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint)
Returns the ID of the closest primitive.
virtual void visualize(bool _setDrawMode, QWidget *_widget)
Visualizes a property.