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