FileOBJ.cc 70.7 KB
Newer Older
Dirk Wilden's avatar
Dirk Wilden committed
1
/*===========================================================================*\
Martin Schultz's avatar
Martin Schultz committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 *                                                                           *
 *                             OpenFlipper                                   *
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
 *                                                                           *
Dirk Wilden's avatar
Dirk Wilden committed
40
41
42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43
44
45
46
47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
Dirk Wilden's avatar
Dirk Wilden committed
48
\*===========================================================================*/
49
50
51
52
#include <ACG/GL/GLState.hh>

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"
#include "OpenFlipper/common/GlobalOptions.hh"
Dirk Wilden's avatar
Dirk Wilden committed
53

54
55
#include <OpenMesh/Core/IO/IOManager.hh>

Martin Schultz's avatar
Martin Schultz committed
56
#include <OpenFlipper/Utils/Memory/RAMInfo.hh>
Matthias Möller's avatar
Matthias Möller committed
57
58
59
60
61
62
63

#if QT_VERSION >= 0x050000 
  #include <QtWidgets>
#else
  #include <QtGui>
#endif

Dirk Wilden's avatar
Dirk Wilden committed
64
65
#include "FileOBJ.hh"

Martin Schultz's avatar
Martin Schultz committed
66
#include <ACG/Utils/SmartPointer.hh>
Martin Schultz's avatar
Martin Schultz committed
67
#include <OpenFlipper/Utils/FileIO/NumberParsing.hh>
Dirk Wilden's avatar
Dirk Wilden committed
68

69
70
71
72
73
74
// Defines for the type handling drop down box
#define TYPEAUTODETECT 0
#define TYPEASK        1
#define TYPEPOLY       2
#define TYPETRIANGLE   3

Martin Schultz's avatar
Martin Schultz committed
75
76
using namespace Utils;

77
78
79
80
81
//-----------------------------------------------------------------------------
// help functions

void remove_duplicated_vertices(VHandles& _indices)
{
82
83
84
85
86
  VHandles::iterator endIter = _indices.end();
  for (VHandles::iterator iter = _indices.begin(); iter != endIter; ++iter)
    endIter = std::remove(iter+1, endIter, *(iter));

  _indices.erase(endIter,_indices.end());
87
88
89
90
}

//-----------------------------------------------------------------------------

Dirk Wilden's avatar
Dirk Wilden committed
91
92
93
94
/// Constructor
FileOBJPlugin::FileOBJPlugin()
: loadOptions_(0),
  saveOptions_(0),
95
96
97
98
99
100
101
102
103
  saveBinary_(0),
  saveVertexColor_(0),
  saveFaceColor_(0),
  saveAlpha_(0),
  saveNormals_(0),
  saveTexCoords_(0),
  saveTextures_(0),
  saveCopyTextures_(0),
  saveCreateTexFolder_(0),
104
105
  savePrecisionLabel_(0),
  savePrecision_(0),
106
  saveDefaultButton_(0),
Dirk Wilden's avatar
Dirk Wilden committed
107
  triMeshHandling_(0),
108
109
110
111
112
113
114
  loadVertexColor_(0),
  loadFaceColor_(0),
  loadAlpha_(0),
  loadNormals_(0),
  loadTexCoords_(0),
  loadTextures_(0),
  loadDefaultButton_(0),
Dirk Wilden's avatar
Dirk Wilden committed
115
  forceTriangleMesh_(false),
116
117
  forcePolyMesh_(false),
  textureIndexPropFetched_(false)
Dirk Wilden's avatar
Dirk Wilden committed
118
119
120
121
122
{
}

//-----------------------------------------------------------------------------------------------------

123
void FileOBJPlugin::initializePlugin() {  
Dirk Wilden's avatar
Dirk Wilden committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
}

//-----------------------------------------------------------------------------------------------------

QString FileOBJPlugin::getLoadFilters() {
    return QString( tr("Alias/Wavefront ( *.obj )") );
};

//-----------------------------------------------------------------------------------------------------

QString FileOBJPlugin::getSaveFilters() {
    return QString( tr("Alias/Wavefront ( *.obj )") );
};

//-----------------------------------------------------------------------------------------------------

DataType  FileOBJPlugin::supportedType() {
141
    DataType type = DATA_POLY_MESH | DATA_TRIANGLE_MESH | DATA_GROUP;
142

Dirk Wilden's avatar
Dirk Wilden committed
143
144
145
146
147
148
149
150
    #ifdef ENABLE_BSPLINECURVE_SUPPORT
      type |= DATA_BSPLINE_CURVE;
    #endif

    #ifdef ENABLE_BSPLINESURFACE_SUPPORT
      type |= DATA_BSPLINE_SURFACE;
    #endif

Dirk Wilden's avatar
Dirk Wilden committed
151
152
153
154
155
156
157
    return type;
}

//-----------------------------------------------------------------------------

