MeshRepairPlugin.cc 17.2 KB
Newer Older
1
/*===========================================================================*\
2 3
 *                                                                            *
 *                              OpenFlipper                                   *
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
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
39
 *                                                                            *
40 41 42 43
\*===========================================================================*/

#include "MeshRepairPlugin.hh"

44

45 46
//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
47 48 49 50 51 52 53 54
MeshRepairPlugin::MeshRepairPlugin() :
tool_(0),
toolIcon_(0)
{

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

55 56 57 58 59 60 61
void
MeshRepairPlugin::
initializePlugin()
{
  tool_ = new MeshRepairToolbarWidget();
  QSize size(300, 300);
  tool_->resize(size);
62

Jan Möbius's avatar
Jan Möbius committed
63 64 65
  //==================
  // Vertex operations
  //==================
66

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

Jan Möbius's avatar
Jan Möbius committed
70 71 72 73
  //==================
  // Edge operations
  //==================

74
  connect(tool_->detectEShorterButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesShorter()) );
75
  connect(tool_->detectELargerButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesLonger()) );
76
  connect(tool_->repairCollapseEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedEdges()) );
77 78
  connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectSkinnyTriangleByAngle()) );
  connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSkinnyTriangleByAngle()) );
79
  connect(tool_->detectFoldoverButton, SIGNAL(clicked()), this, SLOT(slotDetectFoldover()) );
80

Jan Möbius's avatar
Jan Möbius committed
81 82 83
  //==================
  // Face operations
  //==================
84 85 86
  connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect()));
  connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation()));

87
  //==================
Jan Möbius's avatar
Jan Möbius committed
88
  // Normal operations
89
  //==================
90 91 92
  connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals()));
  connect(tool_->computeVertexNormals,SIGNAL(clicked()),this,SLOT(slotUpdateVertexNormals()));
  connect(tool_->computeFaceNormals,SIGNAL(clicked()),this,SLOT(slotUpdateFaceNormals()));
93
  connect(tool_->computeHalfedgeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateHalfedgeNormals()));
94

95 96 97
  //==================
  // General
  //==================
Jan Möbius's avatar
Jan Möbius committed
98
  connect(tool_->snapBoundaryButton, SIGNAL(clicked()), this, SLOT(slotSnapBoundary()) );
99
  connect(tool_->fixNonManifoldVerticesButton,SIGNAL(clicked()),this,SLOT(slotFixNonManifoldVertices()));
Jan Möbius's avatar
Jan Möbius committed
100 101
  connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh()));

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

103 104 105 106
  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"meshrepair-toolbox.png");
  tool_->repairCollapseEButton->setIcon(*toolIcon_);
  tool_->repairFlipEButton->setIcon(*toolIcon_);
  tool_->repairRemoveVButton->setIcon(*toolIcon_);
107

108 109 110
  emit addToolbox( tr("Mesh Repair") , tool_,  toolIcon_);
}

111 112 113
//===========================================================================
// Button Slots
//===========================================================================
114

115
void MeshRepairPlugin::slotRemoveSelectedVal3Vertices() {
116

117
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
118
    removeSelectedVal3Vertices(o_it->id());
119

120
  emit updateView();
121 122 123 124 125
}

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

void MeshRepairPlugin::slotRemoveSelectedEdges(){
126

127 128
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it) 
    removeSelectedEdges(o_it->id());
129

130 131 132
  emit updateView();
}

133 134 135
//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotDetectSkinnyTriangleByAngle()
136
{
137
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
138
    detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), false );
139

140 141 142
  emit updateView();
}

143 144 145
//-----------------------------------------------------------------------------

void MeshRepairPlugin::slotRemoveSkinnyTriangleByAngle()
146
{
147
  //rewrite!!!
148
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
149
    detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), true );
150

151 152 153 154 155 156 157
  emit updateView();
}

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

void MeshRepairPlugin::slotDetectFoldover() {

158
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
159
    detectFoldover(o_it->id(), tool_->detectFoldoverSpinbox->value());
160 161

  emit updateView();
162 163 164 165 166 167
}

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

void MeshRepairPlugin::slotDetectTriangleAspect() {

168
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
169
    detectTriangleAspect(o_it->id(), tool_->triangleAspectSpinbox->value());
170 171 172 173

  emit updateView();
}

174
//-----------------------------------------------------------------------------
175 176 177 178 179 180 181 182 183 184 185

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
186 187 188 189 190 191 192 193 194 195 196 197
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();

}

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

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
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();
}

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

216 217 218 219 220 221 222 223 224
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();
}

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

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
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
254 255 256 257 258 259 260 261 262 263 264
//-----------------------------------------------------------------------------

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();
}

265 266 267 268 269 270 271 272 273 274
//-----------------------------------------------------------------------------

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();
}

275 276
//-----------------------------------------------------------------------------

277
void MeshRepairPlugin::slotFixNonManifoldVertices()
278 279
{
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) );  o_it != PluginFunctions::objectsEnd(); ++o_it)
280
    fixNonManifoldVertices(o_it->id());
281 282 283
  emit updateView();
}

284 285 286 287 288 289 290 291

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

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

Jan Möbius's avatar
Jan Möbius committed
292 293 294
  // ===============================
  // Vertex Operations
  // ===============================
295 296 297 298 299

  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
300
  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"),
301
                          QString(tr("objectId,angle")).split(","),
Jan Möbius's avatar
Jan Möbius committed
302
                          QString(tr("ID of an object;the maximal angle between the adjacent faces")).split(";"));
Jan Möbius's avatar
Jan Möbius committed
303

Jan Möbius's avatar
Jan Möbius committed
304 305 306
  // ===============================
  // Edge Operations
  // ===============================
307 308

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

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

Jan Möbius's avatar
Jan Möbius committed
316 317 318
  emit setSlotDescription("removeSelectedEdges(int)",tr("Remove the selected edges"),
                          QStringList(tr("objectId")),
                          QStringList(tr("ID of an object")));
319

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

Jan Möbius's avatar
Jan Möbius committed
324 325 326
  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
327 328 329 330 331 332 333 334 335 336 337 338

  // ===============================
  // 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")));
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365


  // ===============================
  // 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
366 367 368 369
  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(";"));

370 371 372 373 374 375 376 377
  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(";"));

378 379
}

380 381