Developer Documentation
Loading...
Searching...
No Matches
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//
27//=============================================================================
28
29
30
31#include "SmootherPlugin.hh"
32
33
36
38
39SmootherPlugin::SmootherPlugin() :
40 iterationsSpinbox_(0)
41{
42
43}
44
45void SmootherPlugin::initializePlugin()
46{
47 // Create the Toolbox Widget
48 QWidget* toolBox = new QWidget();
49
50 QPushButton* smoothButton = new QPushButton("&Smooth", toolBox);
51
52 iterationsSpinbox_ = new QSpinBox(toolBox);
53 iterationsSpinbox_->setMinimum(1);
54 iterationsSpinbox_->setMaximum(1000);
55 iterationsSpinbox_->setSingleStep(1);
56
57 QLabel* label = new QLabel("Iterations:");
58
59 QGridLayout* layout = new QGridLayout(toolBox);
60
61 layout->addWidget(label, 0, 0);
62 layout->addWidget(smoothButton, 1, 1);
63 layout->addWidget(iterationsSpinbox_, 0, 1);
64
65 layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding), 2, 0, 1, 2);
66
67 connect(smoothButton, SIGNAL(clicked()), this, SLOT(simpleLaplace()));
68
69 emit addToolbox(tr("Smoother"), toolBox);
70}
71
76{
77
79 ++o_it) {
80
81 if (o_it->dataType(DATA_TRIANGLE_MESH)) {
82
83 // Get the mesh to work on
84 TriMesh* mesh = PluginFunctions::triMesh(*o_it);
85
86 // Property for the active mesh to store original point positions
88
89 // Add a property to the mesh to store original vertex positions
90 mesh->add_property(origPositions, "SmootherPlugin_Original_Positions");
91
92 for (int i = 0; i < iterationsSpinbox_->value(); ++i) {
93
94 // Copy original positions to backup ( in vertex property )
95 TriMesh::VertexIter v_it, v_end = mesh->vertices_end();
96 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
97 mesh->property(origPositions, *v_it) = mesh->point(*v_it);
98 }
99
100 // Do one smoothing step (For each point of the mesh ... )
101 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
102
103 TriMesh::Point point = TriMesh::Point(0.0, 0.0, 0.0);
104
105 // Flag, to skip boundary vertices
106 bool skip = false;
107
108 // ( .. for each outgoing halfedge .. )
109 TriMesh::VertexOHalfedgeIter voh_it(*mesh, *v_it);
110
111 for (; voh_it.is_valid(); ++voh_it) {
112
113 // .. add the (original) position of the neighbour ( end of the outgoing halfedge )
114 point += mesh->property(origPositions, mesh->to_vertex_handle(*voh_it));
115
116 // Check if the current Halfedge is a boundary halfedge
117 // If it is, abort and keep the current vertex position
118 if (mesh->is_boundary(*voh_it)) {
119 skip = true;
120 break;
121 }
122 }
123
124 // Devide by the valence of the current vertex
125 point /= mesh->valence(*v_it);
126
127 if (!skip) {
128 // Set new position for the mesh if its not on the boundary
129 mesh->point(*v_it) = point;
130 }
131 }
132
133 } // Iterations end
134
135 // Remove the property
136 mesh->remove_property(origPositions);
137
138 mesh->update_normals();
139
140 emit updatedObject(o_it->id(),UPDATE_GEOMETRY);
141
142 } else if (o_it->dataType(DATA_POLY_MESH)) {
143
144 // Get the mesh to work on
145 PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
146
147 // Property for the active mesh to store original point positions
149
150 // Add a property to the mesh to store original vertex positions
151 mesh->add_property(origPositions, "SmootherPlugin_Original_Positions");
152
153 for (int i = 0; i < iterationsSpinbox_->value(); ++i) {
154
155 // Copy original positions to backup ( in Vertex property )
156 PolyMesh::VertexIter v_it, v_end = mesh->vertices_end();
157 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
158 mesh->property(origPositions, *v_it) = mesh->point(*v_it);
159 }
160
161 // Do one smoothing step (For each point of the mesh ... )
162 for (v_it = mesh->vertices_begin(); v_it != v_end; ++v_it) {
163
164 PolyMesh::Point point = PolyMesh::Point(0.0, 0.0, 0.0);
165
166 // Flag, to skip boundary vertices
167 bool skip = false;
168
169 // ( .. for each Outoing halfedge .. )
170 PolyMesh::VertexOHalfedgeIter voh_it(*mesh, *v_it);
171 for (; voh_it.is_valid(); ++voh_it) {
172 // .. add the (original) position of the Neighbour ( end of the outgoing halfedge )
173 point += mesh->property(origPositions, mesh->to_vertex_handle(*voh_it));
174
175 // Check if the current Halfedge is a boundary halfedge
176 // If it is, abort and keep the current vertex position
177 if (mesh->is_boundary(*voh_it)) {
178 skip = true;
179 break;
180 }
181
182 }
183
184 // Devide by the valence of the current vertex
185 point /= mesh->valence(*v_it);
186
187 if (!skip) {
188 // Set new position for the mesh if its not on the boundary
189 mesh->point(*v_it) = point;
190 }
191 }
192
193 } // Iterations end
194
195 // Remove the property
196 mesh->remove_property(origPositions);
197
198 mesh->update_normals();
199
200 emit updatedObject(o_it->id(),UPDATE_GEOMETRY);
201
202 } else {
203
204 emit log(LOGERR, "Data type not supported.");
205
206 } // Switch data type
207 }
208}
209
@ LOGERR
#define DATA_POLY_MESH
Definition PolyMesh.hh:59
#define DATA_TRIANGLE_MESH
void update_normals()
Compute normals for all primitives.
Kernel::VertexOHalfedgeIter VertexOHalfedgeIter
Circulator.
Definition PolyMeshT.hh:163
Kernel::Point Point
Coordinate type.
Definition PolyMeshT.hh:112
Kernel::VertexIter VertexIter
Scalar type.
Definition PolyMeshT.hh:143
void simpleLaplace()
simpleLaplace
QSpinBox * iterationsSpinbox_
SpinBox for Number of iterations.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
const QStringList TARGET_OBJECTS("target")
Iterable object range.