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
47MeshRepairPlugin::MeshRepairPlugin() :
48tool_(nullptr),
49toolIcon_(nullptr)
50{
51
52}
53//-----------------------------------------------------------------------------
54
55MeshRepairPlugin::~MeshRepairPlugin() {
56 delete toolIcon_;
57}
58
59
60void
61MeshRepairPlugin::
62initializePlugin()
63{
65 QSize size(300, 300);
66 tool_->resize(size);
67
68 //==================
69 // Vertex operations
70 //==================
71
72 connect(tool_->valenceThreeButton, SIGNAL(clicked()), this, SLOT(slotDetectFlatValence3Vertices()) );
73 connect(tool_->repairRemoveVButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedVal3Vertices()) );
74
75 //==================
76 // Edge operations
77 //==================
78
79 connect(tool_->detectEShorterButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesShorter()) );
80 connect(tool_->detectELargerButton, SIGNAL(clicked()), this, SLOT(slotDetectEdgesLonger()) );
81 connect(tool_->repairCollapseEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedEdges()) );
82 connect(tool_->detectCapAngle, SIGNAL(clicked()), this, SLOT(slotDetectSkinnyTriangleByAngle()) );
83 connect(tool_->repairFlipEButton, SIGNAL(clicked()), this, SLOT(slotRemoveSkinnyTriangleByAngle()) );
84 connect(tool_->detectFoldoverButton, SIGNAL(clicked()), this, SLOT(slotDetectFoldover()) );
85
86 //==================
87 // Face operations
88 //==================
89 connect(tool_->triangleAspectButton,SIGNAL(clicked()),this,SLOT(slotDetectTriangleAspect()));
90 connect(tool_->flipOrientation,SIGNAL(clicked()),this,SLOT(slotFlipOrientation()));
91
92 //==================
93 // Normal operations
94 //==================
95 connect(tool_->computeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateNormals()));
96 connect(tool_->computeVertexNormals,SIGNAL(clicked()),this,SLOT(slotUpdateVertexNormals()));
97 connect(tool_->computeFaceNormals,SIGNAL(clicked()),this,SLOT(slotUpdateFaceNormals()));
98 connect(tool_->computeHalfedgeNormals,SIGNAL(clicked()),this,SLOT(slotUpdateHalfedgeNormals()));
99
100 //==================
101 // General
102 //==================
103 connect(tool_->snapBoundaryButton, SIGNAL(clicked()), this, SLOT(slotSnapBoundary()) );
104 connect(tool_->fixNonManifoldVerticesButton,SIGNAL(clicked()),this,SLOT(slotFixNonManifoldVertices()));
105 connect(tool_->fixMeshButton,SIGNAL(clicked()),this,SLOT(slotFixMesh()));
106
107
108 toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"meshrepair-toolbox.png");
109 tool_->repairCollapseEButton->setIcon(*toolIcon_);
110 tool_->repairFlipEButton->setIcon(*toolIcon_);
111 tool_->repairRemoveVButton->setIcon(*toolIcon_);
112
113 emit addToolbox( tr("Mesh Repair") , tool_, toolIcon_);
114}
115
116//===========================================================================
117// Button Slots
118//===========================================================================
119
121
123 removeSelectedVal3Vertices(o_it->id());
124
125 emit updateView();
126}
127
128//-----------------------------------------------------------------------------
129
131
133 removeSelectedEdges(o_it->id());
134
135 emit updateView();
136}
137
138//-----------------------------------------------------------------------------
139
141{
143 detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), false );
144
145 emit updateView();
146}
147
148//-----------------------------------------------------------------------------
149
151{
152 //rewrite!!!
154 detectSkinnyTriangleByAngle( o_it->id(), tool_->capAngleSpinbox->value(), true );
155
156 emit updateView();
157}
158
159//-----------------------------------------------------------------------------
160
162
164 detectFoldover(o_it->id(), tool_->detectFoldoverSpinbox->value());
165
166 emit updateView();
167}
168
169//-----------------------------------------------------------------------------
170
172
174 detectTriangleAspect(o_it->id(), tool_->triangleAspectSpinbox->value());
175
176 emit updateView();
177}
178
179//-----------------------------------------------------------------------------
180
182
184 flipOrientation(o_it->id());
185
186 emit updateView();
187}
188
189//-----------------------------------------------------------------------------
190
192
193
195 fixMesh(o_it->id() , tool_->fixMeshBox->value() );
196
197 emit updateView();
198
199}
200
201//-----------------------------------------------------------------------------
202
205 updateVertexNormals(o_it->id());
206
207 emit updateView();
208}
209
210//-----------------------------------------------------------------------------
211
214 updateFaceNormals(o_it->id());
215
216 emit updateView();
217}
218
219//-----------------------------------------------------------------------------
220
223 updateHalfedgeNormals(o_it->id());
224
225 emit updateView();
226}
227
228//-----------------------------------------------------------------------------
229
232 updateNormals(o_it->id());
233
234 emit updateView();
235}
236
237//-----------------------------------------------------------------------------
238
240 double length = tool_->edgeSpin->value();
241
243 selectEdgesShorterThan(o_it->id(),length);
244
245 emit updateView();
246}
247
248//-----------------------------------------------------------------------------
249
251 double length = tool_->edgeSpin->value();
252
254 selectEdgesLongerThan(o_it->id(),length);
255
256 emit updateView();
257}
258
259//-----------------------------------------------------------------------------
260
262 double angle = tool_->valenceThreeSpinbox->value();
263
265 detectFlatValence3Vertices(o_it->id(), angle);
266
267 emit updateView();
268}
269
270//-----------------------------------------------------------------------------
271
273{
274 double eps = tool_->snapBoundarySpinBox->value();
276 snapBoundary(o_it->id(), eps);
277 emit updateView();
278}
279
280//-----------------------------------------------------------------------------
281
283{
285 fixNonManifoldVertices(o_it->id());
286 emit updateView();
287}
288
289
290//-----------------------------------------------------------------------------
291
296
297 // ===============================
298 // Vertex Operations
299 // ===============================
300
301 emit setSlotDescription("removeSelectedVal3Vertices(int)",tr("Remove all selected valence 3 vertices"),
302 QStringList(tr("objectId")),
303 QStringList(tr("ID of an object")));
304
305 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"),
306 QString(tr("objectId,angle")).split(","),
307 QString(tr("ID of an object;the maximal angle between the adjacent faces")).split(";"));
308
309 // ===============================
310 // Edge Operations
311 // ===============================
312
313 emit setSlotDescription("selectEdgesShorterThan(int,double)",tr("Selects all edges of an object which are shorter than the given length"),
314 QString(tr("objectId,length")).split(","),
315 QString(tr("ID of an object;All edges shorter than this length will be selected")).split(";"));
316
317 emit setSlotDescription("selectEdgesLongerThan(int,double)",tr("Selects all edges of an object which are longer than the given length"),
318 QString(tr("objectId,length")).split(","),
319 QString(tr("ID of an object;All edges longer than this length will be selected")).split(";"));
320
321 emit setSlotDescription("removeSelectedEdges(int)",tr("Remove the selected edges"),
322 QStringList(tr("objectId")),
323 QStringList(tr("ID of an object")));
324
325 emit setSlotDescription("detectSkinnyTriangleByAngle(int,double,bool)",tr("Select or remove skinny triangles (determined by a minimum angle threshold)."),
326 QString(tr("objectId,angle,remove")).split(","),
327 QString(tr("ID of an object;Minimum angle threshold;Remove")).split(";"));
328
329 emit setSlotDescription("detectFoldover(int,float)",tr("Selects edges that are incident to folded over faces."),
330 QString(tr("objectId,angle")).split(","),
331 QString(tr("ID of an object;Minimum threshold angle for fold-overs")).split(";"));
332
333 // ===============================
334 // Face Operations
335 // ===============================
336
337 emit setSlotDescription("detectTriangleAspect(int,float)",tr("Selects all faces that have a larger aspect ratio than the given one."),
338 QString(tr("objectId,aspect")).split(","),
339 QString(tr("ID of an object;The minimal aspect ratio to select")).split(";"));
340
341 emit setSlotDescription("flipOrientation(int)",tr("Flips the normals of all faces by changing the vertex order in each face"),
342 QStringList(tr("objectId")),
343 QStringList(tr("ID of an object")));
344
345
346 // ===============================
347 // Normal Fixing
348 // ===============================
349
350 emit setSlotDescription("updateFaceNormals(int)",tr("Recompute Face normals"),
351 QStringList(tr("objectId")),
352 QStringList(tr("ID of an object")));
353
354 emit setSlotDescription("updateHalfedgeNormals(int)",tr("Recompute Halfedge normals"),
355 QStringList(tr("objectId")),
356 QStringList(tr("ID of an object")));
357
358 emit setSlotDescription("updateVertexNormals(int)",tr("Recompute Vertex normals"),
359 QStringList(tr("objectId")),
360 QStringList(tr("ID of an object")));
361
362 emit setSlotDescription("updateNormals(int)",tr("Recompute Face and Vertex normals"),
363 QStringList(tr("objectId")),
364 QStringList(tr("ID of an object")));
365
366
367 // ===============================
368 // General Mesh fixing
369 // ===============================
370
371 emit setSlotDescription("snapBoundary(int,double)",tr("Snaps selected boundary vertices if the distance is less than the given maximal distance."),
372 QString(tr("objectId,epsilon")).split(","),
373 QString(tr("ID of an object;Max Distance")).split(";"));
374
375 emit setSlotDescription("(int)",tr("Fixes non manifold vertices."),
376 QString(tr("objectId")).split(","),
377 QString(tr("ID of an object;Non manifold vertices are splitted.")).split(";"));
378
379 emit setSlotDescription("fixMesh(int,double)",tr("Fixes a mesh."),
380 QString(tr("objectId,distance")).split(","),
381 QString(tr("ID of an object;Vertices with distance lower than epsilon will be treated as one.")).split(";"));
382
383}
384
385
386
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
Predefined datatypes.
Definition: DataTypes.hh:83
void removeSelectedEdges(int _objectId)
Removes all selected edges.
void fixMesh(int _objectId, double _epsilon)
Fix a mesh.
void slotDetectFoldover()
Button slot.
void updateNormals(int _objectId)
Recomputes the face and vertex normals of an object.
void slotUpdateFaceNormals()
Button slot.
void removeSelectedVal3Vertices(int _objectId)
Remove all selected valence 3 vertices.
void slotFlipOrientation()
Button slot.
void slotSnapBoundary()
Button slot.
void updateVertexNormals(int _objectId)
Recomputes the vertex normals of an object.
void slotFixNonManifoldVertices()
Button slot.
void updateHalfedgeNormals(int _objectId)
Recomputes the halfedge normals of an object.
Definition: NormalFixing.cc:82
void slotRemoveSelectedVal3Vertices()
Button slot.
void detectSkinnyTriangleByAngle(int _objectId, double _angle, bool _remove)
Detect/Remove edges where neighboring faces form angle > _angle degrees.
void slotFixMesh()
Button slot.
void detectFlatValence3Vertices(int _objectId, double _angle)
Detect valence 3 vertices with faces that lie in the plane of their adjacent triangles.
void fixNonManifoldVertices(int _objectId)
remove non-manifold vertices by duplicating them
void slotRemoveSelectedEdges()
Button slot.
void slotDetectEdgesLonger()
Button Slot.
void updateFaceNormals(int _objectId)
Recomputes the face normals of an object.
Definition: NormalFixing.cc:53
void slotDetectFlatValence3Vertices()
Button slot.
void flipOrientation(int _objectId)
Flips the normals of all selected faces by changing the vertex order.
void slotUpdateVertexNormals()
Button slot.
MeshRepairToolbarWidget * tool_
Widget for Toolbox.
void selectEdgesLongerThan(int _objectId, double _length)
Selects all edges of an object which are larger than the given length.
void slotDetectTriangleAspect()
Button slot.
void slotUpdateNormals()
Button slot.
void slotRemoveSkinnyTriangleByAngle()
Button slot.
void detectFoldover(int _objectId, float _angle)
Detect folded-over configurations by the dihedral angle.
void selectEdgesShorterThan(int _objectId, double _length)
Selects all edges of an object which are shorter than the given length.
void snapBoundary(int _objectId, double _eps)
Snaps selected vertices at boundaries.
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
void detectTriangleAspect(int _objectId, float _aspect)
Detect triangles with aspect ratio greater than _aspect and select them.
void slotUpdateHalfedgeNormals()
Button slot.
void slotDetectEdgesShorter()
Button Slot.
void slotDetectSkinnyTriangleByAngle()
Button slot.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
ObjectRange objects(IteratorRestriction _restriction, DataType _dataType)
Iterable object range.