SmootherPlugin.cc 8.54 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
 *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  OpenFlipper is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenFlipper is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46



#include "SmootherPlugin.hh"

Dirk Wilden's avatar
   
Dirk Wilden committed
47
48
49

#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
Jan Möbius's avatar
 
Jan Möbius committed
50
51
52

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

Jan Möbius's avatar
Jan Möbius committed
53
void SmootherPlugin::initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
54
55
{
   // Create the Toolbox Widget
Dirk Wilden's avatar
   
Dirk Wilden committed
56
   QWidget* toolBox = new QWidget();
57

Dirk Wilden's avatar
   
Dirk Wilden committed
58
   QGridLayout* layout = new QGridLayout(toolBox);
59

Dirk Wilden's avatar
   
Dirk Wilden committed
60
   QPushButton* smoothButton = new QPushButton("&Smooth",toolBox);
61

Dirk Wilden's avatar
   
Dirk Wilden committed
62
   iterationsSpinbox_ =  new QSpinBox(toolBox) ;
Jan Möbius's avatar
 
Jan Möbius committed
63
64
65
   iterationsSpinbox_->setMinimum(1);
   iterationsSpinbox_->setMaximum(1000);
   iterationsSpinbox_->setSingleStep(1);
66

Dirk Wilden's avatar
   
Dirk Wilden committed
67
68
69
70
71
   QLabel* label = new QLabel("Iterations:");

   layout->addWidget( label             , 0, 0);
   layout->addWidget( smoothButton      , 1, 1);
   layout->addWidget( iterationsSpinbox_, 0, 1);
72

Dirk Wilden's avatar
   
Dirk Wilden committed
73
   layout->addItem(new QSpacerItem(10,10,QSizePolicy::Expanding,QSizePolicy::Expanding),2,0,1,2);
74

Dirk Wilden's avatar
   
Dirk Wilden committed
75
   connect( smoothButton, SIGNAL(clicked()), this, SLOT(simpleLaplace()) );
76

Jan Möbius's avatar
Jan Möbius committed
77
   emit addToolbox( tr("Simple Smoother") , toolBox );
Jan Möbius's avatar
 
Jan Möbius committed
78
79
}

80
81
/** \brief
 *
Dirk Wilden's avatar
   
Dirk Wilden committed
82
 */
Jan Möbius's avatar
 
Jan Möbius committed
83
void SmootherPlugin::simpleLaplace() {
84
85


Dirk Wilden's avatar
   
Dirk Wilden committed
86
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) {
87

Dirk Wilden's avatar
   
Dirk Wilden committed
88
    if ( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
89

Dirk Wilden's avatar
   
Dirk Wilden committed
90
        // Get the mesh to work on
Jan Möbius's avatar
 
Jan Möbius committed
91
      TriMesh* mesh = PluginFunctions::triMesh(*o_it);
92

Dirk Wilden's avatar
   
Dirk Wilden committed
93
94
      // Property for the active mesh to store original point positions
      OpenMesh::VPropHandleT< TriMesh::Point > origPositions;
95

Jan Möbius's avatar
 
Jan Möbius committed
96
      // Add a property to the mesh to store original vertex positions
Dirk Wilden's avatar
   
Dirk Wilden committed
97
      mesh->add_property( origPositions, "SmootherPlugin_Original_Positions" );
98

Jan Möbius's avatar
 
Jan Möbius committed
99
      for ( int i = 0 ; i < iterationsSpinbox_->value() ; ++i ) {
100

Dirk Wilden's avatar
   
Dirk Wilden committed
101
102
103
104
105
          // Copy original positions to backup ( in Vertex property )
          TriMesh::VertexIter v_it, v_end=mesh->vertices_end();
          for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
            mesh->property( origPositions, v_it ) = mesh->point(v_it);
          }
106

Dirk Wilden's avatar
   
Dirk Wilden committed
107
108
          // Do one smoothing step (For each point of the mesh ... )
          for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
109

Jan Möbius's avatar
 
Jan Möbius committed
110
            TriMesh::Point point = TriMesh::Point(0.0,0.0,0.0);
111

Jan Möbius's avatar
 
Jan Möbius committed
112
113
            // Flag, to skip boundary vertices
            bool skip = false;
114

Jan Möbius's avatar
 
Jan Möbius committed
115
116
117
            // ( .. for each Outoing halfedge .. )
            TriMesh::VertexOHalfedgeIter voh_it(*mesh,v_it);
            for ( ; voh_it; ++voh_it ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
118
119
                // .. add the (original) position of the Neighbour ( end of the outgoing halfedge )
                point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
120

Dirk Wilden's avatar
   
Dirk Wilden committed
121
122
123
                // Check if the current Halfedge is a boundary halfedge
                // If it is, abort and keep the current vertex position
                if ( mesh->is_boundary( voh_it.handle() ) ) {
Jan Möbius's avatar
 
Jan Möbius committed
124
                  skip = true;
125
                  break;
Dirk Wilden's avatar
   
Dirk Wilden committed
126
                }
127

Jan Möbius's avatar
 
Jan Möbius committed
128
            }
129

Jan Möbius's avatar
 
Jan Möbius committed
130
131
            // Devide by the valence of the current vertex
            point /= mesh->valence( v_it );
132

Jan Möbius's avatar
 
Jan Möbius committed
133
            if ( ! skip ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
134
135
                // Set new position for the mesh if its not on the boundary
                mesh->point(v_it) = point;
Jan Möbius's avatar
 
Jan Möbius committed
136
            }
Dirk Wilden's avatar
   
Dirk Wilden committed
137
          }
138

Jan Möbius's avatar
 
Jan Möbius committed
139
      }// Iterations end
