Developer Documentation
LaplacePlugin.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 
45 #include "LaplacePlugin.hh"
46 
50 
51 #include <QElapsedTimer>
52 
53 #ifdef USE_OPENMP
54 #endif
55 
56 
57 #define UNIFORM_LAPLACE_NAME "Uniform Laplace Length"
58 #define UNIFORM_LAPLACE_SQUARED_NAME "Uniform Laplace Squared Length"
59 
60 void LaplaceLengthPlugin::pluginsInitialized()
61 {
62  emit addTexture( UNIFORM_LAPLACE_NAME , "laplace_length.png" , 1 );
63  emit setTextureMode(UNIFORM_LAPLACE_NAME,"clamp=true,center=true,repeat=false,clamp_min=-20,clamp_max=20");
64 
65  emit addTexture( UNIFORM_LAPLACE_SQUARED_NAME , "laplace_length.png" , 1 );
66  emit setTextureMode(UNIFORM_LAPLACE_SQUARED_NAME,"clamp=true,center=true,repeat=false,clamp_min=-20,clamp_max=20");
67 }
68 
69 void LaplaceLengthPlugin::slotUpdateTexture( QString _textureName , int _identifier )
70 {
71  if ( (_textureName != UNIFORM_LAPLACE_SQUARED_NAME) && (_textureName != UNIFORM_LAPLACE_NAME ) ) {
72  return;
73  }
74 
75  BaseObjectData* object;
76  if (! PluginFunctions::getObject( _identifier , object ) ) {
77  return;
78  }
79 
80  if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
81  TriMesh* mesh = PluginFunctions::triMesh(object);
82  if ( _textureName == UNIFORM_LAPLACE_NAME ) {
83  computeLaplaceLength(mesh);
84  emit updatedTextures(UNIFORM_LAPLACE_NAME,_identifier);
85  }
86  if ( _textureName == UNIFORM_LAPLACE_SQUARED_NAME ) {
87  computeLaplaceSquaredLength(mesh);
88  emit updatedTextures(UNIFORM_LAPLACE_SQUARED_NAME,_identifier);
89  }
90  }
91 
92  if ( object->dataType( DATA_POLY_MESH ) ) {
93  PolyMesh* mesh = PluginFunctions::polyMesh(object);
94  if ( _textureName == UNIFORM_LAPLACE_NAME ) {
95  computeLaplaceLength(mesh);
96  emit updatedTextures(UNIFORM_LAPLACE_NAME,_identifier);
97  }
98  if ( _textureName == UNIFORM_LAPLACE_SQUARED_NAME ) {
99  computeLaplaceSquaredLength(mesh);
100  emit updatedTextures(UNIFORM_LAPLACE_SQUARED_NAME,_identifier);
101  }
102  }
103 }
104 
105 template< typename MeshT >
106 void LaplaceLengthPlugin::computeLaplaceLength(MeshT* _mesh) {
107  OpenMesh::VPropHandleT< ACG::Vec3d > laplace_vector_property;
108  OpenMesh::VPropHandleT< double > laplace_length_property;
109 
110  if(!_mesh->get_property_handle( laplace_vector_property , "Laplace Vector" ))
111  _mesh->add_property( laplace_vector_property, "Laplace Vector" );
112 
113  if(!_mesh->get_property_handle( laplace_length_property , UNIFORM_LAPLACE_NAME ))
114  _mesh->add_property( laplace_length_property, UNIFORM_LAPLACE_NAME );
115 
116 
117  QElapsedTimer time;
118  time.start();
119  std::vector< typename MeshT::VertexHandle > handles;
120  handles.reserve(_mesh->n_vertices());
121  for ( typename MeshT::VertexIter v_it = _mesh->vertices_begin() ; v_it != _mesh->vertices_end(); ++v_it)
122  handles.push_back( *v_it );
123 
124  #ifdef USE_OPENMP
125  #pragma omp parallel for
126  #endif
127  for ( int i = 0 ; i < (int)handles.size(); ++i ) {
128  const typename MeshT::VertexHandle handle = handles[i];
129 
130  ACG::Vec3d laplace(0.0,0.0,0.0);
131  for ( typename MeshT::VertexVertexIter vv_it(*_mesh , handle) ; vv_it.is_valid() ; ++vv_it )
132  laplace += _mesh->point(*vv_it) - _mesh->point(handle);
133 
134  laplace = 1.0 /(double)_mesh->valence(handle) * laplace;
135  _mesh->property(laplace_vector_property,handle) = laplace;
136  _mesh->property(laplace_length_property,handle) = laplace.norm();
137  }
138 
139 // #ifdef USE_OPENMP
140 // std::cerr << "Laplace parallel took : " << time.elapsed() << std::endl;
141 // #else
142 // std::cerr << "Laplace sequential took : " << time.elapsed() << std::endl;
143 // #endif
144 
145 }
146 
147 template< typename MeshT >
148 void LaplaceLengthPlugin::computeLaplaceSquaredLength(MeshT* _mesh) {
149  computeLaplaceLength(_mesh);
150 
151  OpenMesh::VPropHandleT< ACG::Vec3d > laplace_property;
152  OpenMesh::VPropHandleT< double > laplace_squared;
153 
154  if(!_mesh->get_property_handle( laplace_property , "Laplace Vector" )) {
155  std::cerr << "LaplaceLengthPlugin : Unable to get Laplace Vector property" << std::endl;
156  return;
157  }
158 
159  if(!_mesh->get_property_handle( laplace_squared , UNIFORM_LAPLACE_SQUARED_NAME ))
160  _mesh->add_property( laplace_squared, UNIFORM_LAPLACE_SQUARED_NAME );
161 
162  QElapsedTimer time;
163  time.start();
164  std::vector< typename MeshT::VertexHandle > handles;
165  handles.reserve(_mesh->n_vertices());
166  for ( typename MeshT::VertexIter v_it = _mesh->vertices_begin() ; v_it != _mesh->vertices_end(); ++v_it)
167  handles.push_back( *v_it );
168 
169  #ifdef USE_OPENMP
170  #pragma omp parallel for
171  #endif
172  for ( int i = 0 ; i < (int)handles.size(); ++i ) {
173  const typename MeshT::VertexHandle handle = handles[i];
174 
175  ACG::Vec3d laplace(0.0,0.0,0.0);
176  for ( typename MeshT::VertexVertexIter vv_it(*_mesh , handle) ; vv_it.is_valid() ; ++vv_it )
177  laplace += _mesh->property(laplace_property,*vv_it) - _mesh->property(laplace_property,handle);
178  laplace = 1.0 /(double)_mesh->valence(handle) * laplace;
179  _mesh->property(laplace_squared,handle) = laplace.norm();
180  }
181 
182 // #ifdef USE_OPENMP
183 // std::cerr << "Laplace Squared parallel took : " << time.elapsed() << std::endl;
184 // #else
185 // std::cerr << "Laplace Squared sequential took : " << time.elapsed() << std::endl;
186 // #endif
187 }
188 
189 
190 
191 
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
bool dataType(DataType _type) const
Definition: BaseObject.cc:221