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"

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

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

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

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

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

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
78
79
80
   return true;
}

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


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

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

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

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

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

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

Dirk Wilden's avatar
   
Dirk Wilden committed
102
103
104
105
106
          // 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);
          }
107

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

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

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

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

Dirk Wilden's avatar
   
Dirk Wilden committed
122
123
124
                // 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
125
                  skip = true;
126
                  break;
Dirk Wilden's avatar
   
Dirk Wilden committed
127
                }
128

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

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

Jan Möbius's avatar
 
Jan Möbius committed
134
            if ( ! skip ) {
Dirk Wilden's avatar
   
Dirk Wilden committed
135
136
                // 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
137
            }
Dirk Wilden's avatar
   
Dirk Wilden committed
138
          }
139

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

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

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

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

Dirk Wilden's avatar
   
Dirk Wilden committed
149

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

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

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
163
164
165
         // 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
166
            mesh->property( origPositions, v_it ) = mesh->point(v_it);
Jan Möbius's avatar
 
Jan Möbius committed
167
         }
168

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
177
178
179
180
            // ( .. 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
181
               point += mesh->property( origPositions, mesh->to_vertex_handle(voh_it) );
182

Jan Möbius's avatar
 
Jan Möbius committed
183
184
185
186
               // 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;
187
                  break;
Jan Möbius's avatar
 
Jan Möbius committed
188
               }
189

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

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

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

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

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

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

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

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

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


Q_EXPORT_PLUGIN2( smootherplugin , SmootherPlugin );