MeshRepairPlugin.cc 17.4 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
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
 *                                                                            *
 *                              OpenFlipper                                   *
 *      Copyright (C) 2001-2011 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/>.                                       *
 *                                                                            *
Jan Möbius's avatar
 
Jan Möbius committed
33
34
35
\*===========================================================================*/

/*===========================================================================*\
36
37
38
39
40
 *                                                                            *
 *   $Revision$                                                       *
 *   $LastChangedBy$                                                *
 *   $Date$                     *
 *                                                                            *
Jan Möbius's avatar
 
Jan Möbius committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
\*===========================================================================*/

#include <QtGui>

#include "MeshRepairPlugin.hh"

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include "OpenFlipper/INIFile/INIFile.hh"

#include <ACG/Geometry/Algorithms.hh>
#include <Math_Tools/Math_Tools.hh>

//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
55
56
57
58
59
60
61
62
MeshRepairPlugin::MeshRepairPlugin() :
tool_(0),
toolIcon_(0)
{

}
//-----------------------------------------------------------------------------

Jan Möbius's avatar
 
Jan Möbius committed
63
64
65
66
67
68
69
void
MeshRepairPlugin::
initializePlugin()
{
  tool_ = new MeshRepairToolbarWidget();
  QSize size(300, 300);
  tool_->resize(size);
70

Jan Möbius's avatar
Jan Möbius committed
71
72
73
  //==================
  // Vertex operations
  //==================
74

Jan Möbius's avatar
Jan Möbius committed
75
  connect(tool_->valenceThreeButton, SIGNAL(clicked()), this, SLOT(slotDetectFlatValence3Vertices()) );
Jan Möbius's avatar
 
Jan Möbius committed
76
77
  connect(tool_->repairRemoveVButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedVal3Vertices()) );

Jan Möbius's avatar
Jan Möbius committed
78
79
80
81
  //==================
  // Edge operations
  //==================

Jan Möbius's avatar
 
Jan Möbius committed
82
  connect(tool_->detectEShorterButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesShorter()) );
83
  connect(tool_->detectELargerButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesLonger()) );
Jan Möbius's avatar
 
Jan Möbius committed
84
  connect(tool_->repairCollapseEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedEdges()) );
85
86
  connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectSkinnyTriangleByAngle()) );
  connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSkinnyTriangleByAngle()) );
Jan Möbius's avatar
 
Jan Möbius committed
87
  connect(tool_->detectFoldoverButton, SIGNAL(clicked()), this, SLOT(slotDetectFoldover()) );
88

Jan Möbius's avatar
Jan Möbius committed
89
90
91
  //==================
  // Face operations
  //==================
Jan Möbius's avatar
 
Jan Möbius committed
92
93
94
  connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect()));
  connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation()));

95
  //==================
Jan Möbius's avatar
Jan Möbius committed
96
  // Normal operations
97
  //==================
98
99
100
  connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals()));
  connect(tool_->computeVertexNormals,SIGNAL(clicked()),this,SLOT(slotUpdateVertexNormals()));
  connect(tool_->computeFaceNormals,SIGNAL(clicked()),this,SLOT(slotUpdateFaceNormals()));
101
  connect(tool_->computeHalfedgeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateHalfedgeNormals()));
102

103
104
105
  //==================
  // General
  //==================
Jan Möbius's avatar
Jan Möbius committed
106
  connect(tool_->snapBoundaryButton, SIGNAL(clicked()), this, SLOT(slotSnapBoundary()) );
107
  connect(tool_->fixNonManifoldVerticesButton,SIGNAL(clicked()),this,SLOT(slotFixNonManifoldVertices()));
Jan Möbius's avatar
Jan Möbius committed
108
109
  connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh()));

Jan Möbius's avatar
Jan Möbius committed
110

Jan Möbius's avatar
 
Jan Möbius committed
111
112
113
114
  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"meshrepair-toolbox.png");
  tool_->repairCollapseEButton->setIcon(*toolIcon_);
  tool_->repairFlipEButton->setIcon(*toolIcon_);
  tool_->repairRemoveVButton->setIcon(*toolIcon_);
115

Jan Möbius's avatar
 
Jan Möbius committed
116
117
118
  emit addToolbox( tr("Mesh Repair") , tool_,  toolIcon_);
}

119
120
121
//===========================================================================
// Button Slots
//===========================================================================
Jan Möbius's avatar
 
Jan Möbius committed
122

