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 #include "MeshRepairPlugin.hh"
43 
44 
45 //-----------------------------------------------------------------------------
46 
47 MeshRepairPlugin::MeshRepairPlugin() :
48 tool_(0),
49 toolIcon_(0)
50 {
51 
52 }
53 //-----------------------------------------------------------------------------
54 
55 void
56 MeshRepairPlugin::
57 initializePlugin()
58 {
59  tool_ = new MeshRepairToolbarWidget();
60  QSize size(300, 300);
61  tool_->resize(size);
62 
63  //==================
64  // Vertex operations
65  //==================
66 
67  connect(tool_->valenceThreeButton, SIGNAL(clicked()), this, SLOT(slotDetectFlatValence3Vertices()) );
68  connect(tool_->repairRemoveVButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedVal3Vertices()) );
69 
70  //==================
71  // Edge operations
72  //==================
73 
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  connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectSkinnyTriangleByAngle()) );
78  connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSkinnyTriangleByAngle()) );
79  connect(tool_->detectFoldoverButton, SIGNAL(clicked()), this, SLOT(slotDetectFoldover()) );
80 
81  //==================
82  // Face operations
83  //==================
84  connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect()));
85  connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation()));
86 
87  //==================
88  // Normal operations
89  //==================
90  connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals()));
91  connect(tool_->computeVertexNormals,SIGNAL(clicked()),this,SLOT(slotUpdateVertexNormals()));
92  connect(tool_->computeFaceNormals,SIGNAL(clicked()),this,SLOT(slotUpdateFaceNormals()));
93  connect(tool_->computeHalfedgeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateHalfedgeNormals()));
94 
95  //==================
96  // General
97  //==================
98  connect(tool_->snapBoundaryButton, SIGNAL(clicked()), this, SLOT(slotSnapBoundary()) );
99  connect(tool_->fixNonManifoldVerticesButton,SIGNAL(clicked()),this,SLOT(slotFixNonManifoldVertices()));
100  connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh()));
101 
102 
103  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"meshrepair-toolbox.png");
104  tool_->repairCollapseEButton->setIcon(*toolIcon_);
105  tool_->repairFlipEButton->setIcon(*toolIcon_);
106  tool_->repairRemoveVButton->setIcon(*toolIcon_);
107 
108  emit addToolbox( tr("Mesh Repair") , tool_, toolIcon_);
109 }
110 
111 //===========================================================================
112 // Button Slots
113 //===========================================================================
114 
116 
118  removeSelectedVal3Vertices(o_it->id());
119 
120  emit updateView();
121 }
122 
123 //-----------------------------------------------------------------------------
124 
126 
128  removeSelectedEdges(o_it->id());
129 
130  emit updateView();
131 }
132 
133 //-----------------------------------------------------------------------------
134 
136 {
138  detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), false );
139 
140  emit updateView();
141 }
142 
143 //-----------------------------------------------------------------------------
144 
146 {
147  //rewrite!!!
149  detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), true );
150 
151  emit updateView();
152 }
153 
154 //-----------------------------------------------------------------------------
155 
157 
159  detectFoldover(o_it->id(), tool_->detectFoldoverSpinbox->value());
160 
161  emit updateView();
162 }
163 
164 //-----------------------------------------------------------------------------
165 
167 
169  detectTriangleAspect(o_it->id(), tool_->triangleAspectSpinbox->value());
170 
171  emit updateView();
172 }
173 
174 //-----------------------------------------------------------------------------
175 
177 
179  flipOrientation(o_it->id());
180 
181  emit updateView();
182 }
183 
184 //-----------------------------------------------------------------------------
185 
187 
188 
190  fixMesh(o_it->id() , tool_->fixMeshBox->value() );
191 
192  emit updateView();
193 
194 }
195 
196 //-----------------------------------------------------------------------------
197 
200  updateVertexNormals(o_it->id());
201 
202  emit updateView();
203 }
204 
205 //-----------------------------------------------------------------------------
206 
209  updateFaceNormals(o_it->id());
210 
211  emit updateView();
212 }
213 
214 //-----------------------------------------------------------------------------
215 
218  updateHalfedgeNormals(o_it->id());
219 
220  emit updateView();
221 }
222 
223 //-----------------------------------------------------------------------------
224 
227  updateNormals(o_it->id());
228 
229  emit updateView();
230 }
231 
232 //-----------------------------------------------------------------------------
233 
235  double length = tool_->edgeSpin->value();
236 
238  selectEdgesShorterThan(o_it->id(),length);
239 
240  emit updateView();
241 }
242 
243 //-----------------------------------------------------------------------------
244 
246  double length = tool_->edgeSpin->value();
247 
249  selectEdgesLongerThan(o_it->id(),length);
250 
251  emit updateView();
252 }
253 
254 //-----------------------------------------------------------------------------
255 
257  double angle = tool_->valenceThreeSpinbox->value();
258 
260  detectFlatValence3Vertices(o_it->id(), angle);
261 
262  emit updateView();
263 }
264 
265 //-----------------------------------------------------------------------------
266 
268 {
269  double eps = tool_->snapBoundarySpinBox->value();
271  snapBoundary(o_it->id(), eps);
272  emit updateView();
273 }
274 
275 //-----------------------------------------------------------------------------
276 
278 {
280  fixNonManifoldVertices(o_it->id());
281  emit updateView();
282 }
283 
284 
285 //-----------------------------------------------------------------------------
286 
291 
292  // ===============================
293  // Vertex Operations
294  // ===============================
295 
296  emit setSlotDescription("removeSelectedVal3Vertices(int)",tr("Remove all selected valence 3 vertices"),
297  QStringList(tr("objectId")),
298  QStringList(tr("ID of an object")));
299 
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(","),
302  QString(tr("ID of an object;the maximal angle between the adjacent faces")).split(";"));
303 
304  // ===============================
305  // Edge Operations
306  // ===============================
307 
308  emit setSlotDescription("selectEdgesShorterThan(int,double)",tr("Selects all edges of an object which are shorter than the given length"),
309  QString(tr("objectId,length")).split(","),
310  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  QString(tr("objectId,length")).split(","),
314  QString(tr("ID of an object;All edges longer than this length will be selected")).split(";"));
315 
316  emit setSlotDescription("removeSelectedEdges(int)",tr("Remove the selected edges"),
317  QStringList(tr("objectId")),
318  QStringList(tr("ID of an object")));
319 
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(","),
322  QString(tr("ID of an object;Minimum angle threshold;Remove")).split(";"));
323 
324  emit setSlotDescription("detectFoldover(int,float)",tr("Selects edges that are incident to folded over faces."),
325  QString(tr("objectId,angle")).split(","),
326  QString(tr("ID of an object;Minimum threshold angle for fold-overs")).split(";"));
327 
328  // ===============================
329  // Face Operations
330  // ===============================
331 
332  emit setSlotDescription("detectTriangleAspect(int,float)",tr("Selects all faces that have a larger aspect ratio than the given one."),
333  QString(tr("objectId,aspect")).split(","),
334  QString(tr("ID of an object;The minimal aspect ratio to select")).split(";"));
335 
336  emit setSlotDescription("flipOrientation(int)",tr("Flips the normals of all faces by changing the vertex order in each face"),
337  QStringList(tr("objectId")),
338  QStringList(tr("ID of an object")));
339 
340 
341  // ===============================
342  // Normal Fixing
343  // ===============================
344 
345  emit setSlotDescription("updateFaceNormals(int)",tr("Recompute Face normals"),
346  QStringList(tr("objectId")),
347  QStringList(tr("ID of an object")));
348 
349  emit setSlotDescription("updateHalfedgeNormals(int)",tr("Recompute Halfedge normals"),
350  QStringList(tr("objectId")),
351  QStringList(tr("ID of an object")));
352 
353  emit setSlotDescription("updateVertexNormals(int)",tr("Recompute Vertex normals"),
354  QStringList(tr("objectId")),
355  QStringList(tr("ID of an object")));
356 
357  emit setSlotDescription("updateNormals(int)",tr("Recompute Face and Vertex normals"),
358  QStringList(tr("objectId")),
359  QStringList(tr("ID of an object")));
360 
361 
362  // ===============================
363  // General Mesh fixing
364  // ===============================
365 
366  emit setSlotDescription("snapBoundary(int,double)",tr("Snaps selected boundary vertices if the distance is less than the given maximal distance."),
367  QString(tr("objectId,epsilon")).split(","),
368  QString(tr("ID of an object;Max Distance")).split(";"));
369 
370  emit setSlotDescription("(int)",tr("Fixes non manifold vertices."),
371  QString(tr("objectId")).split(","),
372  QString(tr("ID of an object;Non manifold vertices are splitted.")).split(";"));
373 
374  emit setSlotDescription("fixMesh(int,double)",tr("Fixes a mesh."),
375  QString(tr("objectId,distance")).split(","),
376  QString(tr("ID of an object;Vertices with distance lower than epsilon will be treated as one.")).split(";"));
377 
378 }
379 
380 
381 
void slotDetectFoldover()
Button slot.
void slotRemoveSelectedEdges()
Button slot.
void slotDetectTriangleAspect()
Button slot.
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
void slotUpdateVertexNormals()
Button slot.
void slotFlipOrientation()
Button slot.
void slotRemoveSelectedVal3Vertices()
Button slot.
void slotDetectEdgesLonger()
Button Slot.
void slotUpdateHalfedgeNormals()
Button slot.
void slotDetectFlatValence3Vertices()
Button slot.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
void slotUpdateFaceNormals()
Button slot.
void slotDetectSkinnyTriangleByAngle()
Button slot.
void slotFixMesh()
Button slot.
void slotFixNonManifoldVertices()
Button slot.
void slotRemoveSkinnyTriangleByAngle()
Button slot.
void slotSnapBoundary()
Button slot.
void slotDetectEdgesShorter()
Button Slot.
void slotUpdateNormals()
Button slot.
Predefined datatypes.
Definition: DataTypes.hh:83
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60