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
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 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
128 removeSelectedEdges(o_it->id());
129
130 emit updateView();
131 }
132
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 emit updateView();
141 }
142
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 emit updateView();
152 }
153
154 //-----------------------------------------------------------------------------
155
156 void MeshRepairPlugin::slotDetectFoldover() {
157
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 void MeshRepairPlugin::slotDetectTriangleAspect() {
167
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 emit updateView();
172 }
173
174 //-----------------------------------------------------------------------------
175
176 void MeshRepairPlugin::slotFlipOrientation(){
177
178 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
179 flipOrientation(o_it->id());
180
181 emit updateView();
182 }
183
184 //-----------------------------------------------------------------------------
185
186 void MeshRepairPlugin::slotFixMesh() {
187
188
189 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
190 fixMesh(o_it->id() , tool_->fixMeshBox->value() );
191
192 emit updateView();
193
194 }
195
196 //-----------------------------------------------------------------------------
197
198 void MeshRepairPlugin::slotUpdateVertexNormals() {
199 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
200 updateVertexNormals(o_it->id());
201
202 emit updateView();
203 }
204
205 //-----------------------------------------------------------------------------
206
207 void MeshRepairPlugin::slotUpdateFaceNormals() {
208 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
209 updateFaceNormals(o_it->id());
210
211 emit updateView();
212 }
213
214 //-----------------------------------------------------------------------------
215
216 void MeshRepairPlugin::slotUpdateHalfedgeNormals() {
217 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
218 updateHalfedgeNormals(o_it->id());
219
220 emit updateView();
221 }
222
223 //-----------------------------------------------------------------------------
224
225 void MeshRepairPlugin::slotUpdateNormals(){
226 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
227 updateNormals(o_it->id());
228
229 emit updateView();
230 }
231
232 //-----------------------------------------------------------------------------
233
234 void MeshRepairPlugin::slotDetectEdgesShorter(){
235 double length = tool_->edgeSpin->value();
236
237 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
238 selectEdgesShorterThan(o_it->id(),length);
239
240 emit updateView();
241 }
242
243 //-----------------------------------------------------------------------------
244
245 void MeshRepairPlugin::slotDetectEdgesLonger(){
246 double length = tool_->edgeSpin->value();
247
248 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
249 selectEdgesLongerThan(o_it->id(),length);
250
251 emit updateView();
252 }
253
254 //-----------------------------------------------------------------------------
255
256 void MeshRepairPlugin::slotDetectFlatValence3Vertices() {
257 double angle = tool_->valenceThreeSpinbox->value();
258
259 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
260 detectFlatValence3Vertices(o_it->id(), angle);
261
262 emit updateView();
263 }
264
265 //-----------------------------------------------------------------------------
266
267 void MeshRepairPlugin::slotSnapBoundary()
268 {
269 double eps = tool_->snapBoundarySpinBox->value();
270 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ) ); o_it != PluginFunctions::objectsEnd(); ++o_it)
271 snapBoundary(o_it->id(), eps);
272 emit updateView();
273 }
274
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 emit updateView();
282 }
283
284
285 //-----------------------------------------------------------------------------
286
290 void MeshRepairPlugin::pluginsInitialized() {
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
MeshRepairPlugin::slotDetectFoldover
void slotDetectFoldover()
Button slot.
Definition: MeshRepairPlugin.cc:156
MeshRepairPlugin::slotRemoveSelectedEdges
void slotRemoveSelectedEdges()
Button slot.
Definition: MeshRepairPlugin.cc:125
MeshRepairPlugin::slotDetectTriangleAspect
void slotDetectTriangleAspect()
Button slot.
Definition: MeshRepairPlugin.cc:166
MeshRepairPlugin::pluginsInitialized
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
Definition: MeshRepairPlugin.cc:290
DATA_POLY_MESH
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
MeshRepairPlugin::slotUpdateVertexNormals
void slotUpdateVertexNormals()
Button slot.
Definition: MeshRepairPlugin.cc:198
MeshRepairPlugin::slotFlipOrientation
void slotFlipOrientation()
Button slot.
Definition: MeshRepairPlugin.cc:176
MeshRepairPlugin::slotRemoveSelectedVal3Vertices
void slotRemoveSelectedVal3Vertices()
Button slot.
Definition: MeshRepairPlugin.cc:115
MeshRepairPlugin::slotDetectEdgesLonger
void slotDetectEdgesLonger()
Button Slot.
Definition: MeshRepairPlugin.cc:245
MeshRepairPlugin::slotUpdateHalfedgeNormals
void slotUpdateHalfedgeNormals()
Button slot.
Definition: MeshRepairPlugin.cc:216
MeshRepairPlugin::slotDetectFlatValence3Vertices
void slotDetectFlatValence3Vertices()
Button slot.
Definition: MeshRepairPlugin.cc:256
PluginFunctions::TARGET_OBJECTS
const QStringList TARGET_OBJECTS("target")
Iterable object range.
MeshRepairPlugin::slotUpdateFaceNormals
void slotUpdateFaceNormals()
Button slot.
Definition: MeshRepairPlugin.cc:207
MeshRepairPlugin::slotDetectSkinnyTriangleByAngle
void slotDetectSkinnyTriangleByAngle()
Button slot.
Definition: MeshRepairPlugin.cc:135
MeshRepairPlugin::slotFixMesh
void slotFixMesh()
Button slot.
Definition: MeshRepairPlugin.cc:186
MeshRepairPlugin::slotFixNonManifoldVertices
void slotFixNonManifoldVertices()
Button slot.
Definition: MeshRepairPlugin.cc:277
MeshRepairPlugin::slotRemoveSkinnyTriangleByAngle
void slotRemoveSkinnyTriangleByAngle()
Button slot.
Definition: MeshRepairPlugin.cc:145
MeshRepairPlugin::slotSnapBoundary
void slotSnapBoundary()
Button slot.
Definition: MeshRepairPlugin.cc:267
MeshRepairPlugin::slotDetectEdgesShorter
void slotDetectEdgesShorter()
Button Slot.
Definition: MeshRepairPlugin.cc:234
MeshRepairPlugin::slotUpdateNormals
void slotUpdateNormals()
Button slot.
Definition: MeshRepairPlugin.cc:225
DataType
Predefined datatypes.
Definition: DataTypes.hh:83
PluginFunctions::ObjectIterator
Core Data Iterator.
Definition: PluginFunctions.hh:441
PluginFunctions::objectsEnd
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Definition: PluginFunctionsIterator.cc:177
MeshRepairToolbarWidget
Definition: MeshRepairToolbar.hh:47
DATA_TRIANGLE_MESH
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60