bool FileOBJPlugin::readMaterial(QString _filename, OBJImporter& _importer)
{
Martin Schultz's avatar
Martin Schultz committed
158
159
160
161
162
163
164
165
166
  static QString line;
  static QString keyWrd;
  static QString textureName;
  line.clear();
  keyWrd.clear();
  textureName.clear();

  static QString matName;
  matName.clear();
Martin Schultz's avatar
Martin Schultz committed
167
168
169
170
171
172
173
174
175
176
  static Material    mat;
  mat.cleanup();
  static float       f1,f2,f3;
  f1 = 0;
  f2 = 0;
  f3 = 0;
  static bool        insideDefintion;
  insideDefintion = false;
  static int         textureId;
  textureId = 1;
177
178


Dirk Wilden's avatar
Dirk Wilden committed
179
  //open stream
180
181
182
183
184
185
  QFile matFile(_filename);
  if (!matFile.open(QFile::ReadOnly))
  {
    emit log(LOGERR, tr("readMaterial : cannot open file %1").arg(_filename));
    return false;
  }
Dirk Wilden's avatar
Dirk Wilden committed
186

187
  QTextStream matStream(&matFile);
Martin Schultz's avatar
Martin Schultz committed
188
  if ( matStream.status()!=QTextStream::Ok ){
189
    emit log(LOGERR, tr("readMaterial : cannot open stream %1").arg(_filename) );
Dirk Wilden's avatar
Dirk Wilden committed
190
191
192
193
194
195
196
    return false;
  }

  //clear temp material
  mat.cleanup();

  //parse material file
Martin Schultz's avatar
Martin Schultz committed
197
  while( matStream.status() == QTextStream::Ok && !matStream.atEnd() )
Dirk Wilden's avatar
Dirk Wilden committed
198
  {
Martin Schultz's avatar
Martin Schultz committed
199
200
    line = matStream.readLine();
    if ( matStream.status() != QTextStream::Ok ){
Dirk Wilden's avatar
Dirk Wilden committed
201
202
203
204
      emit log(LOGERR, tr("readMaterial : Warning! Could not read file properly!"));
      return false;
    }

Martin Schultz's avatar
Martin Schultz committed
205
    if ( line.isEmpty() )
Dirk Wilden's avatar
Dirk Wilden committed
206
207
      continue;

Martin Schultz's avatar
Martin Schultz committed
208
    QTextStream stream(&line);
Dirk Wilden's avatar
Dirk Wilden committed
209
210
211

    stream >> keyWrd;

Martin Schultz's avatar
Martin Schultz committed
212
    if( ( line[0].isSpace() && line[0] != QLatin1Char('\t') ) || line[0] == QLatin1Char('#') )
Dirk Wilden's avatar
Dirk Wilden committed
213
    {
Martin Schultz's avatar
Martin Schultz committed
214
      if (insideDefintion && !matName.isEmpty() && mat.is_valid())
Dirk Wilden's avatar
Dirk Wilden committed
215
      {
Martin Schultz's avatar
Martin Schultz committed
216
        _importer.materials()[matName.toStdString()] = mat;
Dirk Wilden's avatar
Dirk Wilden committed
217
218
219
220
        mat.cleanup();
      }
    }

Martin Schultz's avatar
Martin Schultz committed
221
    else if (keyWrd == QLatin1String("newmtl")) // begin new material definition
Dirk Wilden's avatar
Dirk Wilden committed
222
223
224
225
226
    {
      stream >> matName;
      insideDefintion = true;
    }

Martin Schultz's avatar
Martin Schultz committed
227
    else if (keyWrd == QLatin1String("Kd")) // diffuse color
Dirk Wilden's avatar
Dirk Wilden committed
228
    {
Martin Schultz's avatar
Martin Schultz committed
229
230
231
      f1 = getFloat(stream);
      f2 = getFloat(stream);
      f3 = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
232

Martin Schultz's avatar
Martin Schultz committed
233
      if( stream.status()==QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
234
235
236
        mat.set_Kd(f1,f2,f3);
    }

Martin Schultz's avatar
Martin Schultz committed
237
    else if (keyWrd == QLatin1String("Ka")) // ambient color
Dirk Wilden's avatar
Dirk Wilden committed
238
    {
Martin Schultz's avatar
Martin Schultz committed
239
240
241
      f1 = getFloat(stream);
      f2 = getFloat(stream);
      f3 = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
242

Martin Schultz's avatar
Martin Schultz committed
243
      if( stream.status()!=QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
244
245
246
        mat.set_Ka(f1,f2,f3);
    }

Martin Schultz's avatar
Martin Schultz committed
247
    else if (keyWrd == QLatin1String("Ks")) // specular color
Dirk Wilden's avatar
Dirk Wilden committed
248
    {
Martin Schultz's avatar
Martin Schultz committed
249
250
251
      f1 = getFloat(stream);
      f2 = getFloat(stream);
      f3 = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
252

Martin Schultz's avatar
Martin Schultz committed
253
      if( stream.status()!=QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
254
255
256
        mat.set_Ks(f1,f2,f3);
    }
#if 0
Martin Schultz's avatar
Martin Schultz committed
257
    else if (keyWrd == QLatin1String("illum") // diffuse/specular shading model
Dirk Wilden's avatar
Dirk Wilden committed
258
259
260
261
    {
      ; // just skip this
    }

Martin Schultz's avatar
Martin Schultz committed
262
    else if (keyWrd == QLatin1String("Ns") // Shininess [0..200]
Dirk Wilden's avatar
Dirk Wilden committed
263
264
265
266
    {
      ; // just skip this
    }

Martin Schultz's avatar
Martin Schultz committed
267
    else if (keyWrd == QLatin1String("map_") // map images
Dirk Wilden's avatar
Dirk Wilden committed
268
269
270
271
272
273
274
275
    {
      // map_Ks, specular map
      // map_Ka, ambient map
      // map_Bump, bump map
      // map_d,  opacity map
      ; // just skip this
    }
#endif
Martin Schultz's avatar
Martin Schultz committed
276
    else if (keyWrd == QLatin1String("map_Kd") ) {
Dirk Wilden's avatar
Dirk Wilden committed
277
278
      // Get the rest of the line, removing leading or trailing spaces
      // This will define the filename of the texture
Martin Schultz's avatar
Martin Schultz committed
279
280
281
282
      textureName = stream.readLine();
      textureName = textureName.trimmed();
      if ( ! textureName.isEmpty() )
        mat.set_map_Kd( textureName.toStdString(), textureId++ );
Dirk Wilden's avatar
Dirk Wilden committed
283
    }
Martin Schultz's avatar
Martin Schultz committed
284
    else if (keyWrd == QLatin1String("Tr")) // transparency value
Dirk Wilden's avatar
Dirk Wilden committed
285
    {
Martin Schultz's avatar
Martin Schultz committed
286
      f1 = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
287

Martin Schultz's avatar
Martin Schultz committed
288
      if( stream.status() == QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
289
290
        mat.set_Tr(f1);
    }
Martin Schultz's avatar
Martin Schultz committed
291
    else if (keyWrd == QLatin1String("d")) // transparency value
Dirk Wilden's avatar
Dirk Wilden committed
292
    {
Martin Schultz's avatar
Martin Schultz committed
293
      f1 = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
294

Martin Schultz's avatar
Martin Schultz committed
295
      if( stream.status() == QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
296
297
298
        mat.set_Tr(f1);
    }

Martin Schultz's avatar
Martin Schultz committed
299
300
    if ( matStream.status() == QTextStream::Ok && insideDefintion && mat.is_valid() && !matName.isEmpty())
      _importer.materials()[matName.toStdString()] = mat;
Dirk Wilden's avatar
Dirk Wilden committed
301
302
303
304
305
306
307
308
309
  }

  emit log( tr("%1 materials loaded.").arg( _importer.materials().size() ) );

  return true;
}

//-----------------------------------------------------------------------------

310
311
void FileOBJPlugin::createAllGroupObjects(OBJImporter& _importer) {

312
    for(unsigned int i = 0; i < _importer.numGroups(); ++i) {
Dirk Wilden's avatar
Dirk Wilden committed
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
        // Get group name
        QString name = _importer.groupName(i);
        convertToOBJName(name);

        if ( _importer.isTriangleMesh( i )  ){

            // add a triangle mesh
            int id = -1;
            emit addEmptyObject(DATA_TRIANGLE_MESH, id);

            BaseObjectData* object(0);

            if (PluginFunctions::getObject(id, object)) {

                _importer.setObject(object, i);

                object->setPath(_importer.path());
                object->setName(name);
            }

        } else if (_importer.isPolyMesh( i )) {

            int id = -1;
            emit addEmptyObject(DATA_POLY_MESH, id);

            BaseObjectData* object(0);

            if (PluginFunctions::getObject(id, object)) {

                _importer.setObject(object, i);

                object->setPath(_importer.path());
                object->setName(name);
            }
        }
Dirk Wilden's avatar
Dirk Wilden committed
349

Dirk Wilden's avatar
Dirk Wilden committed
350
351
#ifdef ENABLE_BSPLINECURVE_SUPPORT

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
        else if (_importer.isCurve( i )) {

            int id = -1;
            emit addEmptyObject(DATA_BSPLINE_CURVE, id);

            BaseObjectData* object(0);

            if (PluginFunctions::getObject(id, object)) {

                _importer.setObject(object, i);

                object->setPath(_importer.path());
                object->setName(name);
            }
        }

Dirk Wilden's avatar
Dirk Wilden committed
368
369
370
371
#endif

#ifdef ENABLE_BSPLINESURFACE_SUPPORT

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
        else if (_importer.isSurface( i )) {

            int id = -1;
            emit addEmptyObject(DATA_BSPLINE_SURFACE, id);

            BaseObjectData* object(0);

            if (PluginFunctions::getObject(id, object)) {

                _importer.setObject(object, i);

                object->setPath(_importer.path());
                object->setName(name);
            }
        }

Dirk Wilden's avatar
Dirk Wilden committed
388
#endif
389
390
391
392
393
394
395
396
397
398
399
400
401
402

        //force gui settings
        if (OpenFlipper::Options::gui() && loadOptions_ != 0) {

            if (!loadFaceColor_->isChecked())
                _importer.objectOptions()[ i ] |= OBJImporter::FORCE_NOCOLOR;

            if (!loadNormals_->isChecked())
                _importer.objectOptions()[ i ] |= OBJImporter::FORCE_NONORMALS;

            if (!loadTexCoords_->isChecked() || !loadTextures_->isChecked())
                _importer.objectOptions()[ i ] |= OBJImporter::FORCE_NOTEXTURES;
        }
    }
Dirk Wilden's avatar
Dirk Wilden committed
403
404
}

Mike Kremer's avatar
Mike Kremer committed
405
void FileOBJPlugin::convertToOBJName(QString& _name) {
406

Mike Kremer's avatar
Mike Kremer committed
407
    QFileInfo fi(_name);
408

Mike Kremer's avatar
Mike Kremer committed
409
    QString n = fi.baseName();
410

Mike Kremer's avatar
Mike Kremer committed
411
412
413
    _name = n.trimmed() + ".obj";
}

414
415
416
417
418
419
420
421
422
423
424
425
/// creates a backup of the original per vertex/face texture coordinates
template <class MeshT>
void FileOBJPlugin::backupTextureCoordinates(MeshT& _mesh) {

    // Create a backup of the original per Vertex texture Coordinates
    if (_mesh.has_vertex_texcoords2D()) {

      OpenMesh::VPropHandleT< typename MeshT::TexCoord2D > oldVertexCoords;
      if (!_mesh.get_property_handle(oldVertexCoords, "Original Per Vertex Texture Coords"))
        _mesh.add_property(oldVertexCoords, "Original Per Vertex Texture Coords");

      for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
Matthias Möller's avatar
Matthias Möller committed
426
        _mesh.property(oldVertexCoords, *v_it) =  _mesh.texcoord2D(*v_it);
427
428
429
430
431
432
433
434
435
436
437

    }

    // Create a backup of the original per Face texture Coordinates
    if (_mesh.has_halfedge_texcoords2D()) {

      OpenMesh::HPropHandleT< typename MeshT::TexCoord2D > oldHalfedgeCoords;
      if (!_mesh.get_property_handle(oldHalfedgeCoords,"Original Per Face Texture Coords"))
        _mesh.add_property(oldHalfedgeCoords,"Original Per Face Texture Coords");

      for (typename MeshT::HalfedgeIter he_it = _mesh.halfedges_begin(); he_it != _mesh.halfedges_end(); ++he_it)
Matthias Möller's avatar
Matthias Möller committed
438
        _mesh.property(oldHalfedgeCoords, *he_it) =  _mesh.texcoord2D(*he_it);
439
440
441
442

    }
}

Dirk Wilden's avatar
Dirk Wilden committed
443
444
445
446
447
448
449
450

//add textures to the mesh
void FileOBJPlugin::addTextures(OBJImporter& _importer, int _objectID ){

  // TODO : If only one Texture, use single Texturing mode
  if ( true ) {

    BaseObject* object = _importer.object(_objectID);
451

Dirk Wilden's avatar
Dirk Wilden committed
452
453
    if (!object)
      return;
454

Dirk Wilden's avatar
Dirk Wilden committed
455
456
457
    std::map< int,int > newMapping;
    // zero ( no texture ) always maps to to zero
    newMapping[0]=0;
458

Dirk Wilden's avatar
Dirk Wilden committed
459
    const std::vector<std::string> matNames = _importer.usedMaterials( _objectID );
460

Jan Möbius's avatar
Jan Möbius committed
461
    for (unsigned int i=0; i < matNames.size(); i++){
462

Dirk Wilden's avatar
Dirk Wilden committed
463
      Material& material = _importer.materials()[ matNames[i] ];
464

Dirk Wilden's avatar
Dirk Wilden committed
465
      int textureId = -1;
466

Dirk Wilden's avatar
Dirk Wilden committed
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
      QString textureBlock = QString( material.map_Kd().c_str());


      QStringList options = textureBlock.split(" ",QString::SkipEmptyParts);

      while ( options.size() > 1 ) {
        if ( options[0] == "-blendu" ) {
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-blendv" ) {
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-cc" ) {
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-clamp" ) {
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-mm" ) {
          options.pop_front();
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-o" ) {
          options.pop_front();
          options.pop_front();
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-s" ) {
          options.pop_front();
          options.pop_front();
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-t" ) {
          options.pop_front();
          options.pop_front();
          options.pop_front();
          options.pop_front();
        } else if ( options[0] == "-texres" ) {
          options.pop_front();
          options.pop_front();
        } else  {
          break;
        }
      }

      QString fullName = _importer.path() + QDir::separator() + options.join(" ");

      QFileInfo info(fullName);
      if ( info.exists() )
Mike Kremer's avatar
Mike Kremer committed
516
        emit addMultiTexture("OBJ Data", info.baseName().trimmed(), fullName, object->id(), textureId );
Dirk Wilden's avatar
Dirk Wilden committed
517
518
519
520
      else {
        emit log(LOGWARN, tr("Unable to load texture image %1").arg( QString(material.map_Kd().c_str()) ) );
        addMultiTexture("OBJ Data","Unknown Texture image " + QString::number(textureId), "unknown.png", object->id(), textureId );
      }
521

Dirk Wilden's avatar
Dirk Wilden committed
522
523
      newMapping[ material.map_Kd_index() ] = textureId;
    }
524

Dirk Wilden's avatar
Dirk Wilden committed
525
    //now map all texture indices to the real texture indices used in OpenFlipper
526

Dirk Wilden's avatar
Dirk Wilden committed
527
    OpenMesh::FPropHandleT< int > indexProperty;
528

Dirk Wilden's avatar
Dirk Wilden committed
529
530
    //handle PolyMeshes
    PolyMeshObject* polyMeshObj = dynamic_cast< PolyMeshObject* > (object);
531

Dirk Wilden's avatar
Dirk Wilden committed
532
    if ( polyMeshObj ){
533

Dirk Wilden's avatar
Dirk Wilden committed
534
535
536
537
538
      PolyMesh& mesh = *(polyMeshObj->mesh());

      PolyMesh::FaceIter f_it;
      PolyMesh::FaceIter f_end = mesh.faces_end();

539
      if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
Dirk Wilden's avatar
Dirk Wilden committed
540
        return;
541

Dirk Wilden's avatar
Dirk Wilden committed
542
      for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
Matthias Möller's avatar
Matthias Möller committed
543
        mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
544

545
      backupTextureCoordinates(mesh);
546

Dirk Wilden's avatar
Dirk Wilden committed
547
548
      return;
    }
549

Dirk Wilden's avatar
Dirk Wilden committed
550
551
    //handle new TriMeshes
    TriMeshObject* triMeshObj = dynamic_cast< TriMeshObject* > (object);
552

Dirk Wilden's avatar
Dirk Wilden committed
553
    if ( triMeshObj ){
554

Dirk Wilden's avatar
Dirk Wilden committed
555
556
557
558
559
      TriMesh& mesh = *(triMeshObj->mesh());

      TriMesh::FaceIter f_it;
      TriMesh::FaceIter f_end = mesh.faces_end();

560
      if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
Dirk Wilden's avatar
Dirk Wilden committed
561
        return;
562

Dirk Wilden's avatar
Dirk Wilden committed
563
      for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
Matthias Möller's avatar
Matthias Möller committed
564
        mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
565

566
      backupTextureCoordinates(mesh);
567

Dirk Wilden's avatar
Dirk Wilden committed
568
569
570
571
572
      return;
    }
  }
}

Martin Schultz's avatar
Martin Schultz committed
573
void FileOBJPlugin::readOBJFile(QByteArray& _bufferedFile, QString _filename, OBJImporter& _importer)
Dirk Wilden's avatar
Dirk Wilden committed
574
575
{
  QString path = QFileInfo(_filename).absolutePath();
Martin Schultz's avatar
Martin Schultz committed
576
577
  ptr::shared_ptr<QTextStream> streamPointer;
  ptr::shared_ptr<QFile> sourceFile;
578

Martin Schultz's avatar
Martin Schultz committed
579
580
  ////setup filestream if not in memory
  if (_bufferedFile.isNull())
581
  {
Martin Schultz's avatar
Martin Schultz committed
582
583
584
585
586
587
588
589
590
      sourceFile.reset(new QFile(_filename) );
	  if(!sourceFile->open(QFile::ReadOnly))
	  {
	    emit log(LOGERR, tr("readOBJFile : cannot open file %1").arg(_filename) );
	    return;
	  }
	  //use the QTextStream and QString objects, since they seem to be more efficient when parsing strings.
	  //especially regarding copy operations.
      streamPointer.reset( new QTextStream(sourceFile.get()));
Dirk Wilden's avatar
Dirk Wilden committed
591
  }
Martin Schultz's avatar
Martin Schultz committed
592
593
594
595
596
597
  else
  {
      streamPointer.reset( new QTextStream(&_bufferedFile));
  }
  QTextStream input(streamPointer->device());
  input.seek(0);
598
599
600
  QTextStream stream;
  QTextStream lineData;
  QTextStream tmp;
Martin Schultz's avatar
Martin Schultz committed
601
  if ( input.status() != QTextStream::Ok){
602
603
604
    emit log(LOGERR, tr("readOBJFile : cannot read file %1 is the file corrupt?").arg(_filename) );
    return;
  }
Dirk Wilden's avatar
Dirk Wilden committed
605

Dirk Wilden's avatar
Dirk Wilden committed
606
607
608
609
  QString currentFileName = QFileInfo(_filename).fileName() ;

  ReaderMode mode = NONE;

610
611
  QString line;
  QString keyWrd;
Martin Schultz's avatar
Martin Schultz committed
612
  QString nextKeyWrd = QLatin1String("");
Dirk Wilden's avatar
Dirk Wilden committed
613

Jan Möbius's avatar
Jan Möbius committed
614
#ifdef ENABLE_BSPLINECURVE_SUPPORT
615
  unsigned int curveCount = 0;
Jan Möbius's avatar
Jan Möbius committed
616
617
618
#endif

#ifdef ENABLE_BSPLINESURFACE_SUPPORT
619
  unsigned int surfaceCount = 0;
Jan Möbius's avatar
Jan Möbius committed
620
#endif
621

Dirk Wilden's avatar
Dirk Wilden committed
622
  float x, y, z, u, v;
Jan Möbius's avatar
Jan Möbius committed
623
  int   deg;
Dirk Wilden's avatar
Dirk Wilden committed
624
625
626

  std::vector<VertexHandle> vhandles;
  std::vector<int>          face_texcoords;
627
  QString                   matname;
Dirk Wilden's avatar
Dirk Wilden committed
628

Matthias Möller's avatar
Matthias Möller committed
629
#if defined (ENABLE_BSPLINECURVE_SUPPORT) || defined (ENABLE_BSPLINESURFACE_SUPPORT)
Dirk Wilden's avatar
Dirk Wilden committed
630
631
  std::vector< int > cpIndices;
  std::vector< double > knotsU,knotsV;
Matthias Möller's avatar
Matthias Möller committed
632
#endif
633

Dirk Wilden's avatar
Dirk Wilden committed
634
  int faceCount = 0;
635

636
637
  // We have to keep track of the already read number of vertices to resolve relative (negative indices)
  int currentVertexCount = 0;
638

639
640
  // We have to keep track of the already read number of Texture coordinates to resolve relative (negative indices)
  int currentTextureCoordCount = 0;
641

642
643
  // We have to keep track of the already read number of normals to resolve relative (negative indices)
  int currentNormalCount = 0;
Dirk Wilden's avatar
Dirk Wilden committed
644

645
646
647
648
649
  // keeps track if faces belong to a group or the default group
  bool inGroup = false;
  // keeps track if the first face of a mesh has been read yet or not
  bool firstFace = true;

Dirk Wilden's avatar
Dirk Wilden committed
650
  _importer.setPath( path );
651

652
653
654
655
656
657
  // Set filename for default mesh
  _importer.setGroupName(0, currentFileName);

  // Now add all meshes for every group (if exists)
  createAllGroupObjects(_importer);

658
  while(  !input.atEnd() )
Dirk Wilden's avatar
Dirk Wilden committed
659
  {
660
    line=input.readLine();
Martin Schultz's avatar
Martin Schultz committed
661
    if ( input.status() == QTextStream::ReadCorruptData ){
Dirk Wilden's avatar
Dirk Wilden committed
662
663
664
665
666
      emit log(LOGERR, tr("readOBJFile : Warning! Could not read file properly!"));
      return;
    }

    // Trim Both leading and trailing spaces
Martin Schultz's avatar
Martin Schultz committed
667
    line = line.trimmed();
668

Dirk Wilden's avatar
Dirk Wilden committed
669
    // comment
Martin Schultz's avatar
Martin Schultz committed
670
    if ( line.isEmpty() || line[0] == QLatin1Char('#') || line[0].isSpace() ) {
Dirk Wilden's avatar
Dirk Wilden committed
671
672
673
      continue;
    }

674
    stream.setString(&line,QIODevice::ReadOnly);
Dirk Wilden's avatar
Dirk Wilden committed
675

Dirk Wilden's avatar
Dirk Wilden committed
676
677
    //unless the keyWrd for the new line is not determined by the previous line
    //read it from stream
Martin Schultz's avatar
Martin Schultz committed
678
    if (nextKeyWrd == QLatin1String(""))
Dirk Wilden's avatar
Dirk Wilden committed
679
680
681
      stream >> keyWrd;
    else {
      keyWrd = nextKeyWrd;
682
      nextKeyWrd = QLatin1String("");
Dirk Wilden's avatar
Dirk Wilden committed
683
    }
Dirk Wilden's avatar
Dirk Wilden committed
684
685

    // material file
686
    if (mode == NONE && keyWrd == QLatin1String("mtllib"))
Dirk Wilden's avatar
Dirk Wilden committed
687
    {
688
      QString matString;
Dirk Wilden's avatar
Dirk Wilden committed
689
690

      // This will define the filename of the texture
691
      matString = stream.readLine();
692

693
      QString matFile = path + QDir::separator() + matString.trimmed();
Dirk Wilden's avatar
Dirk Wilden committed
694
695
696
697
698
699
700

      emit log( tr("Loading material file: %1").arg( matFile ) );

      readMaterial( matFile, _importer );
    }

    // usemtl
701
    else if (mode == NONE && keyWrd == QLatin1String("usemtl"))
Dirk Wilden's avatar
Dirk Wilden committed
702
703
    {
      stream >> matname;
704
      if ( _importer.materials().find(matname.toStdString())==_importer.materials().end() )
Dirk Wilden's avatar
Dirk Wilden committed
705
      {
706
        emit log( LOGERR, tr("Warning! Material '%1' not defined in material file").arg( matname ) );
Martin Schultz's avatar
Martin Schultz committed
707
        matname=QLatin1String("");
708

Dirk Wilden's avatar
Dirk Wilden committed
709
      }else{
710

711
        Material& mat = _importer.materials()[matname.toStdString()];
712

Mike Kremer's avatar
Mike Kremer committed
713
        if ( mat.has_Texture() ){
Dirk Wilden's avatar
Dirk Wilden committed
714
          //add object if not already there
715
          _importer.useMaterial( matname.toStdString() );
Dirk Wilden's avatar
Dirk Wilden committed
716
        }
Dirk Wilden's avatar
Dirk Wilden committed
717
      }
718
    }
719
    else if (mode == NONE && keyWrd == QLatin1String("v"))
720
    {
721
722
723
     if (!firstFace)
       firstFace = true;

724
     currentVertexCount++;
Dirk Wilden's avatar
Dirk Wilden committed
725
726
    }
    // texture coord
Martin Schultz's avatar
Martin Schultz committed
727
    else if (mode == NONE && keyWrd == QLatin1String("vt"))
Dirk Wilden's avatar
Dirk Wilden committed
728
    {
729
730
731
      if (!firstFace)
        firstFace = true;

732
733
      // New texture coordinate read so increase counter
      currentTextureCoordCount++;
734

735
736
      u = getFloat(stream);
      v = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
737

738
      if ( stream.status() == QTextStream::Ok ){
Dirk Wilden's avatar
Dirk Wilden committed
739
740
741
742
743

        _importer.addTexCoord( OpenMesh::Vec2f(u, v) );

      }else{

744
        emit log( LOGERR, tr("Could not add TexCoord. Possible NaN or Inf?\nOnly single 2D texture coordinate per vertex allowed"));
Dirk Wilden's avatar
Dirk Wilden committed
745
746
747
748
749
      }
    }


    // normal
750
    else if (mode == NONE && keyWrd == QLatin1String("vn"))
Dirk Wilden's avatar
Dirk Wilden committed
751
    {
752
753
754
      if (!firstFace)
        firstFace = true;

755
756
      // New normal read so increase counter
      currentNormalCount++;
757

758
759
760
      x = getFloat(stream);
      y = getFloat(stream);
      z = getFloat(stream);
Dirk Wilden's avatar
Dirk Wilden committed
761

762
      if ( stream.status() == QTextStream::Ok ){
Dirk Wilden's avatar
Dirk Wilden committed
763
        _importer.addNormal( OpenMesh::Vec3f(x,y,z) );
764
765
      }else{
        emit log( LOGERR, tr("Could not read normal. Possible NaN or Inf?"));
Dirk Wilden's avatar
Dirk Wilden committed
766
767
      }
    }
768

Dirk Wilden's avatar
Dirk Wilden committed
769
    // degree (for curves)
770
    else if (mode == NONE && keyWrd == QLatin1String("deg"))
Dirk Wilden's avatar
Dirk Wilden committed
771
772
773
    {
      stream >> deg;

774
      if ( stream.status() == QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
775
776
777
778
        _importer.setDegreeU( deg );

      stream >> deg;

779
      if ( stream.status() == QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
780
781
        _importer.setDegreeV( deg );
    }
Dirk Wilden's avatar
Dirk Wilden committed
782
783

    // group
Martin Schultz's avatar
Martin Schultz committed
784
    else if (mode == NONE && keyWrd == QLatin1String("g")){
785
786
787
      if (!firstFace)
        firstFace = true;

788
789
      QString groupName;
      groupName = stream.readLine();
Dirk Wilden's avatar
Dirk Wilden committed
790

791
      if(faceCount == 0) {
792
        currentFileName = groupName;
Mike Kremer's avatar
Mike Kremer committed
793
      }
Dirk Wilden's avatar
Dirk Wilden committed
794

795
      int id = _importer.groupId(groupName);
796
797
798
799
800
      if(id == -1) {
          std::cerr << "Error: Group has not been added before!" << std::endl;
          return;
      }
      _importer.setCurrentGroup(id);
801
      inGroup = true;
Dirk Wilden's avatar
Dirk Wilden committed
802
803
804
805
806

      faceCount = 0;
    }

    // face
807
    else if (mode == NONE && keyWrd == QLatin1String("f"))
Dirk Wilden's avatar
Dirk Wilden committed
808
    {
809
810
811
812
813
814
815
      if (firstFace) {
        // store faces in the default Group if we aren't in a group already
        if (!inGroup)
          _importer.setCurrentGroup(0);

        firstFace = false;
      }
Dirk Wilden's avatar
Dirk Wilden committed
816
817
818
819
820
821

      int component(0), nV(0);
      int value;

      vhandles.clear();
      face_texcoords.clear();
822

Dirk Wilden's avatar
Dirk Wilden committed
823
      // read full line after detecting a face
824
825
      QString faceLine;
      faceLine = stream.readLine();
826
      lineData.setString(&faceLine);
Dirk Wilden's avatar
Dirk Wilden committed
827
828

      // work on the line until nothing left to read
829
      while ( !lineData.atEnd() )
Dirk Wilden's avatar
Dirk Wilden committed
830
831
      {
        // read one block from the line ( vertex/texCoord/normal )
832
        QString vertex;
Dirk Wilden's avatar
Dirk Wilden committed
833
834
835
836
837
        lineData >> vertex;

        do{

          //get the component (vertex/texCoord/normal)
838
          int found=vertex.indexOf(QLatin1String("/"));
Dirk Wilden's avatar
Dirk Wilden committed
839
840

          // parts are seperated by '/' So if no '/' found its the last component
Martin Schultz's avatar
Martin Schultz committed
841
          if( found != -1 ){
Dirk Wilden's avatar
Dirk Wilden committed
842
843

            // read the index value
844
            QString vertexEntry = vertex.left(found);
845
            tmp.setString( &vertexEntry );
Dirk Wilden's avatar
Dirk Wilden committed
846
847

            // If we get an empty string this property is undefined in the file
848
            if ( vertexEntry.isEmpty() ) {
Dirk Wilden's avatar
Dirk Wilden committed
849
              // Switch to next field
850
              vertex = vertex.right(vertex.length()-(found+1));
Dirk Wilden's avatar
Dirk Wilden committed
851
852
853
854
855
856
857
858
859
860
861
862

              // Now we are at the next component
              ++component;

              // Skip further processing of this component
              continue;
            }

            // Read current value
            tmp >> value;

            // remove the read part from the string
863
            vertex = vertex.right(vertex.length()-(found+1));
Dirk Wilden's avatar
Dirk Wilden committed
864
865
866
867

          } else {

            // last component of the vertex, read it.
868
            tmp.setString( &vertex );
Dirk Wilden's avatar
Dirk Wilden committed
869
870
871
            tmp >> value;

            // Clear vertex after finished reading the line
Martin Schultz's avatar
Martin Schultz committed
872
            vertex=QLatin1String("");
Dirk Wilden's avatar
Dirk Wilden committed
873
874

            // Nothing to read here ( garbage at end of line )
875
            if ( tmp.status() != QTextStream::Ok ) {
Dirk Wilden's avatar
Dirk Wilden committed
876
877
878
879
880
881
882
883
884
885
886
887
              continue;
            }
          }

          // store the component ( each component is referenced by the index here! )
          switch (component)
          {
            case 0: // vertex
              if ( value < 0 ) {
                // Calculation of index :
                // -1 is the last vertex in the list
                // As obj counts from 1 and not zero add +1
888
                value = currentVertexCount + value + 1;
Dirk Wilden's avatar
Dirk Wilden committed
889
890
891
892
893
894
895
896
897
898
899
              }

              // Obj counts from 1 and not zero .. array counts from zero therefore -1
              vhandles.push_back( value-1 );
              break;

            case 1: // texture coord
              if ( value < 0 ) {
                // Calculation of index :
                // -1 is the last vertex in the list
                // As obj counts from 1 and not zero add +1
900
                value = currentTextureCoordCount + value + 1;
Dirk Wilden's avatar
Dirk Wilden committed
901
              }
902
903
904
905
906
907
908
909
910
911
912
913
914

              if (vhandles.empty())
              {
                emit log (LOGWARN, tr("Texture coordinates defined, but no vertex coordinates found!"));
                break;
              }
              if ((unsigned int)(value-1) >= _importer.n_texCoords())
              {
                emit log (LOGWARN, tr("Too many texcoords defined, skipping the rest"));
                break;
              }

              if ( _importer.n_texCoords() > 0 ) {
Dirk Wilden's avatar
Dirk Wilden committed
915
916
917
918
919
920
921
922
923
924
925
926
927
928
                // Obj counts from 1 and not zero .. array counts from zero therefore -1
                _importer.setVertexTexCoord( vhandles.back(), value-1 );
                face_texcoords.push_back( value-1 );
              } else {
                emit log( LOGERR, tr("Error setting Texture coordinates") );
              }

              break;

            case 2: // normal
              if ( value < 0 ) {
                // Calculation of index :
                // -1 is the last vertex in the list
                // As obj counts from 1 and not zero add +1
929
                value = currentNormalCount + value + 1;
Dirk Wilden's avatar
Dirk Wilden committed
930
              }
931
932
933
934
935
936
937
938
939
940
941
942
943

              if (vhandles.empty())
              {
                emit log (LOGWARN, tr("Texture coordinates defined, but no vertex coordinates found!"));
                break;
              }

              if ((unsigned int)(value-1) >= _importer.n_normals())
              {
                emit log (LOGWARN, tr("Too many normals defined, skipping the rest"));
                break;
              }

Dirk Wilden's avatar
Dirk Wilden committed
944
945
946
947
948
949
950
951
952
              // Obj counts from 1 and not zero .. array counts from zero therefore -1
              _importer.setNormal(vhandles.back(), value-1);
              break;
          }

          // Prepare for reading next component
          ++component;

          // Read until line does not contain any other info
953
        } while ( !vertex.isEmpty() );
Dirk Wilden's avatar
Dirk Wilden committed
954
955
956
957
958

        component = 0;
        nV++;
      }

959
960
      // remove vertices which can lead to degenerated faces
      remove_duplicated_vertices(vhandles);
Dirk Wilden's avatar
Dirk Wilden committed
961

962
963
      // from spec: A minimum of three vertices are required.
      if( vhandles.size() > 2 ){
964

965
        if ( !face_texcoords.empty() )
Dirk Wilden's avatar
Dirk Wilden committed
966
967
968
969
          //if we have texCoords add face+texCoords
          _importer.addFace(vhandles, face_texcoords );
        else
          //otherwise just add the face
970
          _importer.addFace(vhandles);
Dirk Wilden's avatar
Dirk Wilden committed
971
972
973
974
975
976
977

        faceCount++;
      }


      //add material to the last added face(s)
      //if polygons get triangulated this can be more than one face
978
      _importer.addMaterial( matname.toStdString() );
Dirk Wilden's avatar
Dirk Wilden committed
979
    }
980

Dirk Wilden's avatar
Dirk Wilden committed
981
982
#ifdef ENABLE_BSPLINECURVE_SUPPORT
    // param
983
    else if ( (mode == CURVE && keyWrd == QLatin1String("parm")) || (mode == CURVE && keyWrd == QLatin1String("parm_add")) ){
Dirk Wilden's avatar
Dirk Wilden committed
984
985

      //get curve knots
986
987
      QString paramLine;
      QString tmp;
988

989
      paramLine = stream.readLine();
990

Dirk Wilden's avatar
Dirk Wilden committed
991
      // value may contain a / as line separator
992
993
994
      if (  paramLine.endsWith(QLatin1String("\\"))){
        paramLine = paramLine.left( paramLine.length()-1);
        nextKeyWrd = QLatin1String("parm_add");
Dirk Wilden's avatar
Dirk Wilden committed
995
      }
996

997
      lineData.setString( &paramLine );
Dirk Wilden's avatar
Dirk Wilden committed
998

999
      if ( keyWrd != QLatin1String("parm_add"))
Dirk Wilden's avatar
Dirk Wilden committed
1000
1001
1002
        lineData >> tmp; //push the first u out

      // work on the line until nothing left to read
1003
      while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
1004
      {
1005

Jan Möbius's avatar
Jan Möbius committed
1006
1007
        double knot;

1008
        knot = getDouble(lineData);
Dirk Wilden's avatar
Dirk Wilden committed
1009

1010
        if ( lineData.status() == QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
1011
1012
1013
1014
1015
          knotsU.push_back( knot );
      }
    }

    // curve
1016
    else if ( (mode == NONE && keyWrd == QLatin1String("curv")) || (mode == CURVE && keyWrd == QLatin1String("curv_add")) ){
1017
1018
1019
1020
      if (!firstFace)
        firstFace = true;

      inGroup = false;
Dirk Wilden's avatar
Dirk Wilden committed
1021
1022

      mode = CURVE;
1023

Martin Schultz's avatar
Martin Schultz committed
1024
1025
      if ( keyWrd == QLatin1String("curv") )
      {
1026
          int id = _importer.getCurveGroupId(curveCount);
1027
1028
1029
1030
1031
1032
1033
          if(id == -1) {
              std::cerr << "Error: Group has not been added before!" << std::endl;
              return;
          }
          _importer.setCurrentGroup(id);
          curveCount++;
      }
1034

Dirk Wilden's avatar
Dirk Wilden committed
1035
      //get curve control points
1036
      QString curveLine;
1037

1038
      curveLine = stream.readLine();
1039

Dirk Wilden's avatar
Dirk Wilden committed
1040
      // value may contain a / as line separator
1041
1042
1043
      if ( curveLine.endsWith(QLatin1String("\\"))){
        curveLine = curveLine.left(curveLine.length()-1);
        nextKeyWrd = QLatin1String("curv_add");
Dirk Wilden's avatar
Dirk Wilden committed
1044
      }
1045

1046
      lineData.setString( &curveLine );
1047

1048
      // Read knots at the beginning before the indices
1049
      if ( keyWrd == QLatin1String("curv") ) {
1050
        double trash;
1051
1052
        trash = getDouble(lineData);
        trash = getDouble(lineData);
1053
      }
1054

Jan Möbius's avatar
Jan Möbius committed
1055
1056


Dirk Wilden's avatar
Dirk Wilden committed
1057
      // work on the line until nothing left to read
1058
      while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
Dirk Wilden's avatar
Dirk Wilden committed
1059
      {
Jan Möbius's avatar
Jan Möbius committed
1060
1061
        int index = 0;

Dirk Wilden's avatar
Dirk Wilden committed
1062
        lineData >> index;
1063

1064
1065
1066
1067
1068
1069
        if ( index < 0 ) {
          // Calculation of index :
          // -1 is the last vertex in the list
          // As obj counts from 1 and not zero add +1
          index = currentVertexCount + index + 1;
        }
Dirk Wilden's avatar
Dirk Wilden committed
1070

1071
        if ( lineData.status()==QTextStream::Ok  )
Dirk Wilden's avatar
Dirk Wilden committed
1072
1073
1074
          cpIndices.push_back( index -1 );
      }
    }
1075

Dirk Wilden's avatar
Dirk Wilden committed
1076
    // end
1077
    else if (mode == CURVE && keyWrd == QLatin1String("end")){
1078

Dirk Wilden's avatar
Dirk Wilden committed
1079
1080
1081
1082
1083
1084
1085
      if ( _importer.isCurve( _importer.currentObject() ) ){
        // set up the spline curve
        _importer.currentCurve()->set_degree( _importer.degreeU() );
        _importer.currentCurve()->autocompute_knotvector(false);

        // add the control points
        std::vector< ACG::Vec3d > controlPolygon;
1086

Jan Möbius's avatar
Jan Möbius committed
1087
        for (unsigned int i = 0; i < cpIndices.size(); ++i)
Dirk Wilden's avatar
Dirk Wilden committed
1088
1089