Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
OFFImporter.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 "OFFImporter.hh"
51
52 //-----------------------------------------------------------------------------
53
55 OFFImporter::~OFFImporter(){
56
57 }
58
59 //-----------------------------------------------------------------------------
60
62 OFFImporter::OFFImporter() :
63 polyMesh_(0),
64 triMesh_(0),
65 object_(0),
66 objectOptions_(0),
67 maxFaceValence_(0) {}
68
69 //-----------------------------------------------------------------------------
70
72 void OFFImporter::addObject( BaseObject* _object ){
73
74 PolyMeshObject* polyMeshObj = dynamic_cast< PolyMeshObject* > (_object);
75 TriMeshObject* triMeshObj = dynamic_cast< TriMeshObject* > (_object);
76
77 if ( polyMeshObj ){
78
79 polyMesh_ = polyMeshObj->mesh();
80 object_ = _object;
81 objectOptions_ |= POLYMESH;
82 objectOptions_ &= ~TRIMESH;
83
84 } else if ( triMeshObj ){
85
86 triMesh_ = triMeshObj->mesh();
87 object_ = _object;
88 objectOptions_ |= TRIMESH;
89 objectOptions_ &= ~POLYMESH;
90
91 } else {
92 std::cerr << "Error: Cannot add object. Type is unknown!" << std::endl;
93 }
94 }
95
96 //-----------------------------------------------------------------------------
97
99 Vec3f OFFImporter::vertex(uint _index){
100
101 if ( vertices_.size() > _index )
102 return vertices_[ _index ];
103 else
104 return Vec3f();
105 }
106
107 //-----------------------------------------------------------------------------
108
110 int OFFImporter::addTexCoord(const Vec2f& _coord){
111 texCoords_.push_back( _coord );
112
113 return texCoords_.size()-1;
114 }
115
116 //-----------------------------------------------------------------------------
117
119 int OFFImporter::addNormal(const Vec3f& _normal){
120 normals_.push_back( _normal );
121
122 return normals_.size()-1;
123 }
124
125 //-----------------------------------------------------------------------------
126
128 int OFFImporter::addColor(const Vec4f& _color) {
129 colors_.push_back( _color );
130
131 return colors_.size()-1;
132 }
133
134 //-----------------------------------------------------------------------------
135
137 PolyMesh* OFFImporter::polyMesh(){
138 if (polyMesh_ == 0)
139 return 0;
140 else
141 return polyMesh_;
142 }
143
144 //-----------------------------------------------------------------------------
145
147 TriMesh* OFFImporter::triMesh(){
148 if (triMesh_ == 0)
149 return 0;
150 else
151 return triMesh_;
152 }
153
154 //-----------------------------------------------------------------------------
155
157 void OFFImporter::setVertexTexCoord(VertexHandle _vh, int _texCoordID){
158
159 if ( isTriangleMesh() ){
160
161 //handle triangle meshes
162 if ( !triMesh() ) return;
163
164 if ( _texCoordID < (int) texCoords_.size() ){
165
166 //perhaps request texCoords for the mesh
167 if ( !triMesh()->has_vertex_texcoords2D() )
168 triMesh()->request_vertex_texcoords2D();
169
170 if ( vertexMapTri_.find( _vh ) != vertexMapTri_.end() )
171 triMesh()->set_texcoord2D( vertexMapTri_[_vh], texCoords_[ _texCoordID ] );
172 objectOptions_ |= VERTEXTEXCOORDS;
173
174 }else{
175 std::cerr << "Error: TexCoord ID too large" << std::endl;
176 }
177
178 } else if ( isPolyMesh() ){
179
180 //handle poly meshes
181 if ( !polyMesh() ) return;
182
183 if ( _texCoordID < (int) texCoords_.size() ){
184
185 //perhaps request texCoords for the mesh
186 if ( !polyMesh()->has_vertex_texcoords2D() )
187 polyMesh()->request_vertex_texcoords2D();
188
189 if ( vertexMapPoly_.find( _vh ) != vertexMapPoly_.end() )
190 polyMesh()->set_texcoord2D( vertexMapPoly_[_vh], texCoords_[ _texCoordID ] );
191 objectOptions_ |= VERTEXTEXCOORDS;
192
193 }else{
194 std::cerr << "Error: TexCoord ID too large" << std::endl;
195 }
196 }
197 }
198
199 //-----------------------------------------------------------------------------
200
202 void OFFImporter::setNormal(VertexHandle _vh, int _normalID){
203
204 if ( isTriangleMesh() ){
205
206 //handle triangle meshes
207 if ( !triMesh() ) return;
208
209 if ( _normalID < (int) normals_.size() ){
210
211 if ( vertexMapTri_.find( _vh ) != vertexMapTri_.end() ){
212 triMesh()->set_normal( vertexMapTri_[_vh], (TriMesh::Point) normals_[ _normalID ] );
213 objectOptions_ |= VERTEXNORMAL;
214 }
215
216 }else{
217 std::cerr << "Error: normal ID too large" << std::endl;
218 }
219
220 } else if ( isPolyMesh() ){
221
222 //handle poly meshes
223 if ( !polyMesh() ) return;
224
225 if ( _normalID < (int) normals_.size() ){
226
227 if ( vertexMapPoly_.find( _vh ) != vertexMapPoly_.end() ){
228 polyMesh()->set_normal( vertexMapPoly_[_vh], (PolyMesh::Point) normals_[ _normalID ] );
229 objectOptions_ |= VERTEXNORMAL;
230 }
231
232 }else{
233 std::cerr << "Error: normal ID too large" << std::endl;
234 }
235
236 }
237 }
238
239 //-----------------------------------------------------------------------------
240
242 VertexHandle OFFImporter::addVertex(const Vec3f& _point){
243
244 vertices_.push_back( _point );
245
246 int id = vertices_.size()-1;
247
248 if ( isTriangleMesh() ){
249
250 //handle triangle meshes
251 if ( !triMesh() ) return false;
252 vertexMapTri_[ id ] = triMesh()->add_vertex( (TriMesh::Point) vertices_[id] );
253
254 } else if ( isPolyMesh() ){
255
256 //handle poly meshes
257 if ( !polyMesh() ) return false;
258 vertexMapPoly_[ id ] = polyMesh()->add_vertex( (PolyMesh::Point) vertices_[id] );
259 }
260
261 return id;
262 }
263
264 //-----------------------------------------------------------------------------
265
267 int OFFImporter::addFace(const VHandles& _indices) {
268
269 int faceIndex = -1;
270
271 if ( isTriangleMesh() ){
272
273 //handle triangle meshes
274 if ( !triMesh() ) return -1;
275
276 std::vector< TriMesh::VertexHandle > vertices;
277
278 for (uint i=0; i < _indices.size(); i++){
279
280 if ( vertexMapTri_.find( _indices[i] ) != vertexMapTri_.end() ){
281
282 vertices.push_back( vertexMapTri_[ _indices[i] ] );
283
284 } else {
285 std::cerr << "Error: Cannot add face. Undefined index (" << _indices[i] << ")" << std::endl;
286 return -1;
287 }
288 }
289
290 TriMesh::FaceHandle fh = triMesh()->add_face( vertices );
291
292 if(fh.is_valid()) {
293 faceMapTri_.push_back( fh );
294 faceIndex = faceMapTri_.size()-1;
295 } else {
296 // Store non-manifold face
297 invalidFaces_.push_back( vertices );
298 }
299
300 } else if ( isPolyMesh() ){
301
302 //handle poly meshes
303 if ( !polyMesh() ) return -1;
304
305 std::vector< PolyMesh::VertexHandle > vertices;
306
307 for (uint i=0; i < _indices.size(); i++){
308
309 if ( vertexMapPoly_.find( _indices[i] ) != vertexMapPoly_.end() ){
310
311 vertices.push_back( vertexMapPoly_[ _indices[i] ] );
312
313 }else{
314 std::cerr << "Error: Cannot add face. Undefined index (" << _indices[i] << ")" << std::endl;
315 return -1;
316 }
317 }
318
319 PolyMesh::FaceHandle fh = polyMesh()->add_face( vertices );
320
321 if(fh.is_valid()) {
322 faceMapPoly_.push_back(fh);
323 faceIndex = faceMapPoly_.size()-1;
324 } else {
325 // Store non-manifold face vertices
326 invalidFaces_.push_back( vertices );
327 }
328 }
329
330 return faceIndex;
331 }
332
333 //-----------------------------------------------------------------------------
334
335 void OFFImporter::finish() {
336
337 if(invalidFaces_.empty()) return;
338
339 if ( isTriangleMesh() ) {
340
341 for(std::vector<OMVHandles>::iterator it = invalidFaces_.begin();
342 it != invalidFaces_.end(); ++it) {
343
344 OMVHandles& vhandles = *it;
345
346 // double vertices
347 for (unsigned int j = 0; j < vhandles.size(); ++j)
348 {
349 TriMesh::Point p = triMesh()->point(vhandles[j]);
350 vhandles[j] = triMesh()->add_vertex(p);
351 // DO STORE p, reference may not work since vertex array
352 // may be relocated after adding a new vertex !
353
354 // Mark vertices of failed face as non-manifold
355 if (triMesh()->has_vertex_status()) {
356 triMesh()->status(vhandles[j]).set_fixed_nonmanifold(true);
357 }
358 }
359
360 // add face
361 OpenMesh::FaceHandle fh = triMesh()->add_face(vhandles);
362
363 // Mark failed face as non-manifold
364 if (triMesh()->has_face_status())
365 triMesh()->status(fh).set_fixed_nonmanifold(true);
366
367 // Mark edges of failed face as non-two-manifold
368 if (triMesh()->has_edge_status()) {
369 TriMesh::FaceEdgeIter fe_it = triMesh()->fe_iter(fh);
370 for(; fe_it.is_valid(); ++fe_it) {
371 triMesh()->status(*fe_it).set_fixed_nonmanifold(true);
372 }
373 }
374
375 faceMapTri_.push_back(fh);
376 }
377
378 } else if ( isPolyMesh() ) {
379
380 for(std::vector<OMVHandles>::iterator it = invalidFaces_.begin();
381 it != invalidFaces_.end(); ++it) {
382
383 OMVHandles& vhandles = *it;
384
385 // double vertices
386 for (unsigned int j = 0; j < vhandles.size(); ++j)
387 {
388 TriMesh::Point p = polyMesh()->point(vhandles[j]);
389 vhandles[j] = polyMesh()->add_vertex(p);
390 // DO STORE p, reference may not work since vertex array
391 // may be relocated after adding a new vertex !
392
393 // Mark vertices of failed face as non-manifold
394 if (polyMesh()->has_vertex_status()) {
395 polyMesh()->status(vhandles[j]).set_fixed_nonmanifold(true);
396 }
397 }
398
399 // add face
400 OpenMesh::FaceHandle fh = polyMesh()->add_face(vhandles);
401
402 // Mark failed face as non-manifold
403 if (polyMesh()->has_face_status())
404 polyMesh()->status(fh).set_fixed_nonmanifold(true);
405
406 // Mark edges of failed face as non-two-manifold
407 if (polyMesh()->has_edge_status()) {
408 TriMesh::FaceEdgeIter fe_it = polyMesh()->fe_iter(fh);
409 for(; fe_it.is_valid(); ++fe_it) {
410 polyMesh()->status(*fe_it).set_fixed_nonmanifold(true);
411 }
412 }
413
414 faceMapPoly_.push_back(fh);
415 }
416 }
417
418 // Clear all invalid faces
419 invalidFaces_.clear();
420 }
421
422 //-----------------------------------------------------------------------------
423
424 bool OFFImporter::isTriangleMesh(){
425 return objectOptions_ & TRIMESH;
426 }
427
428 //-----------------------------------------------------------------------------
429
430 bool OFFImporter::isPolyMesh(){
431 return objectOptions_ & POLYMESH;
432 }
433
434 //-----------------------------------------------------------------------------
435
436 bool OFFImporter::isBinary(){
437 return objectOptions_ & BINARY;
438 }
439
440 //-----------------------------------------------------------------------------
441
442 bool OFFImporter::hasVertexNormals(){
443
444 return objectOptions_ & VERTEXNORMAL;
445 }
446
447 //-----------------------------------------------------------------------------
448
449 bool OFFImporter::hasTextureCoords(){
450 return objectOptions_ & VERTEXTEXCOORDS;
451 }
452
453 //-----------------------------------------------------------------------------
454
455 bool OFFImporter::hasVertexColors() {
456 return objectOptions_ & VERTEXCOLOR;
457 }
458
459 //-----------------------------------------------------------------------------
460
461 bool OFFImporter::hasFaceColors() {
462 return objectOptions_ & FACECOLOR;
463 }
464
465 //-----------------------------------------------------------------------------
466
467 bool OFFImporter::hasOption(ObjectOptionsE _option) {
468 return objectOptions_ & _option;
469 }
470
471 //-----------------------------------------------------------------------------
472
473 uint OFFImporter::n_vertices(){
474 return vertices_.size();
475 }
476
477 //-----------------------------------------------------------------------------
478
479 uint OFFImporter::n_normals(){
480 return normals_.size();
481 }
482
483 //-----------------------------------------------------------------------------
484
485 uint OFFImporter::n_texCoords(){
486 return texCoords_.size();
487 }
488
489 //-----------------------------------------------------------------------------
490
491 void OFFImporter::reserve(unsigned int _nv, unsigned int _ne, unsigned int _nf) {
492
493 vertices_.reserve(_nv);
494 normals_.reserve(_nv);
495 texCoords_.reserve(_nv);
496 colors_.reserve(_nv);
497
498 if(isPolyMesh() && polyMesh_ != 0) {
499 polyMesh_->reserve(_nv, _ne, _nf);
500 }
501
502 if(isTriangleMesh() && triMesh_ != 0) {
503 triMesh_->reserve(_nv, _ne, _nf);
504 }
505 }
506
507 //-----------------------------------------------------------------------------
508
509 BaseObject* OFFImporter::getObject(){
510
511 return object_;
512 }
513
514 //-----------------------------------------------------------------------------
515
516 QString OFFImporter::path(){
517 return path_;
518 }
519
520 //-----------------------------------------------------------------------------
521
522 void OFFImporter::setPath(QString _path){
523 path_ = _path;
524 }
525
526 //-----------------------------------------------------------------------------
527
528 void OFFImporter::setObjectOptions(ObjectOptions _options){
529 objectOptions_ = _options;
530 }
531
532 //-----------------------------------------------------------------------------
533
534 void OFFImporter::addOption(ObjectOptionsE _option) {
535 objectOptions_ |= _option;
536 }
537
538 //-----------------------------------------------------------------------------
539
540 void OFFImporter::removeOption(ObjectOptionsE _option) {
541 if(objectOptions_ & _option) objectOptions_ -= _option;
542 }
543
544 //-----------------------------------------------------------------------------
545
546 OFFImporter::ObjectOptions& OFFImporter::objectOptions(){
547 return objectOptions_;
548 }
549
550 //-----------------------------------------------------------------------------
551
552 void OFFImporter::setObjectName(QString _name){
553
554 if ( object_ != 0 )
555 object_->setName( _name );
556 }
557
558 //------------------------------------------------------------------------------
559
561 void OFFImporter::setVertexColor(VertexHandle _vh, int _colorIndex) {
562
563 if ( isTriangleMesh() ){
564
565 //handle triangle meshes
566 if ( !triMesh() ) return;
567
568 if ( _colorIndex < (int) colors_.size() ){
569
570 if ( vertexMapTri_.find( _vh ) != vertexMapTri_.end() ){
571 triMesh()->set_color( vertexMapTri_[_vh], colors_[_colorIndex] );
572 objectOptions_ |= VERTEXCOLOR;
573 }
574
575 }else{
576 std::cerr << "Error: Color ID too large" << std::endl;
577 }
578
579 } else if ( isPolyMesh() ){
580
581 //handle poly meshes
582 if ( !polyMesh() ) return;
583
584 if ( _colorIndex < (int) colors_.size() ){
585
586 if ( vertexMapPoly_.find( _vh ) != vertexMapPoly_.end() ){
587 polyMesh()->set_color( vertexMapPoly_[_vh], colors_[_colorIndex] );
588 objectOptions_ |= VERTEXCOLOR;
589 }
590
591 }else{
592 std::cerr << "Error: Color ID too large" << std::endl;
593 }
594
595 }
596 }
597
598 //------------------------------------------------------------------------------
599
601 void OFFImporter::setFaceColor(FaceHandle _fh, int _colorIndex) {
602
603 if ( isTriangleMesh() ){
604
605 //handle triangle meshes
606 if ( !triMesh() ) return;
607
608 if ( _colorIndex < (int) colors_.size() ){
609
610 if ( _fh < (int)faceMapTri_.size() ) {
611 triMesh()->set_color( faceMapTri_[_fh],colors_[_colorIndex] );
612 objectOptions_ |= FACECOLOR;
613 }
614
615 }else{
616 std::cerr << "Error: Color ID too large" << std::endl;
617 }
618
619 } else if ( isPolyMesh() ){
620
621 //handle poly meshes
622 if ( !polyMesh() ) return;
623
624 if ( _colorIndex < (int) colors_.size() ){
625
626 if ( _fh < (int)faceMapPoly_.size() ) {
627 polyMesh()->set_color( faceMapPoly_[_fh], colors_[_colorIndex] );
628 objectOptions_ |= FACECOLOR;
629 }
630
631 }else{
632 std::cerr << "Error: Color ID too large" << std::endl;
633 }
634
635 }
636 }
OFFImporter::addObject
void addObject(BaseObject *_object)
add initial object
Definition: OFFImporter.cc:72
OFFImporter::hasOption
bool hasOption(ObjectOptionsE _option)
test if object has a certain option
Definition: OFFImporter.cc:467
OFFImporter::setNormal
void setNormal(VertexHandle _vh, int _normalID)
set vertex normal
Definition: OFFImporter.cc:202
MeshObject::mesh
MeshT * mesh()
return a pointer to the mesh
Definition: MeshObjectT.cc:351
PolyMeshObject
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:70
OFFImporter::setVertexColor
void setVertexColor(VertexHandle _vh, int _colorIndex)
set vertex color
Definition: OFFImporter.cc:561
OFFImporter::n_vertices
uint n_vertices()
Global Properties.
Definition: OFFImporter.cc:473
TriMeshObject
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:73
OFFImporter::addTexCoord
int addTexCoord(const Vec2f &_coord)
add texture coordinates
Definition: OFFImporter.cc:110
OFFImporter::addVertex
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
Definition: OFFImporter.cc:242
OFFImporter::setFaceColor
void setFaceColor(FaceHandle _fh, int _colorIndex)
set face color
Definition: OFFImporter.cc:601
OFFImporter::addColor
int addColor(const Vec4f &_color)
add a color
Definition: OFFImporter.cc:128
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
OFFImporter::~OFFImporter
~OFFImporter()
base class needs virtual destructor
Definition: OFFImporter.cc:55
OFFImporter::finish
void finish()
Definition: OFFImporter.cc:335
OFFImporter::addFace
int addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
Definition: OFFImporter.cc:267
OFFImporter::removeOption
void removeOption(ObjectOptionsE _option)
remove an option
Definition: OFFImporter.cc:540
OFFImporter::triMesh
TriMesh * triMesh()
get a pointer to the active triMesh
Definition: OFFImporter.cc:147
BaseObject
Definition: BaseObject.hh:94
OFFImporter::setObjectOptions
void setObjectOptions(ObjectOptions _options)
Definition: OFFImporter.cc:528
OFFImporter::hasVertexNormals
bool hasVertexNormals()
Query Object Options.
Definition: OFFImporter.cc:442
OFFImporter::addOption
void addOption(ObjectOptionsE _option)
add an option
Definition: OFFImporter.cc:534
OpenMesh::VectorT
Definition: Vector11T.hh:83
OFFImporter::vertex
Vec3f vertex(uint _index)
get vertex with given index
Definition: OFFImporter.cc:99
OFFImporter::addNormal
int addNormal(const Vec3f &_normal)
add a normal
Definition: OFFImporter.cc:119
OFFImporter::objectOptions
ObjectOptions & objectOptions()
get Object Options
Definition: OFFImporter.cc:546
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:146
OFFImporter::OFFImporter
OFFImporter()
constructor
Definition: OFFImporter.cc:62
OFFImporter::setVertexTexCoord
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
Definition: OFFImporter.cc:157
OpenVolumeMesh::Geometry::VectorT
Definition: Vector11T.hh:78
BaseObject::setName
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
Definition: BaseObject.cc:734
OFFImporter::path
QString path()
Path of the OFF file.
Definition: OFFImporter.cc:516
OFFImporter::getObject
BaseObject * getObject()
get BaseObject data of object
Definition: OFFImporter.cc:509
OFFImporter::polyMesh
PolyMesh * polyMesh()
get a pointer to the active polyMesh
Definition: OFFImporter.cc:137
OFFImporter::setObjectName
void setObjectName(QString _name)
change the name of an object
Definition: OFFImporter.cc:552