123
void MeshRepairPlugin::slotRemoveSelectedVal3Vertices() {
Jan Möbius's avatar
 
Jan Möbius committed
124

125
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
126
    removeSelectedVal3Vertices(o_it->id());
Jan Möbius's avatar
 
Jan Möbius committed
127

128
  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
129
130
131
132
133
}

//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotRemoveSelectedEdges(){
134

Jan Möbius's avatar
 
Jan Möbius committed
135
136
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it) 
    removeSelectedEdges(o_it->id());
137

Jan Möbius's avatar
 
Jan Möbius committed
138
139
140
  emit updateView();
}

141
142
143
//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectSkinnyTriangleByAngle()
Jan Möbius's avatar
 
Jan Möbius committed
144
{
145
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
146
    detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), false );
147

Jan Möbius's avatar
 
Jan Möbius committed
148
149
150
  emit updateView();
}

151
152
153
//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotRemoveSkinnyTriangleByAngle()
Jan Möbius's avatar
 
Jan Möbius committed
154
{
155
  //rewrite!!!
156
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
157
    detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), true );
158

Jan Möbius's avatar
 
Jan Möbius committed
159
160
161
162
163
164
165
  emit updateView();
}

//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectFoldover() {

166
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
167
    detectFoldover(o_it->id(), tool_->detectFoldoverSpinbox->value());
168
169

  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
170
171
172
173
174
175
}

//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectTriangleAspect() {

176
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
177
    detectTriangleAspect(o_it->id(), tool_->triangleAspectSpinbox->value());
178
179
180
181

  emit updateView();
}

182
//-----------------------------------------------------------------------------
183
184
185
186
187
188
189
190
191
192
193

void MeshRepairPlugin::slotFlipOrientation(){

  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    flipOrientation(o_it->id());

  emit updateView();
}

//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
194
195
196
197
198
199
200
201
202
203
204
205
void MeshRepairPlugin::slotFixMesh() {


  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    fixMesh(o_it->id() , tool_->fixMeshBox->value() );

  emit updateView();

}

//-----------------------------------------------------------------------------

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
void MeshRepairPlugin::slotUpdateVertexNormals() {
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    updateVertexNormals(o_it->id());

  emit updateView();
}

//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotUpdateFaceNormals() {
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    updateFaceNormals(o_it->id());

  emit updateView();
}

//-----------------------------------------------------------------------------

224
225
226
227
228
229
230
231
232
void MeshRepairPlugin::slotUpdateHalfedgeNormals() {
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    updateHalfedgeNormals(o_it->id());

  emit updateView();
}

//-----------------------------------------------------------------------------

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
void MeshRepairPlugin::slotUpdateNormals(){
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    updateNormals(o_it->id());

  emit updateView();
}

//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectEdgesShorter(){
  double length = tool_->edgeSpin->value();

  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    selectEdgesShorterThan(o_it->id(),length);

  emit updateView();
}

//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectEdgesLonger(){
  double length = tool_->edgeSpin->value();

  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    selectEdgesLongerThan(o_it->id(),length);

  emit updateView();
}

Jan Möbius's avatar
Jan Möbius committed
262
263
264
265
266
267
268
269
270
271
272
//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectFlatValence3Vertices() {
  double angle = tool_->valenceThreeSpinbox->value();

  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
    detectFlatValence3Vertices(o_it->id(), angle);

  emit updateView();
}

273
274
275
276
277
278
279
280
281
282
//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotSnapBoundary()
{
  double eps = tool_->snapBoundarySpinBox->value();
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
      snapBoundary(o_it->id(), eps);
  emit updateView();
}

Matthias Möller's avatar
Matthias Möller committed
283
284
//-----------------------------------------------------------------------------

285
void MeshRepairPlugin::slotFixNonManifoldVertices()
Matthias Möller's avatar
Matthias Möller committed
286
287
{
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
288
    fixNonManifoldVertices(o_it->id());
Matthias Möller's avatar
Matthias Möller committed
289
290
291
  emit updateView();
}

292
293
294
295
296
297
298
299

//-----------------------------------------------------------------------------

/** \brief Initialization of the plugin when it is loaded by the core
 *
 */
