Developer Documentation
MeshRepairPlugin.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision$ *
45  * $LastChangedBy$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 
51 #include "MeshRepairPlugin.hh"
52 
53 #if QT_VERSION >= 0x050000
54 #else
55 #include <QtGui>
56 #endif
57 
58 //-----------------------------------------------------------------------------
59 
60 MeshRepairPlugin::MeshRepairPlugin() :
61 tool_(0),
62 toolIcon_(0)
63 {
64 
65 }
66 //-----------------------------------------------------------------------------
67 
68 void
69 MeshRepairPlugin::
70 initializePlugin()
71 {
72  tool_ = new MeshRepairToolbarWidget();
73  QSize size(300, 300);
74  tool_->resize(size);
75 
76  //==================
77  // Vertex operations
78  //==================
79 
80  connect(tool_->valenceThreeButton, SIGNAL(clicked()), this, SLOT(slotDetectFlatValence3Vertices()) );
81  connect(tool_->repairRemoveVButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedVal3Vertices()) );
82 
83  //==================
84  // Edge operations
85  //==================
86 
87  connect(tool_->detectEShorterButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesShorter()) );
88  connect(tool_->detectELargerButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesLonger()) );
89  connect(tool_->repairCollapseEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedEdges()) );
90  connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectSkinnyTriangleByAngle()) );
91  connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSkinnyTriangleByAngle()) );
92  connect(tool_->detectFoldoverButton, SIGNAL(clicked()), this, SLOT(slotDetectFoldover()) );
93 
94  //==================
95  // Face operations
96  //==================
97  connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect()));
98  connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation()));
99 
100  //==================
101  // Normal operations
102  //==================
103  connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals()));
104  connect(tool_->computeVertexNormals,SIGNAL(clicked()),this,SLOT(slotUpdateVertexNormals()));
105  connect(tool_->computeFaceNormals,SIGNAL(clicked()),this,SLOT(slotUpdateFaceNormals()));
106  connect(tool_->computeHalfedgeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateHalfedgeNormals()));
107 
108  //==================
109  // General
110  //==================
111  connect(tool_->snapBoundaryButton, SIGNAL(clicked()), this, SLOT(slotSnapBoundary()) );
112  connect(tool_->fixNonManifoldVerticesButton,SIGNAL(clicked()),this,SLOT(slotFixNonManifoldVertices()));
113  connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh()));
114 
115 
116  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"meshrepair-toolbox.png");
117  tool_->repairCollapseEButton->setIcon(*toolIcon_);
118  tool_->repairFlipEButton->setIcon(*toolIcon_);
119  tool_->repairRemoveVButton->setIcon(*toolIcon_);
120 
121  emit addToolbox( tr("Mesh Repair") , tool_, toolIcon_);
122 }
123 
124 //===========================================================================
125 // Button Slots
126 //===========================================================================
127 
129 
131  removeSelectedVal3Vertices(o_it->id());
132 
133  emit updateView();
134 }
135 
136 //-----------------------------------------------------------------------------
137 
139 
141  removeSelectedEdges(o_it->id());
142 
143  emit updateView();
144 }
145 
146 //-----------------------------------------------------------------------------
147 
149 {
151  detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), false );
152 
153  emit updateView();
154 }
155 
156 //-----------------------------------------------------------------------------
157 
159 {
160  //rewrite!!!
162  detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), true );
163 
164  emit updateView();
165 }
166 
167 //-----------------------------------------------------------------------------
168 
170 
172  detectFoldover(o_it->id(), tool_->detectFoldoverSpinbox->value());
173 
174  emit updateView();
175 }
176 
177 //-----------------------------------------------------------------------------
178 
180 
182  detectTriangleAspect(o_it->id(), tool_->triangleAspectSpinbox->value());
183 
184  emit updateView();
185 }
186 
187 //-----------------------------------------------------------------------------
188 
190 
192  flipOrientation(o_it->id());
193 
194  emit updateView();
195 }
196 
197 //-----------------------------------------------------------------------------
198 
200 
201 
203  fixMesh(o_it->id() , tool_->fixMeshBox->value() );
204 
205  emit updateView();
206 
207 }
208 
209 //-----------------------------------------------------------------------------
210 
213  updateVertexNormals(o_it->id());
214 
215  emit updateView();
216 }
217 
218 //-----------------------------------------------------------------------------
219 
222  updateFaceNormals(o_it->id());
223 
224  emit updateView();
225 }
226 
227 //-----------------------------------------------------------------------------
228 
231  updateHalfedgeNormals(o_it->id());
232 
233  emit updateView();
234 }
235 
236 //-----------------------------------------------------------------------------
237 
240  updateNormals(o_it->id());
241 
242  emit updateView();
243 }
244 
245 //-----------------------------------------------------------------------------
246 
248  double length = tool_->edgeSpin->value();
249 
251  selectEdgesShorterThan(o_it->id(),length);
252 
253  emit updateView();
254 }
255 
256 //-----------------------------------------------------------------------------
257 
259  double length = tool_->edgeSpin->value();
260 
262  selectEdgesLongerThan(o_it->id(),length);
263 
264  emit updateView();
265 }
266 
267 //-----------------------------------------------------------------------------
268 
270  double angle = tool_->valenceThreeSpinbox->value();
271 
273  detectFlatValence3Vertices(o_it->id(), angle);
274 
275  emit updateView();
276 }
277 
278 //-----------------------------------------------------------------------------
279 
281 {
282  double eps = tool_->snapBoundarySpinBox->value();
284  snapBoundary(o_it->id(), eps);
285  emit updateView();
286 }
287 
288 //-----------------------------------------------------------------------------
289 
291 {
293  fixNonManifoldVertices(o_it->id());
294  emit updateView();
295 }
296 
297 
298 //-----------------------------------------------------------------------------
299 
304 
305  // ===============================
306  // Vertex Operations
307  // ===============================
308 
309  emit setSlotDescription("removeSelectedVal3Vertices(int)",tr("Remove all selected valence 3 vertices"),
310  QStringList(tr("objectId")),
311  QStringList(tr("ID of an object")));
312 
313  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"),
314  QString(tr("objectId,angle")).split(","),
315  QString(tr("ID of an object;the maximal angle between the adjacent faces")).split(";"));
316 
317  // ===============================
318  // Edge Operations
319  // ===============================
320 
321  emit setSlotDescription("selectEdgesShorterThan(int,double)",tr("Selects all edges of an object which are shorter than the given length"),
322  QString(tr("objectId,length")).split(","),
323  QString(tr("ID of an object;All edges shorter than this length will be selected")).split(";"));
324 
325  emit setSlotDescription("selectEdgesLongerThan(int,double)",tr("Selects all edges of an object which are longer than the given length"),
326  QString(tr("objectId,length")).split(","),
327  QString(tr("ID of an object;All edges longer than this length will be selected")).split(";"));
328 
329  emit setSlotDescription("removeSelectedEdges(int)",tr("Remove the selected edges"),
330  QStringList(tr("objectId")),
331  QStringList(tr("ID of an object")));
332 
333  emit setSlotDescription("detectSkinnyTriangleByAngle(int,double,bool)",tr("Select or remove skinny triangles (determined by a minimum angle threshold)."),
334  QString(tr("objectId,angle,remove")).split(","),
335  QString(tr("ID of an object;Minimum angle threshold;Remove")).split(";"));
336 
337  emit setSlotDescription("detectFoldover(int,float)",tr("Selects edges that are incident to folded over faces."),
338  QString(tr("objectId,angle")).split(","),
339  QString(tr("ID of an object;Minimum threshold angle for fold-overs")).split(";"));
340 
341  // ===============================
342  // Face Operations
343  // ===============================
344 
345  emit setSlotDescription("detectTriangleAspect(int,float)",tr("Selects all faces that have a larger aspect ratio than the given one."),
346  QString(tr("objectId,aspect")).split(","),
347  QString(tr("ID of an object;The minimal aspect ratio to select")).split(";"));
348 
349  emit setSlotDescription("flipOrientation(int)",tr("Flips the normals of all faces by changing the vertex order in each face"),
350  QStringList(tr("objectId")),
351  QStringList(tr("ID of an object")));
352 
353 
354  // ===============================
355  // Normal Fixing
356  // ===============================
357 
358  emit setSlotDescription("updateFaceNormals(int)",tr("Recompute Face normals"),
359  QStringList(tr("objectId")),
360  QStringList(tr("ID of an object")));
361 
362  emit setSlotDescription("updateHalfedgeNormals(int)",tr("Recompute Halfedge normals"),
363  QStringList(tr("objectId")),
364  QStringList(tr("ID of an object")));
365 
366  emit setSlotDescription("updateVertexNormals(int)",tr("Recompute Vertex normals"),
367  QStringList(tr("objectId")),
368  QStringList(tr("ID of an object")));
369 
370  emit setSlotDescription("updateNormals(int)",tr("Recompute Face and Vertex normals"),
371  QStringList(tr("objectId")),
372  QStringList(tr("ID of an object")));
373 
374 
375  // ===============================
376  // General Mesh fixing
377  // ===============================
378 
379  emit setSlotDescription("snapBoundary(int,double)",tr("Snaps selected boundary vertices if the distance is less than the given maximal distance."),
380  QString(tr("objectId,epsilon")).split(","),
381  QString(tr("ID of an object;Max Distance")).split(";"));
382 
383  emit setSlotDescription("(int)",tr("Fixes non manifold vertices."),
384  QString(tr("objectId")).split(","),
385  QString(tr("ID of an object;Non manifold vertices are splitted.")).split(";"));
386 
387  emit setSlotDescription("fixMesh(int,double)",tr("Fixes a mesh."),
388  QString(tr("objectId,distance")).split(","),
389  QString(tr("ID of an object;Vertices with distance lower than epsilon will be treated as one.")).split(";"));
390 
391 }
392 
393 #if QT_VERSION < 0x050000
394  Q_EXPORT_PLUGIN2( meshrepairplugin , MeshRepairPlugin );
395 #endif
396 
397 
void slotDetectSkinnyTriangleByAngle()
Button slot.
void slotDetectFlatValence3Vertices()
Button slot.
void slotRemoveSkinnyTriangleByAngle()
Button slot.
void slotSnapBoundary()
Button slot.
Predefined datatypes.
Definition: DataTypes.hh:96
void slotFixMesh()
Button slot.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
void slotFlipOrientation()
Button slot.
void slotUpdateNormals()
Button slot.
void slotRemoveSelectedEdges()
Button slot.
void slotUpdateFaceNormals()
Button slot.
void slotFixNonManifoldVertices()
Button slot.
void slotDetectEdgesShorter()
Button Slot.
void slotDetectFoldover()
Button slot.
void slotUpdateVertexNormals()
Button slot.
void slotUpdateHalfedgeNormals()
Button slot.
void slotRemoveSelectedVal3Vertices()
Button slot.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
void slotDetectTriangleAspect()
Button slot.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
void slotDetectEdgesLonger()
Button Slot.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.