140

Jan Möbius's avatar
 
Jan Möbius committed
141
      // Remove the property
Dirk Wilden's avatar
   
Dirk Wilden committed
142
      mesh->remove_property( origPositions );
143

Jan Möbius's avatar
 
Jan Möbius committed
144
      mesh->update_normals();
145

Jan Möbius's avatar
   
Jan Möbius committed
146
      emit updatedObject( o_it->id() );
147

Dirk Wilden's avatar
   
Dirk Wilden committed
148

149
   } else if ( o_it->dataType( DATA_POLY_MESH ) ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
150

Jan Möbius's avatar
 
Jan Möbius committed
151
       // Get the mesh to work on
152
      PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
153

Dirk Wilden's avatar
   
Dirk Wilden committed
154
155
156
      // Property for the active mesh to store original point positions
      OpenMesh::VPropHandleT< TriMesh::Point > origPositions;

Jan Möbius's avatar
 
Jan Möbius committed
157
      // Add a property to the mesh to store original vertex positions
Dirk Wilden's avatar
   
Dirk Wilden committed
158
      mesh->add_property( origPositions, "SmootherPlugin_Original_Positions" );
159

Jan Möbius's avatar
 
Jan Möbius committed
160
      for ( int i = 0 ; i < iterationsSpinbox_->value() ; ++i ) {
161

Jan Möbius's avatar
 
Jan Möbius committed
162
163
164
         // Copy original positions to backup ( in Vertex property )
         PolyMesh::VertexIter v_it, v_end=mesh->vertices_end();
         for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
Dirk Wilden's avatar
   
Dirk Wilden committed
165
            mesh->property( origPositions, v_it ) = mesh->point(v_it);
Jan Möbius's avatar
 
Jan Möbius committed
166
         }
167

Jan Möbius's avatar
 
Jan Möbius committed
168
169
         // Do one smoothing step (For each point of the mesh ... )
         for (v_it=mesh->vertices_begin(); v_it!=v_end; ++v_it) {
170

Jan Möbius's avatar
 
Jan Möbius committed
171
            PolyMesh::Point point = PolyMesh::Point(0.0,0.0,0.0);
172

Jan Möbius's avatar
 
Jan Möbius committed
173
174
            // Flag, to skip boundary vertices
            bool skip = false;
175

Jan Möbius's avatar
 
Jan Möbius committed
176
177
178
179
            // ( .. for each Outoing halfedge .. )
            PolyMesh::VertexOHalfedgeIter voh_it(*mesh,v_it);
            for ( ; voh_it; ++voh_it ) {
               // .. add the (original) position of the Neighbour ( end of the outgoing halfedge )
Dirk Wilden's avatar
   
Dirk Wilden committed
180
               point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
181

Jan Möbius's avatar
 
Jan Möbius committed
182
183
184
185
               // Check if the current Halfedge is a boundary halfedge
               // If it is, abort and keep the current vertex position
               if ( mesh->is_boundary( voh_it.handle() ) ) {
                  skip = true;
186
                  break;
Jan Möbius's avatar
 
Jan Möbius committed
187
               }
188

Jan Möbius's avatar
 
Jan Möbius committed
189
            }
190

Jan Möbius's avatar
 
Jan Möbius committed
191
192
            // Devide by the valence of the current vertex
            point /= mesh->valence( v_it );
193

Jan Möbius's avatar
 
Jan Möbius committed
194
195
196
197
198
            if ( ! skip ) {
               // Set new position for the mesh if its not on the boundary
               mesh->point(v_it) = point;
            }
         }
199

Jan Möbius's avatar
 
Jan Möbius committed
200
      }// Iterations end
201

Jan Möbius's avatar
 
Jan Möbius committed
202
      // Remove the property
Dirk Wilden's avatar
   
Dirk Wilden committed
203
      mesh->remove_property( origPositions );
204

Jan Möbius's avatar
 
Jan Möbius committed
205
      mesh->update_normals();
206

Jan Möbius's avatar
   
Jan Möbius committed
207
      emit updatedObject( o_it->id() );
208

Dirk Wilden's avatar
   
Dirk Wilden committed
209
    } else {
Jan Möbius's avatar
 
Jan Möbius committed
210

Dirk Wilden's avatar
   
Dirk Wilden committed
211
212
      emit log(LOGERR, "DataType not supported.");
    }
Jan Möbius's avatar
 
Jan Möbius committed
213
214
215
216
217
218
  }
}


Q_EXPORT_PLUGIN2( smootherplugin , SmootherPlugin );