void MeshRepairPlugin::pluginsInitialized() {

Jan Möbius's avatar
Jan Möbius committed
300
301
302
  // ===============================
  // Vertex Operations
  // ===============================
303
304
305
306
307

  emit setSlotDescription("removeSelectedVal3Vertices(int)",tr("Remove all selected valence 3 vertices"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));

Jan Möbius's avatar
Jan Möbius committed
308
  emit setSlotDescription("detectFlatValence3Vertices(int,double)",tr("Selects all vertices that have valence 3 and the normals of their neighboring faces have an angle less then the given angle"),
309
                          QString(tr("objectId,angle")).split(","),
Jan Möbius's avatar
Jan Möbius committed
310
                          QString(tr("ID of an object;the maximal angle between the adjacent faces")).split(";"));
Jan Möbius's avatar
Jan Möbius committed
311

Jan Möbius's avatar
Jan Möbius committed
312
313
314
  // ===============================
  // Edge Operations
  // ===============================
315
316

  emit setSlotDescription("selectEdgesShorterThan(int,double)",tr("Selects all edges of an object which are shorter than the given length"),
317
318
                          QString(tr("objectId,length")).split(","),
                          QString(tr("ID of an object;All edges shorter than this length will be selected")).split(";"));
319
320

  emit setSlotDescription("selectEdgesLongerThan(int,double)",tr("Selects all edges of an object which are longer than the given length"),
321
322
                          QString(tr("objectId,length")).split(","),
                          QString(tr("ID of an object;All edges longer than this length will be selected")).split(";"));
323

Jan Möbius's avatar
Jan Möbius committed
324
325
326
  emit setSlotDescription("removeSelectedEdges(int)",tr("Remove the selected edges"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));
327

Jan Möbius's avatar
Jan Möbius committed
328
  emit setSlotDescription("detectSkinnyTriangleByAngle(int,double,bool)",tr("Select or remove skinny triangles (determined by a minimum angle threshold)."),
329
                          QString(tr("objectId,angle,remove")).split(","),
Jan Möbius's avatar
Jan Möbius committed
330
                          QString(tr("ID of an object;Minimum angle threshold;Remove")).split(";"));
Jan Möbius's avatar
Jan Möbius committed
331

Jan Möbius's avatar
Jan Möbius committed
332
333
334
  emit setSlotDescription("detectFoldover(int,float)",tr("Selects edges that are incident to folded over faces."),
                          QString(tr("objectId,angle")).split(","),
                          QString(tr("ID of an object;Minimum threshold angle for fold-overs")).split(";"));
Jan Möbius's avatar
Jan Möbius committed
335
336
337
338
339
340
341
342
343
344
345
346

  // ===============================
  // Face Operations
  // ===============================

  emit setSlotDescription("detectTriangleAspect(int,float)",tr("Selects all faces that have a larger aspect ratio than the given one."),
                           QString(tr("objectId,aspect")).split(","),
                           QString(tr("ID of an object;The minimal aspect ratio to select")).split(";"));

  emit setSlotDescription("flipOrientation(int)",tr("Flips the normals of all faces by changing the vertex order in each face"),
                           QStringList(tr("objectId")),
                           QStringList(tr("ID of an object")));
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373


  // ===============================
  // Normal Fixing
  // ===============================

  emit setSlotDescription("updateFaceNormals(int)",tr("Recompute Face normals"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));

  emit setSlotDescription("updateHalfedgeNormals(int)",tr("Recompute Halfedge normals"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));

  emit setSlotDescription("updateVertexNormals(int)",tr("Recompute Vertex normals"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));

  emit setSlotDescription("updateNormals(int)",tr("Recompute Face and Vertex normals"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));


  // ===============================
  // General Mesh fixing
  // ===============================

Jan Möbius's avatar
Jan Möbius committed
374
375
376
377
  emit setSlotDescription("snapBoundary(int,double)",tr("Snaps selected boundary vertices if the distance is less than the given maximal distance."),
                           QString(tr("objectId,epsilon")).split(","),
                           QString(tr("ID of an object;Max Distance")).split(";"));

378
379
380
381
382
383
384
385
  emit setSlotDescription("(int)",tr("Fixes non manifold vertices."),
                            QString(tr("objectId")).split(","),
                            QString(tr("ID of an object;Non manifold vertices are splitted.")).split(";"));

  emit setSlotDescription("fixMesh(int,double)",tr("Fixes a mesh."),
                          QString(tr("objectId,distance")).split(","),
                          QString(tr("ID of an object;Vertices with distance lower than epsilon will be treated as one.")).split(";"));

386
387
}

Jan Möbius's avatar
 
Jan Möbius committed
388
Q_EXPORT_PLUGIN2( meshrepairplugin , MeshRepairPlugin );