Developer Documentation
FilePLY.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 #include "FilePLY.hh"
45 
46  #include <QtWidgets>
47 
48 
49 // Defines for the type handling drop down box
50 #define TYPEAUTODETECT 0
51 #define TYPEASK 1
52 #define TYPEPOLY 2
53 #define TYPETRIANGLE 3
54 
57 : loadOptions_(0),
58  saveOptions_(0),
59  saveBinary_(0),
60  saveVertexNormal_(0),
61  saveVertexColor_(0),
62  saveVertexTexCoord_(0),
63  saveFaceNormal_(0),
64  saveFaceColor_(0),
65  savePrecisionLabel_(0),
66  savePrecision_(0),
67  saveDefaultButton_(0),
68  triMeshHandling_(0),
69  loadVertexNormal_(0),
70  loadVertexColor_(0),
71  loadVertexTexCoord_(0),
72  loadFaceNormal_(0),
73  loadFaceColor_(0),
74  loadDefaultButton_(0),
75  trimeshOptions_(0) {
76 }
77 
78 //-----------------------------------------------------------------------------------------------------
79 
81 }
82 
83 //-----------------------------------------------------------------------------------------------------
84 
86  return QString( tr("Polygon File Format files ( *.ply )") );
87 };
88 
89 //-----------------------------------------------------------------------------------------------------
90 
92  return QString( tr("Polygon File Format files ( *.ply )") );
93 };
94 
95 //-----------------------------------------------------------------------------------------------------
96 
99  return type;
100 }
101 
102 //-----------------------------------------------------------------------------------------------------
103 int FilePLYPlugin::loadObject(QString _filename, DataType _type) {
104 
105  int objectId = -1;
106 
107  bool gui = OpenFlipper::Options::gui() && (loadVertexNormal_ != 0) /*buttons initialized*/;
108  // If in no gui mode -> request as much as possible
109  bool vNormals = ((gui && loadVertexNormal_->isChecked()) ||
110  (!gui && OpenFlipperSettings().value("FilePLY/Load/Normals",true).toBool()));
111  bool vColors = ((gui && loadVertexColor_->isChecked()) ||
112  (!gui && OpenFlipperSettings().value("FilePLY/Load/VertexColor",true).toBool()));
113  bool vTexCoords = ((gui && loadVertexTexCoord_->isChecked()) ||
114  (!gui && OpenFlipperSettings().value("FilePLY/Load/TexCoords",true).toBool()));
115  bool fNormals = ((gui && loadFaceNormal_->isChecked()) ||
116  (!gui && OpenFlipperSettings().value("FilePLY/Load/FaceNormal",true).toBool()));
117  bool fColors = ((gui && loadFaceColor_->isChecked()) ||
118  (!gui && OpenFlipperSettings().value("FilePLY/Load/FaceColor",true).toBool()));
119 
121  if (vNormals)
123  if (vColors)
125  if (vTexCoords)
127  if (fNormals)
129  if (fColors)
132 
133  // Forced polymesh read
134  if ( _type == DATA_POLY_MESH ) {
135  objectId = loadPolyMeshObject(_filename, opt);
136 
137  PolyMeshObject* object(0);
138  if(PluginFunctions::getObject( objectId, object )) {
139  emit updatedObject(objectId, UPDATE_ALL);
140  emit openedFile( objectId );
141  }
142 
143 
144  return objectId;
145  } else if ( _type == DATA_TRIANGLE_MESH) {
146  // If always open as TriMesh is selected
147 
148  objectId = loadTriMeshObject(_filename, opt);
149 
150  TriMeshObject* object(0);
151  if(PluginFunctions::getObject( objectId, object )) {
152 
153  emit updatedObject(objectId, UPDATE_ALL);
154  emit openedFile( objectId );
155  }
156 
157 
158  return objectId;
159  } else {
160  emit log( LOGERR, tr("FilePLYPlugin::loadObject(): Tried loading with unknown forced data type"));
161  }
162 
163  return -1;
164 }
165 
166 //-----------------------------------------------------------------------------------------------------
167 
168 int FilePLYPlugin::loadObject(QString _filename) {
169 
170  int triMeshControl = TYPEAUTODETECT; // 0 == Auto-Detect
171 
172  bool gui = OpenFlipper::Options::gui() && (loadVertexNormal_ != 0) /*buttons initialized*/;
173  // If in no gui mode -> request as much as possible
174  bool vNormals = ((gui && loadVertexNormal_->isChecked()) ||
175  (!gui && OpenFlipperSettings().value("FilePLY/Load/Normals",true).toBool()));
176  bool vColors = ((gui && loadVertexColor_->isChecked()) ||
177  (!gui && OpenFlipperSettings().value("FilePLY/Load/VertexColor",true).toBool()));
178  bool vTexCoords = ((gui && loadVertexTexCoord_->isChecked()) ||
179  (!gui && OpenFlipperSettings().value("FilePLY/Load/TexCoords",true).toBool()));
180  bool fNormals = ((gui && loadFaceNormal_->isChecked()) ||
181  (!gui && OpenFlipperSettings().value("FilePLY/Load/FaceNormal",true).toBool()));
182  bool fColors = ((gui && loadFaceColor_->isChecked()) ||
183  (!gui && OpenFlipperSettings().value("FilePLY/Load/FaceColor",true).toBool()));
184 
186  if (vNormals)
188  if (vColors)
190  if (vTexCoords)
192  if (fNormals)
194  if (fColors)
197 
198  if ( OpenFlipper::Options::gui() ){
199  if ( triMeshHandling_ != 0 ){
200  triMeshControl = triMeshHandling_->currentIndex();
201  } else {
202  triMeshControl = TYPEAUTODETECT;
203  }
204  }
205 
206  int objectId = -1;
207 
208 
209  if(triMeshControl == TYPEAUTODETECT || triMeshControl == TYPEASK) {
210 
211  objectId = loadPolyMeshObject(_filename, opt);
212 
213  PolyMeshObject *object = 0;
214  if(!PluginFunctions::getObject(objectId, object))
215  return -1;
216 
217  bool isTriMesh = true;
218  for ( PolyMesh::FaceIter f_it = object->mesh()->faces_begin(); f_it != object->mesh()->faces_end() && isTriMesh; ++f_it) {
219 
220  // Count number of vertices for the current face
221  unsigned count = 0;
222  for ( PolyMesh::FaceVertexIter fv_it( *(object->mesh()),*f_it); fv_it.is_valid(); ++fv_it )
223  ++count;
224 
225  // Check if it is a triangle. If not, this is really a poly mesh
226  isTriMesh = isTriMesh && (count == 3);
227  }
228 
229  if (triMeshControl == TYPEAUTODETECT)
230  {
231  if(!isTriMesh) {
232  PolyMeshObject* object(0);
233  if(PluginFunctions::getObject( objectId, object )) {
234  emit updatedObject(objectId, UPDATE_ALL);
235  emit openedFile( objectId );
236  }
237  return objectId;
238  }
239  }
240  else if (triMeshControl == TYPEASK) {
241 
242  // If Ask is selected -> show dialog
243  QMetaObject::invokeMethod(this,"handleTrimeshDialog",Qt::BlockingQueuedConnection);
244  if ((trimeshOptions_ == TYPEPOLY) ||
245  (trimeshOptions_ == TYPEASK && !isTriMesh)) {
246 
247  PolyMeshObject* object(0);
248  if(PluginFunctions::getObject( objectId, object )) {
249  emit updatedObject(object->id(), UPDATE_ALL);
250  emit openedFile( objectId );
251  }
252 
253  return objectId;
254  }
255 
256  }
257  } else if (triMeshControl == TYPEPOLY) {
258  // If always open as PolyMesh is selected
259 
260  objectId = loadPolyMeshObject(_filename, opt);
261 
262  PolyMeshObject* object(0);
263  if(PluginFunctions::getObject( objectId, object )) {
264  emit updatedObject(object->id(), UPDATE_ALL);
265  emit openedFile( objectId );
266  }
267 
268  return objectId;
269  } else {
270  // If always open as TriMesh is selected
271 
272  objectId = loadTriMeshObject(_filename, opt);
273 
274  TriMeshObject* object(0);
275  if(PluginFunctions::getObject( objectId, object )) {
276  emit updatedObject(object->id(), UPDATE_ALL);
277  emit openedFile( objectId );
278  }
279 
280 
281  return objectId;
282  }
283 
284  // Load object as triangle mesh
285 
286  if(objectId != -1) emit deleteObject(objectId);
287  objectId = loadTriMeshObject(_filename, opt);
288 
289  TriMeshObject* object(0);
290  if(PluginFunctions::getObject( objectId, object )) {
291  emit updatedObject(object->id(), UPDATE_ALL);
292  emit openedFile( objectId );
293  }
294 
295  return objectId;
296 };
297 
299 {
300  QMessageBox msgBox;
301  QPushButton *detectButton = msgBox.addButton(tr("Auto-Detect"), QMessageBox::ActionRole);
302  QPushButton *triButton = msgBox.addButton(tr("Open as triangle mesh"), QMessageBox::ActionRole);
303  QPushButton *polyButton = msgBox.addButton(tr("Open as poly mesh"), QMessageBox::ActionRole);
304  msgBox.setWindowTitle( tr("Mesh types in file") );
305  msgBox.setText( tr("You are about to open a file containing one or more mesh types. \n\n Which mesh type should be used?") );
306  msgBox.setDefaultButton( detectButton );
307  msgBox.exec();
308 
309 
310  if (msgBox.clickedButton() == triButton)
311  trimeshOptions_ = TYPETRIANGLE ;
312  else if (msgBox.clickedButton() == polyButton)
313  trimeshOptions_ = TYPEPOLY ;
314  else
315  trimeshOptions_ = TYPEASK;
316 }
317 
318 //-----------------------------------------------------------------------------------------------------
319 
322 
323  int id = -1;
324  emit addEmptyObject(DATA_TRIANGLE_MESH, id);
325 
326  TriMeshObject* object(0);
327  if(PluginFunctions::getObject( id, object)) {
328 
329  if ( PluginFunctions::objectCount() == 1 )
330  object->target(true);
331 
332  object->setFromFileName(_filename);
333  object->setName(object->filename());
334 
335  // Get mesh
336  TriMesh* mesh = object->mesh();
337 
338  bool hadVNormals = mesh->has_vertex_normals();
339  bool hadVColors = mesh->has_vertex_colors();
340  bool hadVTexCoords = mesh->has_vertex_texcoords2D();
341  bool hadFNormals = mesh->has_face_normals();
342  bool hadFColors = mesh->has_face_colors();
343 
344  if(_opt.vertex_has_normal())
345  mesh->request_vertex_normals();
346  if(_opt.vertex_has_color())
347  mesh->request_vertex_colors();
348  if(_opt.vertex_has_texcoord())
349  mesh->request_vertex_texcoords2D();
350  if(_opt.face_has_normal())
351  mesh->request_face_normals();
352  if(_opt.face_has_color())
353  mesh->request_face_colors();
354 
355  bool ok = OpenMesh::IO::read_mesh( *mesh , _filename.toStdString(), _opt);
356  if (!ok)
357  {
358  emit log(LOGERR, "Error while reading PLY file!");
359  emit deleteObject(id);
360  return -1;
361  }
362 
363  //update normals if they aren't read
364  if (!_opt.vertex_has_normal() || !_opt.face_has_normal()) {
365 
366 
367  if (_opt.vertex_has_normal() ) {
368  // If we have vertex normals, we can use them to compute the face normals
369  emit log(LOGINFO,"Vertex normals loaded from file. Computing Face normals.");
370  mesh->update_face_normals();
371  std::cerr << "Update face normals" << std::endl;
372  } else {
373  // If we don't have any normals, we compute all of them
374  emit log(LOGINFO,"File did not contain normals. Computing automatically.");
375  mesh->update_normals();
376  }
377 
378 
379  }
380 
381  //cleanup mesh if selected option could not be loaded
382  if (!hadVColors && !_opt.vertex_has_color() && mesh->has_vertex_colors())
383  mesh->release_vertex_colors();
384  if (!hadVTexCoords && !_opt.vertex_has_texcoord() && mesh->has_vertex_texcoords2D())
385  mesh->release_vertex_texcoords2D();
386  if (!hadFColors && !_opt.face_has_color() && mesh->has_face_colors())
387  mesh->release_face_colors();
388 
389  // Switch to point mode if mesh does not contain one single face
390  if(mesh->n_faces() == 0)
392 
394 
395  return object->id();
396 
397  } else {
398  emit log(LOGERR,"Error : Could not create new triangle mesh object.");
399  return -1;
400  }
401 }
402 
403 //-----------------------------------------------------------------------------------------------------
404 
407 
408  int id = -1;
409  emit addEmptyObject(DATA_POLY_MESH, id);
410 
411  PolyMeshObject* object(0);
412  if(PluginFunctions::getObject(id, object)) {
413 
414  if (PluginFunctions::objectCount() == 1 )
415  object->target(true);
416 
417  object->setFromFileName(_filename);
418  object->setName(object->filename());
419 
420  // Get mesh
421  PolyMesh* mesh = object->mesh();
422 
423  bool hadVNormals = mesh->has_vertex_normals();
424  bool hadVColors = mesh->has_vertex_colors();
425  bool hadVTexCoords = mesh->has_vertex_texcoords2D();
426  bool hadFNormals = mesh->has_face_normals();
427  bool hadFColors = mesh->has_face_colors();
428 
429  if(_opt.vertex_has_normal())
430  mesh->request_vertex_normals();
431  if(_opt.vertex_has_color())
432  mesh->request_vertex_colors();
433  if(_opt.vertex_has_texcoord())
434  mesh->request_vertex_texcoords2D();
435  if(_opt.face_has_normal())
436  mesh->request_face_normals();
437  if(_opt.face_has_color())
438  mesh->request_face_colors();
439 
440  bool ok = OpenMesh::IO::read_mesh( *mesh , _filename.toStdString(), _opt);
441  if (!ok)
442  {
443  emit log(LOGERR, "Error while reading PLY file!");
444  emit deleteObject(id);
445  return -1;
446  }
447 
448 
449  //update normals if they aren't read
450  if (!_opt.vertex_has_normal() || !_opt.face_has_normal()) {
451 
452 
453  if (_opt.vertex_has_normal() ) {
454  // If we have vertex normals, we can use them to compute the face normals
455  emit log(LOGINFO,"Vertex normals loaded from file. Computing Face normals.");
456  mesh->update_face_normals();
457  std::cerr << "Update face normals" << std::endl;
458  } else {
459  // If we don't have any normals, we compute all of them
460  emit log(LOGINFO,"File did not contain normals. Computing automatically.");
461  mesh->update_normals();
462  }
463 
464 
465  }
466 
467  //cleanup mesh if selected option could not be loaded
468  if (!hadVColors && !_opt.vertex_has_color() && mesh->has_vertex_colors())
469  mesh->release_vertex_colors();
470  if (!hadVTexCoords && !_opt.vertex_has_texcoord() && mesh->has_vertex_texcoords2D())
471  mesh->release_vertex_texcoords2D();
472  if (!hadFColors && !_opt.face_has_color() && mesh->has_face_colors())
473  mesh->release_face_colors();
474 
475 
476  // Switch to point mode if mesh does not contain one single face
477  if(mesh->n_faces() == 0)
479 
481 
482  return object->id();
483 
484  } else {
485  emit log(LOGERR,"Error : Could not create new poly mesh object.");
486  return -1;
487  }
488 
489  return id;
490 }
491 
492 //-----------------------------------------------------------------------------------------------------
493 
494 bool FilePLYPlugin::saveObject(int _id, QString _filename)
495 {
496  BaseObjectData* object;
497  if ( !PluginFunctions::getObject(_id,object) ) {
498  emit log(LOGERR, tr("saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
499  return false;
500  }
501 
502  object->setFromFileName(_filename);
503  object->setName(object->filename());
504 
505 
507  bool gui = OpenFlipper::Options::gui() && (saveBinary_ != 0) /*buttons initialized?*/;
508  bool binary = ((gui && saveBinary_->isChecked()) ||
509  OpenFlipperSettings().value("FilePLY/Save/Binary",false).toBool());
510 
511  if (binary)
513 
514  bool vNormals = ((gui && saveVertexNormal_->isChecked())) ||
515  (!gui && OpenFlipperSettings().value("FilePLY/Save/Normals",true).toBool());
516  bool vColors = ((gui && saveVertexColor_->isChecked())) ||
517  (!gui && OpenFlipperSettings().value("FilePLY/Save/VertexColor",true).toBool());
518  bool vTexCoords = ((gui && saveVertexTexCoord_->isChecked())) ||
519  (!gui && OpenFlipperSettings().value("FilePLY/Save/TexCoords",true).toBool());
520  bool fNormals = ((gui && saveFaceNormal_->isChecked())) ||
521  (!gui && OpenFlipperSettings().value("FilePLY/Save/FaceNormal",true).toBool());
522  bool fColors = ((gui && saveFaceColor_->isChecked())) ||
523  (!gui && OpenFlipperSettings().value("FilePLY/Save/FaceColor",true).toBool());
524 
525 
526  bool ok = false;
527 
528  if ( object->dataType(DATA_POLY_MESH) ) {
529 
530  PolyMeshObject* polyObj = dynamic_cast<PolyMeshObject*>(object);
531  PolyMesh* mesh = polyObj->mesh();
532 
533  if (vNormals && mesh->has_vertex_normals())
535  if (vColors && mesh->has_vertex_colors())
537  if (vTexCoords && mesh->has_vertex_texcoords2D())
539  if (fNormals && mesh->has_face_normals())
541  if (fColors && mesh->has_face_colors())
543 
544  ok = OpenMesh::IO::write_mesh(*mesh, _filename.toStdString() ,opt);
545 
546  } else if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
547 
548  TriMeshObject* triObj = dynamic_cast<TriMeshObject*>(object);
549  TriMesh* mesh = triObj->mesh();
550 
551  if (vNormals && mesh->has_vertex_normals())
553  if (vColors && mesh->has_vertex_colors())
555  if (vTexCoords && mesh->has_vertex_texcoords2D())
557  if (fNormals && mesh->has_face_normals())
559  if (fColors && mesh->has_face_colors())
561 
562  ok = OpenMesh::IO::write_mesh(*mesh, _filename.toStdString() ,opt);
563  }
564 
565  if(!ok) {
566  emit log(LOGERR, tr("Unable to save ") + _filename);
567  return false;
568  }
569 
570  emit log(LOGINFO, tr("Saved object to ") + _filename );
571  return true;
572 }
573 
574 //-----------------------------------------------------------------------------------------------------
575 
576 QWidget* FilePLYPlugin::saveOptionsWidget(QString /*_currentFilter*/) {
577 
578  if (saveOptions_ == 0){
579  //generate widget
580  saveOptions_ = new QWidget();
581  QVBoxLayout* layout = new QVBoxLayout();
582  layout->setAlignment(Qt::AlignTop);
583 
584  saveBinary_ = new QCheckBox("Save Binary");
585  layout->addWidget(saveBinary_);
586 
587  saveVertexNormal_ = new QCheckBox("Save Vertex Normals");
588  layout->addWidget(saveVertexNormal_);
589 
590  saveVertexColor_ = new QCheckBox("Save Vertex Colors");
591  layout->addWidget(saveVertexColor_);
592 
593  saveVertexTexCoord_ = new QCheckBox("Save Vertex TexCoords");
594  layout->addWidget(saveVertexTexCoord_);
595 
596  saveFaceNormal_ = new QCheckBox("Save Face Normals");
597  layout->addWidget(saveFaceNormal_);
598 
599  saveFaceColor_ = new QCheckBox("Save Face Colors");
600  layout->addWidget(saveFaceColor_);
601 
602  savePrecisionLabel_ = new QLabel("Writer Precision");
603  layout->addWidget(savePrecisionLabel_);
604 
605  savePrecision_ = new QSpinBox();
606  savePrecision_->setMinimum(1);
607  savePrecision_->setMaximum(12);
608  savePrecision_->setValue(6);
609  layout->addWidget(savePrecision_);
610 
611  saveDefaultButton_ = new QPushButton("Make Default");
612  layout->addWidget(saveDefaultButton_);
613 
614  saveOptions_->setLayout(layout);
615 
616  connect(saveBinary_, SIGNAL(clicked(bool)), savePrecision_, SLOT(setDisabled(bool)));
617  connect(saveDefaultButton_, SIGNAL(clicked()), this, SLOT(slotSaveDefault()));
618 
619  saveBinary_->setChecked( OpenFlipperSettings().value("FilePLY/Save/Binary",true).toBool() );
620  savePrecision_->setDisabled(true);
621  saveVertexNormal_->setChecked( OpenFlipperSettings().value("FilePLY/Save/Normals",true).toBool() );
622  saveVertexColor_->setChecked( OpenFlipperSettings().value("FilePLY/Save/VertexColor",true).toBool() );
623  saveVertexTexCoord_->setChecked( OpenFlipperSettings().value("FilePLY/Save/TexCoords",true).toBool() );
624  saveFaceNormal_->setChecked( OpenFlipperSettings().value("FilePLY/Save/FaceNormal",true).toBool() );
625  saveFaceColor_->setChecked( OpenFlipperSettings().value("FilePLY/Save/FaceColor",true).toBool() );
626  }
627 
628  return saveOptions_;
629 }
630 
631 //-----------------------------------------------------------------------------------------------------
632 
633 QWidget* FilePLYPlugin::loadOptionsWidget(QString /*_currentFilter*/) {
634 
635  if (loadOptions_ == 0){
636  //generate widget
637  loadOptions_ = new QWidget();
638  QVBoxLayout* layout = new QVBoxLayout();
639  layout->setAlignment(Qt::AlignTop);
640 
641  QLabel* label = new QLabel(tr("If PolyMesh is a Triangle Mesh:"));
642 
643  layout->addWidget(label);
644 
645  triMeshHandling_ = new QComboBox();
646  triMeshHandling_->addItem( tr("Auto-Detect") );
647  triMeshHandling_->addItem( tr("Ask") );
648  triMeshHandling_->addItem( tr("Always open as PolyMesh") );
649  triMeshHandling_->addItem( tr("Always open as TriangleMesh") );
650 
651  layout->addWidget(triMeshHandling_);
652 
653  loadVertexNormal_ = new QCheckBox("Load Vertex Normals");
654  layout->addWidget(loadVertexNormal_);
655 
656  loadVertexColor_ = new QCheckBox("Load Vertex Colors");
657  layout->addWidget(loadVertexColor_);
658 
659  loadVertexTexCoord_ = new QCheckBox("Load Vertex TexCoords");
660  layout->addWidget(loadVertexTexCoord_);
661 
662  loadFaceNormal_ = new QCheckBox("Load Face Normals");
663  layout->addWidget(loadFaceNormal_);
664 
665  loadFaceColor_ = new QCheckBox("Load Face Colors");
666  layout->addWidget(loadFaceColor_);
667 
668  loadDefaultButton_ = new QPushButton("Make Default");
669  layout->addWidget(loadDefaultButton_);
670 
671  loadOptions_->setLayout(layout);
672 
673  connect(loadDefaultButton_, SIGNAL(clicked()), this, SLOT(slotLoadDefault()));
674 
675 
676  triMeshHandling_->setCurrentIndex(OpenFlipperSettings().value("FilePLY/Load/TriMeshHandling",TYPEAUTODETECT).toInt() );
677 
678  loadVertexNormal_->setChecked( OpenFlipperSettings().value("FilePLY/Load/Normals",true).toBool() );
679  loadVertexColor_->setChecked( OpenFlipperSettings().value("FilePLY/Load/VertexColor",true).toBool() );
680  loadVertexTexCoord_->setChecked( OpenFlipperSettings().value("FilePLY/Load/TexCoords",true).toBool() );
681  loadFaceNormal_->setChecked( OpenFlipperSettings().value("FilePLY/Load/FaceNormal",true).toBool() );
682  loadFaceColor_->setChecked( OpenFlipperSettings().value("FilePLY/Load/FaceColor",true).toBool() );
683  }
684 
685  return loadOptions_;
686 }
687 
689 
690  OpenFlipperSettings().setValue( "FilePLY/Load/Normals", loadVertexNormal_->isChecked() );
691  OpenFlipperSettings().setValue( "FilePLY/Load/VertexColor", loadVertexColor_->isChecked() );
692  OpenFlipperSettings().setValue( "FilePLY/Load/TexCoords", loadVertexTexCoord_->isChecked() );
693  OpenFlipperSettings().setValue( "FilePLY/Load/FaceNormal", loadFaceNormal_->isChecked() );
694  OpenFlipperSettings().setValue( "FilePLY/Load/FaceColor", loadFaceColor_->isChecked() );
695 
696  OpenFlipperSettings().setValue( "FilePLY/Load/TriMeshHandling", triMeshHandling_->currentIndex() );
697 
698  OpenFlipperSettings().setValue( "Core/File/UseLoadDefaults", true );
699 }
700 
701 
703 
704  OpenFlipperSettings().setValue( "FilePLY/Save/Binary", saveBinary_->isChecked() );
705  OpenFlipperSettings().setValue( "FilePLY/Save/TexCoords", saveVertexTexCoord_->isChecked() );
706  OpenFlipperSettings().setValue( "FilePLY/Save/Normals", saveVertexNormal_->isChecked() );
707  OpenFlipperSettings().setValue( "FilePLY/Save/VertexColor", saveVertexColor_->isChecked() );
708  OpenFlipperSettings().setValue( "FilePLY/Save/FaceNormal", saveFaceNormal_->isChecked() );
709  OpenFlipperSettings().setValue( "FilePLY/Save/FaceColor", saveFaceColor_->isChecked() );
710 }
711 
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
Definition: FilePLY.cc:702
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
int id() const
Definition: BaseObject.cc:190
Has (r) / store (w) face colors.
Definition: Options.hh:109
bool write_mesh(const Mesh &_mesh, const std::string &_filename, Options _opt=Options::Default, std::streamsize _precision=6)
Write a mesh to the file _filename.
Definition: MeshIO.hh:207
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void slotLoadDefault()
Slot called when user wants to save the given Load options as default.
Definition: FilePLY.cc:688
QString getSaveFilters()
Definition: FilePLY.cc:91
Has (r) / store (w) face normals.
Definition: Options.hh:108
Kernel::FaceVertexIter FaceVertexIter
Circulator.
Definition: PolyMeshT.hh:167
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
MeshT * mesh()
return a pointer to the mesh
int loadTriMeshObject(QString _filename, OpenMesh::IO::Options &_opt)
Loads a triangle mesh.
Definition: FilePLY.cc:321
void setDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, int _viewer)
Set the draw Mode of a Viewer. .
QString getLoadFilters()
Definition: FilePLY.cc:85
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
QString filename() const
return the filename of the object
Definition: BaseObject.cc:706
QWidget * saveOptionsWidget(QString)
Definition: FilePLY.cc:576
Has (r) custom properties (currently only implemented in PLY Reader ASCII version) ...
Definition: Options.hh:113
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
Definition: FilePLY.cc:97
void backupTextureCoordinates(MeshT &_mesh)
creates a backup of the original per vertex/face texture coordinates
Set options for reader/writer modules.
Definition: Options.hh:90
void handleTrimeshDialog()
Displays a dialog to ask how to load the mesh (triangle, polymesh , autodetect)
Definition: FilePLY.cc:298
Predefined datatypes.
Definition: DataTypes.hh:83
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
int loadPolyMeshObject(QString _filename, OpenMesh::IO::Options &_opt)
Always loads mesh as polymesh.
Definition: FilePLY.cc:406
Set binary mode for r/w.
Definition: Options.hh:100
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
void update_face_normals()
Update normal vectors for all faces.
int objectCount()
Get the number of available objects.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
QWidget * loadOptionsWidget(QString)
Definition: FilePLY.cc:633
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
void initializePlugin()
Initialize Plugin.
Definition: FilePLY.cc:80
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
Definition: FilePLY.cc:168
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:73
void update_normals()
Compute normals for all primitives.
FilePLYPlugin()
Constructor.
Definition: FilePLY.cc:56