Developer Documentation
FileSTL.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 #include "FileSTL.hh"
51 
52 
53 #if QT_VERSION >= 0x050000
54  #include <QtWidgets>
55 #else
56  #include <QtGui>
57 #endif
58 
61  saveOptions_(0),
62  loadOptions_(0),
63  saveBinary_(0),
64  savePrecisionLabel_(0),
65  savePrecision_(0),
66  loadFaceNormal_(0),
67  saveDefaultButton_(0),
68  loadDefaultButton_(0)
69 
70 {
71 }
72 
73 //-----------------------------------------------------------------------------------------------------
74 
76 }
77 
78 //-----------------------------------------------------------------------------------------------------
79 
81  return QString( tr("Stereolithography files ( *.stl *.stla *.stlb )") );
82 };
83 
84 //-----------------------------------------------------------------------------------------------------
85 
87  return QString( tr("Stereolithography files ( *.stl *.stla *.stlb )") );
88 };
89 
90 //-----------------------------------------------------------------------------------------------------
91 
94  return type;
95 }
96 
97 //-----------------------------------------------------------------------------------------------------
98 
99 int FileSTLPlugin::loadObject(QString _filename) {
100 
101  int id = -1;
102  emit addEmptyObject(DATA_TRIANGLE_MESH, id);
103 
104  TriMeshObject* object(0);
105  if(PluginFunctions::getObject( id, object)) {
106 
107  if (PluginFunctions::objectCount() == 1 )
108  object->target(true);
109 
110  object->setFromFileName(_filename);
111  object->setName(object->filename());
112 
113  std::string filename = std::string( _filename.toUtf8() );
114 
115  object->mesh()->request_face_normals();
116 
117  bool loadNormals( (loadFaceNormal_ && loadFaceNormal_->isChecked()) ||
118  (!loadFaceNormal_ && OpenFlipperSettings().value("FileSTL/Load/FaceNormal", true).toBool())
119  );
120 
121  // load file
123  // load face normals from the stl file if requested
124  if (loadNormals) {
126  }
127 
128  bool ok = OpenMesh::IO::read_mesh( (*object->mesh()) , filename, opt );
129  if (!ok)
130  {
131  std::cerr << "Plugin FileSTL : Read error for stl mesh.\n";
132  emit deleteObject( object->id() );
133  return -1;
134 
135  }
136 
137  // only calculate the face normals if they are not read from the file
138  if (!loadNormals || !opt.face_has_normal())
139  object->mesh()->update_normals();
140  else {
141  if (object->mesh()->has_vertex_normals())
142  object->mesh()->update_vertex_normals();
143  if (object->mesh()->has_halfedge_normals())
144  object->mesh()->update_halfedge_normals();
145  }
146 
147  emit updatedObject(object->id(), UPDATE_ALL);
148 
149  emit openedFile( object->id() );
150 
151  return object->id();
152 
153  } else {
154  emit log(LOGERR,"Error : Could not create new triangle mesh object.");
155  return -1;
156  }
157 };
158 
159 //-----------------------------------------------------------------------------------------------------
160 
161 bool FileSTLPlugin::saveObject(int _id, QString _filename)
162 {
163  BaseObjectData* object;
164  if ( !PluginFunctions::getObject(_id,object) ) {
165  emit log(LOGERR, tr("saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
166  return false;
167  }
168 
169  std::string filename = std::string( _filename.toUtf8() );
170 
171  if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
172 
173  object->setFromFileName(_filename);
174  object->setName(object->filename());
175 
176  TriMeshObject* triObj = dynamic_cast<TriMeshObject* >( object );
177 
179 
180  std::streamsize precision = 6;
181  if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0){
182 
183  if (!OpenFlipper::Options::nogui() && saveBinary_->isChecked())
185 
186  if (!saveBinary_->isChecked())
187  precision = savePrecision_->value();
188 
189  }
190 
191  if (OpenMesh::IO::write_mesh(*triObj->mesh(), filename.c_str(), opt, precision) ) {
192  emit log(LOGINFO, tr("Saved object to ") + _filename );
193  return true;
194  } else {
195  emit log(LOGERR, tr("Unable to save ") + _filename );
196  return false;
197  }
198  } else {
199  emit log(LOGERR, tr("Unable to save (object is not a triangle mesh type)"));
200  return false;
201  }
202 }
203 
204 //-----------------------------------------------------------------------------------------------------
205 
206 QWidget* FileSTLPlugin::saveOptionsWidget(QString /*_currentFilter*/) {
207 
208  if (saveOptions_ == 0){
209  //generate widget
210  saveOptions_ = new QWidget();
211  QVBoxLayout* layout = new QVBoxLayout();
212  layout->setAlignment(Qt::AlignTop);
213 
214  saveBinary_ = new QCheckBox("Save Binary");
215  layout->addWidget(saveBinary_);
216 
217  savePrecisionLabel_ = new QLabel("Writer Precision");
218  layout->addWidget(savePrecisionLabel_);
219 
220  savePrecision_ = new QSpinBox();
221  savePrecision_->setMinimum(1);
222  savePrecision_->setMaximum(12);
223  savePrecision_->setValue(6);
224  layout->addWidget(savePrecision_);
225 
226  saveDefaultButton_ = new QPushButton("Make Default");
227  layout->addWidget(saveDefaultButton_);
228 
229  saveOptions_->setLayout(layout);
230 
231  saveBinary_->setChecked( OpenFlipperSettings().value( "FileSTL/Save/Binary", false ).toBool() );
232 
233  connect(saveBinary_, SIGNAL(clicked(bool)), savePrecision_, SLOT(setDisabled(bool)));
234  connect(saveDefaultButton_, SIGNAL(clicked()), this, SLOT(slotSaveDefault()));
235 
236  }
237 
238  return saveOptions_;
239 }
240 
241 //-----------------------------------------------------------------------------------------------------
242 
243 QWidget* FileSTLPlugin::loadOptionsWidget(QString /*_currentFilter*/) {
244 
245  if (loadOptions_ == 0){
246  //generate widget
247  loadOptions_ = new QWidget();
248  QVBoxLayout* layout = new QVBoxLayout();
249  layout->setAlignment(Qt::AlignTop);
250 
251  loadFaceNormal_ = new QCheckBox("Load Face Normals");
252  layout->addWidget(loadFaceNormal_);
253 
254  loadFaceNormal_->setChecked( OpenFlipperSettings().value("FileSTL/Load/FaceNormal",true).toBool() );
255 
256  loadDefaultButton_ = new QPushButton("Make Default");
257  layout->addWidget(loadDefaultButton_);
258 
259  loadOptions_->setLayout(layout);
260 
261  connect(loadDefaultButton_, SIGNAL(clicked()), this, SLOT(slotLoadDefault()));
262  }
263 
264  return loadOptions_;
265 }
266 
267 //-----------------------------------------------------------------------------------------------------
268 
270  OpenFlipperSettings().setValue( "FileSTL/Load/FaceNormal", loadFaceNormal_->isChecked() );
271  OpenFlipperSettings().setValue( "Core/File/UseLoadDefaults", true );
272 }
273 
274 //-----------------------------------------------------------------------------------------------------
275 
277  OpenFlipperSettings().setValue( "FileSTL/Save/Binary", saveBinary_->isChecked() );
278 }
279 #if QT_VERSION < 0x050000
280  Q_EXPORT_PLUGIN2( filestlplugin , FileSTLPlugin );
281 #endif
282 
283 
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
Definition: FileSTL.cc:92
Predefined datatypes.
Definition: DataTypes.hh:96
QWidget * loadOptionsWidget(QString)
Definition: FileSTL.cc:243
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:73
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
Definition: FileSTL.cc:276
Set binary mode for r/w.
Definition: Options.hh:105
QString filename() const
return the filename of the object
Definition: BaseObject.cc:717
bool getObject(int _identifier, BSplineCurveObject *&_object)
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
Has (r) / store (w) face normals.
Definition: Options.hh:113
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
int id() const
Definition: BaseObject.cc:201
void initializePlugin()
Initialize Plugin.
Definition: FileSTL.cc:75
MeshT * mesh()
return a pointer to the mesh
Definition: MeshObjectT.cc:351
int loadObject(QString _filename)
Loads Object as triangle mesh.
Definition: FileSTL.cc:99
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
FileSTLPlugin()
Constructor.
Definition: FileSTL.cc:60
int objectCount()
Get the number of available objects.
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:104
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
QWidget * saveOptionsWidget(QString)
Definition: FileSTL.cc:206
Set options for reader/writer modules.
Definition: Options.hh:95
void slotLoadDefault()
Slot called when user wants to save the given Load options as default.
Definition: FileSTL.cc:269
QString getSaveFilters()
Definition: FileSTL.cc:86
QString getLoadFilters()
Definition: FileSTL.cc:80
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
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:199