Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SmootherPlugin.cc
1 //=============================================================================
2 //
3 // OpenFlipper
4 // Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
5 // www.openflipper.org
6 //
7 //-----------------------------------------------------------------------------
8 //
9 // License
10 //
11 // OpenFlipper is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU Lesser General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // OpenFlipper is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public License
22 // along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
23 //
24 //-----------------------------------------------------------------------------
25 //
26 // $Revision$
27 // $Author$
28 // $Date$
29 //
30 //=============================================================================
31
32
33
34 #include "SmootherPlugin.hh"
35
36
37 #include <ObjectTypes/PolyMesh/PolyMesh.hh>
38 #include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
39
40 #include "OpenFlipper/BasePlugin/PluginFunctions.hh"
41
42 SmootherPlugin::SmootherPlugin() :
43 iterationsSpinbox_(0)
44 {
45
46 }
47
48 void SmootherPlugin::initializePlugin()
49 {
50 // Create the Toolbox Widget
51 QWidget* toolBox = new QWidget();
52
53 QPushButton* smoothButton = new QPushButton("&Smooth", toolBox);
54
55 iterationsSpinbox_ = new QSpinBox(toolBox);
56 iterationsSpinbox_->setMinimum(1);
57 iterationsSpinbox_->setMaximum(1000);
58 iterationsSpinbox_->setSingleStep(1);
59
60 QLabel* label = new QLabel("Iterations:");
61
62 QGridLayout* layout = new QGridLayout(toolBox);
63
64 layout->addWidget(label, 0, 0);
65 layout->addWidget(smoothButton, 1, 1);
66 layout->addWidget(iterationsSpinbox_, 0, 1);
67
68 layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding), 2, 0, 1, 2);
69
70 connect(smoothButton, SIGNAL(clicked()), this, SLOT(simpleLaplace()));
71
72 emit addToolbox(tr("Smoother"), toolBox);
73 }
74
78 void SmootherPlugin::simpleLaplace()
79 {
80
81 for (PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS); o_it != PluginFunctions::objectsEnd();
82 ++o_it) {
83
84 if (o_it->dataType(DATA_TRIANGLE_MESH)) {
85
86 // Get the mesh to work on
87 TriMesh* mesh = PluginFunctions::triMesh(*o_it);
88
89 // Property for the active mesh to store original point positions
90 OpenMesh::VPropHandleT<TriMesh::Point> origPositions;
91
92 // Add a property to the mesh to store original vertex positions
93 mesh->add_property(origPositions, "SmootherPlugin_Original_Positions");
94
95 for (int i = 0; i < iterationsSpinbox_->value(); ++i) {
96
97 // Copy original positions to backup ( in vertex property )
98 TriMesh::VertexIter v_it, v_end = mesh->vertices_end();
99 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
100 mesh->property(origPositions, v_it) = mesh->point(v_it);
101 }
102
103 // Do one smoothing step (For each point of the mesh ... )
104 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
105
106 TriMesh::Point point = TriMesh::Point(0.0, 0.0, 0.0);
107
108 // Flag, to skip boundary vertices
109 bool skip = false;
110
111 // ( .. for each outgoing halfedge .. )
112 TriMesh::VertexOHalfedgeIter voh_it(*mesh, v_it);
113
114 for (; voh_it; ++voh_it) {
115
116 // .. add the (original) position of the neighbour ( end of the outgoing halfedge )
117 point += mesh->property(origPositions, mesh->to_vertex_handle(voh_it));
118
119 // Check if the current Halfedge is a boundary halfedge
120 // If it is, abort and keep the current vertex position
121 if (mesh->is_boundary(*voh_it)) {
122 skip = true;
123 break;
124 }
125 }
126
127 // Devide by the valence of the current vertex
128 point /= mesh->valence(v_it);
129
130 if (!skip) {
131 // Set new position for the mesh if its not on the boundary
132 mesh->point(v_it) = point;
133 }
134 }
135
136 } // Iterations end
137
138 // Remove the property
139 mesh->remove_property(origPositions);
140
141 mesh->update_normals();
142
143 emit updatedObject(o_it->id(),UPDATE_GEOMETRY);
144
145 } else if (o_it->dataType(DATA_POLY_MESH)) {
146
147 // Get the mesh to work on
148 PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
149
150 // Property for the active mesh to store original point positions
151 OpenMesh::VPropHandleT<PolyMesh::Point> origPositions;
152
153 // Add a property to the mesh to store original vertex positions
154 mesh->add_property(origPositions, "SmootherPlugin_Original_Positions");
155
156 for (int i = 0; i < iterationsSpinbox_->value(); ++i) {
157
158 // Copy original positions to backup ( in Vertex property )
159 PolyMesh::VertexIter v_it, v_end = mesh->vertices_end();
160 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
161 mesh->property(origPositions, v_it) = mesh->point(v_it);
162 }
163
164 // Do one smoothing step (For each point of the mesh ... )
165 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
166
167 PolyMesh::Point point = PolyMesh::Point(0.0, 0.0, 0.0);
168
169 // Flag, to skip boundary vertices
170 bool skip = false;
171
172 // ( .. for each Outoing halfedge .. )
173 PolyMesh::VertexOHalfedgeIter voh_it(*mesh, v_it);
174 for (; voh_it; ++voh_it) {
175 // .. add the (original) position of the Neighbour ( end of the outgoing halfedge )
176 point += mesh->property(origPositions, mesh->to_vertex_handle(voh_it));
177
178 // Check if the current Halfedge is a boundary halfedge
179 // If it is, abort and keep the current vertex position
180 if (mesh->is_boundary(*voh_it)) {
181 skip = true;
182 break;
183 }
184
185 }
186
187 // Devide by the valence of the current vertex
188 point /= mesh->valence(v_it);
189
190 if (!skip) {
191 // Set new position for the mesh if its not on the boundary
192 mesh->point(v_it) = point;
193 }
194 }
195
196 } // Iterations end
197
198 // Remove the property
199 mesh->remove_property(origPositions);
200
201 mesh->update_normals();
202
203 emit updatedObject(o_it->id(),UPDATE_GEOMETRY);
204
205 } else {
206
207 emit log(LOGERR, "Data type not supported.");
208
209 } // Switch data type
210 }
211 }
212
213 Q_EXPORT_PLUGIN2( smootherplugin, SmootherPlugin);
214
SmootherPlugin
Definition: SmootherPlugin.hh:9
UPDATE_GEOMETRY
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
OpenMesh::PolyMesh_ArrayKernelT
Definition: PolyMesh_ArrayKernelT.hh:98
LOGERR
Definition: LoggingInterface.hh:107
TriangleMesh.hh
PluginFunctions::polyMesh
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Definition: PluginFunctionsPolyMesh.cc:134
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
PluginFunctions::TARGET_OBJECTS
const QStringList TARGET_OBJECTS("target")
Iterable object range.
PluginFunctions::triMesh
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
Definition: PluginFunctionsTriangleMesh.cc:140
SmootherPlugin::simpleLaplace
void simpleLaplace()
simpleLaplace
Definition: SmootherPlugin.cc:78
OpenMesh::VPropHandleT
Definition: Property.hh:487
PluginFunctions::ObjectIterator
Core Data Iterator.
Definition: PluginFunctions.hh:452
PluginFunctions::objectsEnd
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Definition: PluginFunctionsIterator.cc:187
DATA_POLY_MESH
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
OpenMesh::PolyMeshT::VertexOHalfedgeIter
Kernel::VertexOHalfedgeIter VertexOHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:166
PolyMesh.hh
OpenMesh::PolyMeshT::update_normals
void update_normals()
Compute normals for all primitives.
Definition: PolyMeshT.cc:241
SmootherPlugin::iterationsSpinbox_
QSpinBox * iterationsSpinbox_
SpinBox for Number of iterations.
Definition: SmootherPlugin.hh:34
PluginFunctions.hh
DATA_TRIANGLE_MESH
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66