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 {
71 MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
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>
85 void OMPropertyVisualizer<MeshT>::removeProperty_stage2() {
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>
93 inline void OMPropertyVisualizer<MeshT>::removeProperty_stage1() {
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>
128 inline void OMPropertyVisualizer<MeshT>::duplicateProperty_stage1() {
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>
142 QString OMPropertyVisualizer<MeshT>::getPropertyText(unsigned int index)
143 {
144 return "";
145 }
146
147
148 template <typename MeshT>
149 void OMPropertyVisualizer<MeshT>::setDrawMode(const ACG::SceneGraph::DrawModes::DrawMode& _mode)
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>
172 int OMPropertyVisualizer<MeshT>::getEntityCount()
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>
185 QString OMPropertyVisualizer<MeshT>::getHeader()
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>
343 void OMPropertyVisualizer<MeshT>::clear()
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>
380 void OMPropertyVisualizer<MeshT>::clearFaceProp()
381 {
382 if ( mesh->has_face_colors() )
383 OMPropertyVisualizer<MeshT>::mesh->release_face_colors();
384 }
385
386 template <typename MeshT>
387 void OMPropertyVisualizer<MeshT>::clearEdgeProp()
388 {
389 if ( mesh->has_edge_colors() )
390 OMPropertyVisualizer<MeshT>::mesh->release_edge_colors();
391 }
392
393 template <typename MeshT>
394 void OMPropertyVisualizer<MeshT>::clearHalfedgeProp()
395 {
396 if ( mesh->has_halfedge_colors() )
397 OMPropertyVisualizer<MeshT>::mesh->release_halfedge_colors();
398 }
399
400 template <typename MeshT>
401 void OMPropertyVisualizer<MeshT>::clearVertexProp()
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>
434 void OMPropertyVisualizer<MeshT>::showHistogram(ACG::QtWidgets::QtHistogramWidget *histogramWidget) {
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 }
LOGERR
Definition: LoggingInterface.hh:96
OpenMesh::VPropHandleT
Definition: Property.hh:484
OMPropertyVisualizer::getClosestPrimitiveId
unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint)
Returns the ID of the closest primitive.
Definition: OMPropertyVisualizerT_impl.hh:210
OpenMesh::HPropHandleT
Definition: Property.hh:499
OpenMesh::EPropHandleT
Definition: Property.hh:514
PluginFunctions::getObject
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Definition: PluginFunctions.cc:296
OMPropertyVisualizer::visualize
virtual void visualize(bool _setDrawMode, QWidget *_widget)
Visualizes the property.
Definition: OMPropertyVisualizerT_impl.hh:313
OMPropertyVisualizer::setPropertyFromText
virtual void setPropertyFromText(unsigned int index, QString text)
Returns the value of a property in text form.
Definition: OMPropertyVisualizerT_impl.hh:159
OpenMesh::VectorT
Definition: Vector11T.hh:83
OMPropertyVisualizer
Definition: OMPropertyVisualizer.hh:55
BaseObjectData::setObjectDrawMode
void setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, const bool &_force=false)
Set the draw mode for the object.
Definition: BaseObjectData.cc:298
OMPropertyVisualizer::getEntityCount
virtual int getEntityCount()
Returns the number of entities.
Definition: OMPropertyVisualizerT_impl.hh:172
PropertyInfo
Cellection of information about a property.
Definition: Utils.hh:109
OMPropertyVisualizer::clear
virtual void clear()
Clears the property.
Definition: OMPropertyVisualizerT_impl.hh:343
ACG::QtWidgets::QtHistogramWidget
Definition: QtHistogramWidget.hh:57
BaseObjectData
Definition: BaseObjectData.hh:102
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:288
OpenMesh::FPropHandleT
Definition: Property.hh:529
OMPropertyVisualizer::getHeader
virtual QString getHeader()
Returns the header for saving.
Definition: OMPropertyVisualizerT_impl.hh:185
OMPropertyVisualizer::getPropertyText
virtual QString getPropertyText(unsigned int index)
Returns the value of a property in text form.
Definition: OMPropertyVisualizerT_impl.hh:142
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121