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
OBJImporter.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 "OBJImporter.hh"
51
52 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54
56 OBJImporter::~OBJImporter(){
57
58 }
59
60 //-----------------------------------------------------------------------------
61
63 VertexHandle OBJImporter::addVertex(const Vec3f& _point){
64 vertices_.push_back( _point );
65
66 return vertices_.size()-1;
67 }
68
70 Vec3f OBJImporter::vertex(unsigned int _index){
71
72 if ( vertices_.size() > _index )
73 return vertices_[ _index ];
74 else
75 return Vec3f();
76 }
77
78 //-----------------------------------------------------------------------------
79
81 int OBJImporter::addTexCoord(const Vec2f& _coord){
82 texCoords_.push_back( _coord );
83
84 return texCoords_.size()-1;
85 }
86
87 //-----------------------------------------------------------------------------
88
90 int OBJImporter::addNormal(const Vec3f& _normal){
91 normals_.push_back( _normal );
92
93 return normals_.size()-1;
94 }
95
96 //-----------------------------------------------------------------------------
97
99 void OBJImporter::setDegreeU(int _degree){
100 degreeU_ = _degree;
101 }
102
103 //-----------------------------------------------------------------------------
104
106 void OBJImporter::setDegreeV(int _degree){
107 degreeV_ = _degree;
108 }
109
110
111 //-----------------------------------------------------------------------------
112
114 int OBJImporter::degreeU(){
115 return degreeU_;
116 }
117
118 //-----------------------------------------------------------------------------
119
121 int OBJImporter::degreeV(){
122 return degreeV_;
123 }
124
125 //-----------------------------------------------------------------------------
126
128 void OBJImporter::setObject(BaseObject* _object, int _groupId) {
129
130 if((unsigned int)_groupId >= triMeshes_.size()) {
131 std::cerr << "Error: Group does not exist!" << std::endl;
132 return;
133 }
134
135 if(PluginFunctions::polyMeshObject(_object->id()) != NULL) {
136
137 polyMeshes_[_groupId] = PluginFunctions::polyMeshObject(_object->id());
138 addUsedVertices(_groupId);
139
140 } else if(PluginFunctions::triMeshObject(_object->id()) != NULL) {
141
142 triMeshes_[_groupId] = PluginFunctions::triMeshObject(_object->id());
143 addUsedVertices(_groupId);
144 }
145 #ifdef ENABLE_BSPLINECURVE_SUPPORT
146 else if(PluginFunctions::bsplineCurveObject(PluginFunctions::baseObjectData(_object)) != NULL) {
147
148 bSplineCurves_[_groupId] = PluginFunctions::bsplineCurveObject(PluginFunctions::baseObjectData(_object));
149 }
150 #endif
151 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
152 else if(PluginFunctions::bsplineSurfaceObject(PluginFunctions::baseObjectData(_object)) != NULL) {
153
154 bSplineSurfaces_[_groupId] = PluginFunctions::bsplineSurfaceObject(PluginFunctions::baseObjectData(_object));
155 }
156 #endif
157 else {
158 std::cerr << "Error: Cannot add object. Type is unknown!" << std::endl;
159 }
160 }
161
162 //-----------------------------------------------------------------------------
163
165 int OBJImporter::currentObject(){
166
167 return currentGroup_;
168 }
169
170 //-----------------------------------------------------------------------------
171
173 PolyMesh* OBJImporter::currentPolyMesh(){
174
175 return polyMeshes_[currentGroup_]->mesh();
176 }
177
178 //-----------------------------------------------------------------------------
179
181 TriMesh* OBJImporter::currentTriMesh(){
182
183 return triMeshes_[currentGroup_]->mesh();
184 }
185
186 //-----------------------------------------------------------------------------
187
188 #ifdef ENABLE_BSPLINECURVE_SUPPORT
189
190 BSplineCurve* OBJImporter::currentCurve(){
191
192 return bSplineCurves_[currentGroup_]->splineCurve();
193 }
194
195 #endif
196
197 //-----------------------------------------------------------------------------
198
199 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
200
201 BSplineSurface* OBJImporter::currentSurface(){
202
203 return bSplineSurfaces_[currentGroup_]->splineSurface();
204 }
205
206 #endif
207
208 //-----------------------------------------------------------------------------
209
211 void OBJImporter::addUsedVertices(int _groupId) {
212
213 if (isTriangleMesh(_groupId)) {
214
215 //handle triangle meshes
216 TriMesh* curMesh = triMeshes_[_groupId]->mesh();
217 if (curMesh == NULL)
218 return;
219
220 // add all vertices to the mesh
221
222 if(usedVertices_.size() <= static_cast<size_t>(_groupId)) return;
223
224 for(std::map<int, VertexHandle>::const_iterator it = usedVertices_[_groupId].begin();
225 it != usedVertices_[_groupId].end(); ++it) {
226
227 if (it->first >= (int)vertices_.size()) {
228 std::cerr << "Error: Vertex ID too large" << std::endl;
229 continue;
230 }
231
232 if (vertexMapTri_[_groupId].find(it->first) == vertexMapTri_[_groupId].end()) {
233 vertexMapTri_[_groupId].insert(std::pair<int, TriMesh::VertexHandle>(it->first, curMesh->add_vertex((TriMesh::Point)vertices_[it->first])));
234 }
235 }
236
237 } else if (isPolyMesh(_groupId)) {
238
239 //handle triangle meshes
240 PolyMesh* curMesh = polyMeshes_[_groupId]->mesh();
241 if (curMesh == NULL)
242 return;
243
244 //add all vertices to the mesh
245
246 if(usedVertices_.size() <= static_cast<size_t>(_groupId)) return;
247
248 for(std::map<int, VertexHandle>::const_iterator it = usedVertices_[_groupId].begin();
249 it != usedVertices_[_groupId].end(); ++it) {
250
251 if (it->first >= (int)vertices_.size()) {
252 std::cerr << "Error: Vertex ID too large" << std::endl;
253 continue;
254 }
255
256 if (vertexMapPoly_[_groupId].find(it->first) == vertexMapPoly_[_groupId].end()) {
257 vertexMapPoly_[_groupId].insert(std::pair<int, PolyMesh::VertexHandle>(it->first, curMesh->add_vertex((PolyMesh::Point)vertices_[it->first])));
258 }
259 }
260 }
261 }
262
263 //-----------------------------------------------------------------------------
264
266 void OBJImporter::setVertexTexCoord(VertexHandle _vh, int _texCoordID){
267
268 if ( isTriangleMesh( currentObject() ) ){
269
270 //handle triangle meshes
271 if ( !currentTriMesh() ) return;
272
273 if ( _texCoordID < (int) texCoords_.size() ){
274
275 //perhaps request texCoords for the mesh
276 if ( !currentTriMesh()->has_vertex_texcoords2D() )
277 currentTriMesh()->request_vertex_texcoords2D();
278
279 //set the texCoords
280 if ( vertexMapTri_[currentGroup_].find( _vh ) != vertexMapTri_[currentGroup_].end() )
281 currentTriMesh()->set_texcoord2D( vertexMapTri_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
282
283 }else{
284 std::cerr << "Error: TexCoord ID too large" << std::endl;
285 }
286
287 } else if ( isPolyMesh( currentObject() ) ){
288
289 //handle poly meshes
290 if ( !currentPolyMesh() ) return;
291
292 if ( _texCoordID < (int) texCoords_.size() ){
293
294 //perhaps request texCoords for the mesh
295 if ( !currentPolyMesh()->has_vertex_texcoords2D() )
296 currentPolyMesh()->request_vertex_texcoords2D();
297
298 //set the texCoords
299 if ( vertexMapPoly_[currentGroup_].find( _vh ) != vertexMapPoly_[currentGroup_].end() )
300 currentPolyMesh()->set_texcoord2D( vertexMapPoly_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
301
302 }else{
303 std::cerr << "Error: TexCoord ID too large" << std::endl;
304 }
305 }
306 }
307
308 //-----------------------------------------------------------------------------
309
311 void OBJImporter::setNormal(int _index, int _normalID){
312
313 if ( isTriangleMesh( currentObject() ) ){
314
315 //handle triangle meshes
316 if ( !currentTriMesh() ) return;
317
318 if ( _normalID < (int) normals_.size() )
319 {
320 if ( vertexMapTri_[currentGroup_].find( _index ) != vertexMapTri_[currentGroup_].end() )
321 {
322 TriMesh::VertexHandle vh = vertexMapTri_[currentGroup_][_index];
323 TriMesh::Normal normal = static_cast<TriMesh::Normal>( normals_[ _normalID ] );
324 TriMesh* currentMesh = currentTriMesh();
325 currentMesh->set_normal( vh , normal );
326 objectOptions_[ currentGroup_ ] |= NORMALS;
327
328 storedTriHENormals_[vh] = normal;
329 }
330
331 }else{
332 std::cerr << "Error: normal ID too large" << std::endl;
333 }
334
335 } else if ( isPolyMesh( currentObject() ) ){
336
337 //handle poly meshes
338 if ( !currentPolyMesh() ) return;
339
340 if ( _normalID < (int) normals_.size() )
341 {
342 if ( vertexMapPoly_[currentGroup_].find( _index ) != vertexMapPoly_[currentGroup_].end() )
343 {
344 PolyMesh::VertexHandle vh = vertexMapPoly_[currentGroup_][_index];
345 PolyMesh::Point normal = static_cast<PolyMesh::Point>( normals_[ _normalID ] );
346 PolyMesh* currentMesh = currentPolyMesh();
347 currentMesh->set_normal( vh , normal );
348 objectOptions_[ currentGroup_ ] |= NORMALS;
349
350 storedPolyHENormals_[vh] = normal;
351 }
352
353 }else{
354 std::cerr << "Error: normal ID too large" << std::endl;
355 }
356
357 }
358 }
359
360 //-----------------------------------------------------------------------------
361
362 bool OBJImporter::addFace(const VHandles& _indices, OpenMesh::FaceHandle &_outFH, std::vector< TriMesh::VertexHandle > &_outTriVertices, std::vector< PolyMesh::VertexHandle > &_outPolyVertices)
363 {
364 if ( isTriangleMesh( currentObject() ) ){
365
366 //handle triangle meshes
367 if ( !currentTriMesh() ) return false;
368
369 addedFacesTri_[currentGroup_].clear();
370
371 for (unsigned int i=0; i < _indices.size(); i++){
372
373 if ( vertexMapTri_[currentGroup_].find( _indices[i] ) != vertexMapTri_[currentGroup_].end() ){
374
375 _outTriVertices.push_back( vertexMapTri_[currentGroup_][ _indices[i] ] );
376
377 }else{
378 std::cerr << "Error: cannot add face. undefined index (" << _indices[i] << ")" << std::endl;
379 return false;
380 }
381 }
382
383 size_t n_faces = currentTriMesh()->n_faces();
384
385 OpenMesh::FaceHandle fh = currentTriMesh()->add_face( _outTriVertices );
386
387 //remember all new faces
388 if(!fh.is_valid()) {
389 // Store non-manifold face
390 invalidFaces_[currentGroup_].push_back(_outTriVertices);
391
392 } else {
393 // Store recently added face
394 for( size_t i=0; i < currentTriMesh()->n_faces()-n_faces; ++i )
395 addedFacesTri_[currentGroup_].push_back( TriMesh::FaceHandle(n_faces+i) );
396
397 //write stored normals into the half edges
398 if (!currentTriMesh()->has_halfedge_normals())
399 currentTriMesh()->request_halfedge_normals();
400
401 //iterate over all incoming haldedges of the added face
402 for (TriMesh::FaceHalfedgeIter fh_iter = currentTriMesh()->fh_begin(fh);
403 fh_iter != currentTriMesh()->fh_end(fh); ++fh_iter)
404 {
405 //and write the normals to it
406 TriMesh::HalfedgeHandle heh = *fh_iter;
407 TriMesh::VertexHandle vh = currentTriMesh()->to_vertex_handle(heh);
408 std::map<TriMesh::VertexHandle,TriMesh::Normal>::iterator iter = storedTriHENormals_.find(vh);
409 if (iter != storedTriHENormals_.end())
410 currentTriMesh()->set_normal(heh,iter->second);
411 }
412 storedTriHENormals_.clear();
413 }
414
415 _outFH = fh;
416 return true;
417
418 } else if ( isPolyMesh( currentObject() ) ){
419
420 //handle poly meshes
421 if ( !currentPolyMesh() ) return false;
422
423 for (unsigned int i=0; i < _indices.size(); i++){
424
425 if ( vertexMapPoly_[currentGroup_].find( _indices[i] ) != vertexMapPoly_[currentGroup_].end() ){
426
427 _outPolyVertices.push_back( vertexMapPoly_[currentGroup_][ _indices[i] ] );
428
429 }else{
430 std::cerr << "Error: cannot add face. undefined index (" << _indices[i] << ")" << std::endl;
431 return false;
432 }
433 }
434
435 if(!vertexListIsManifold(_outPolyVertices)) {
436 std::cerr << "Face consists of multiple occurrences of the same vertex!" << std::endl;
437 return false;
438 }
439
440 OpenMesh::FaceHandle fh = currentPolyMesh()->add_face( _outPolyVertices );
441
442 if(!fh.is_valid()) {
443 // Store non-manifold face
444 invalidFaces_[currentGroup_].push_back(_outPolyVertices);
445 } else {
446 addedFacePoly_ = fh;
447
448 //write stored normals into the half edges
449 if (!currentPolyMesh()->has_halfedge_normals())
450 currentPolyMesh()->request_halfedge_normals();
451
452 //iterate over all incoming haldedges of the added face
453 for (PolyMesh::FaceHalfedgeIter fh_iter = currentPolyMesh()->fh_begin(fh);
454 fh_iter != currentPolyMesh()->fh_end(fh); ++fh_iter)
455 {
456 //and write the normals to it
457 PolyMesh::HalfedgeHandle heh = *fh_iter;
458 PolyMesh::VertexHandle vh = currentPolyMesh()->to_vertex_handle(heh);
459 std::map<PolyMesh::VertexHandle,PolyMesh::Normal>::iterator iter = storedTriHENormals_.find(vh);
460 if (iter != storedTriHENormals_.end())
461 currentPolyMesh()->set_normal(heh,iter->second);
462 }
463 storedPolyHENormals_.clear();
464
465 }
466
467 _outFH = fh;
468 return true;
469 }
470 return false;
471 }
472
474 void OBJImporter::addFace(const VHandles& _indices){
475 OpenMesh::FaceHandle fh;
476 std::vector< TriMesh::VertexHandle > triVertices;
477 std::vector< PolyMesh::VertexHandle > polyVertices;
478 addFace(_indices,fh,triVertices,polyVertices);
479
480 }
481
482 //-----------------------------------------------------------------------------
483
484 bool OBJImporter::vertexListIsManifold(const std::vector<PolyMesh::VertexHandle>& _vertices) const {
485
486 std::set<PolyMesh::VertexHandle> check;
487 for(std::vector<PolyMesh::VertexHandle>::const_iterator v_it = _vertices.begin();
488 v_it != _vertices.end(); ++v_it) {
489 check.insert(*v_it);
490 }
491
492 return (check.size() == _vertices.size());
493 }
494
495 //-----------------------------------------------------------------------------
496
498 void OBJImporter::addFace(const VHandles& _indices, const std::vector<int>& _face_texcoords){
499
500
501 OpenMesh::FaceHandle fh;
502 std::vector< TriMesh::VertexHandle > triVertices;
503 std::vector< PolyMesh::VertexHandle > polyVertices;
504 if(!addFace(_indices, fh, triVertices, polyVertices) || !fh.is_valid())
505 return;
506
507 if ( isTriangleMesh(currentObject()) )
508 {
509 //perhaps request texCoords for the mesh
510 if ( !currentTriMesh()->has_halfedge_texcoords2D() )
511 currentTriMesh()->request_halfedge_texcoords2D();
512
513 //now add texCoords
514
515 // get first halfedge handle
516 TriMesh::HalfedgeHandle cur_heh = currentTriMesh()->halfedge_handle( addedFacesTri_[currentGroup_][0] );
517 TriMesh::HalfedgeHandle end_heh = currentTriMesh()->prev_halfedge_handle(cur_heh);
518
519 // find start heh
520 while( currentTriMesh()->to_vertex_handle(cur_heh) != triVertices[0] && cur_heh != end_heh )
521 cur_heh = currentTriMesh()->next_halfedge_handle( cur_heh);
522
523 for(unsigned int i=0; i<_face_texcoords.size(); ++i)
524 {
525 if ( _face_texcoords[i] < (int)texCoords_.size() ){
526
527 PolyMesh::TexCoord2D tex = OpenMesh::vector_cast<TriMesh::TexCoord2D>( texCoords_[ _face_texcoords[i] ] );
528 currentTriMesh()->set_texcoord2D(cur_heh, tex);
529
530 cur_heh = currentTriMesh()->next_halfedge_handle(cur_heh);
531
532 } else
533 std::cerr << "Error: cannot set texture coordinates. undefined index." << std::endl;
534 }
535 }else if (isPolyMesh(currentObject()))
536 {
537 addedFacePoly_ = fh;
538
539 //perhaps request texCoords for the mesh
540 if ( !currentPolyMesh()->has_halfedge_texcoords2D() )
541 currentPolyMesh()->request_halfedge_texcoords2D();
542
543 //now add texCoords
544
545 if ( addedFacePoly_.is_valid() ) {
546 // get first halfedge handle
547 PolyMesh::HalfedgeHandle cur_heh = currentPolyMesh()->halfedge_handle( addedFacePoly_ );
548 PolyMesh::HalfedgeHandle end_heh = currentPolyMesh()->prev_halfedge_handle(cur_heh);
549
550 // find start heh
551 while( currentPolyMesh()->to_vertex_handle(cur_heh) != polyVertices[0] && cur_heh != end_heh )
552 cur_heh = currentPolyMesh()->next_halfedge_handle( cur_heh);
553
554 for(unsigned int i=0; i<_face_texcoords.size(); ++i)
555 {
556 if ( _face_texcoords[i] < (int)texCoords_.size() ){
557
558 PolyMesh::TexCoord2D tex = OpenMesh::vector_cast<PolyMesh::TexCoord2D>( texCoords_[ _face_texcoords[i] ] );
559 currentPolyMesh()->set_texcoord2D(cur_heh, tex);
560
561 cur_heh = currentPolyMesh()->next_halfedge_handle(cur_heh);
562
563 }else
564 std::cerr << "Error: cannot set texture coordinates. undefined index." << std::endl;
565 }
566 }
567 }
568 }
569
570 //-----------------------------------------------------------------------------
571
572 void OBJImporter::addMaterial(std::string _materialName){
573
574
575 if ( isTriangleMesh( currentObject() ) ){
576
577 //handle triangle meshes
578 if ( !currentTriMesh() ) return;
579
580
581 if ( materials_.find( _materialName ) != materials_.end() ){
582
583 Material& mat = materials_[ _materialName ];
584
585 //get textureIndex Property
586 OpenMesh::FPropHandleT< int > indexProperty;
587
588 if ( hasTexture( currentObject() ) ){
589
590 bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
591
592 if ( textureAllowed ){
593
594 // Add texture index property if it doesn't exist yet
595 if (! currentTriMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
596 currentTriMesh()->add_property(indexProperty,TEXTUREINDEX);
597 }
598 }
599
600 for (unsigned int i=0; i < addedFacesTri_[currentGroup_].size(); i++){
601
602 if ( mat.has_Kd() ) {
603 bool colorAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOCOLOR );
604
605 if ( currentTriMesh()->has_face_colors() && colorAllowed ){
606
607 TriMesh::Color color = OpenMesh::color_cast< OpenMesh::Vec4f >(mat.Kd() );
608
609 // Get alpha if available
610 if (mat.has_Tr() ) {
611 color[3] = mat.Tr();
612 } else {
613 color[3] = 1.0;
614 }
615
616 currentTriMesh()->set_color(addedFacesTri_[currentGroup_][i], color );
617 objectOptions_[ currentObject() ] |= FACECOLOR;
618 }
619 }
620
621 bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
622
623 // Set the texture index in the face index property
624 if ( mat.has_Texture() ) {
625
626 if ( hasTexture( currentObject() ) && textureAllowed )
627 currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = mat.map_Kd_index();
628
629 } else {
630 // If we don't have the info, set it to no texture
631 if ( hasTexture( currentObject() ) && textureAllowed )
632 currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = 0;
633 }
634 }
635 }
636
637 } else if ( isPolyMesh( currentObject() ) ){
638
639 //handle poly meshes
640 if ( !currentPolyMesh() ) return;
641
642 if ( materials_.find( _materialName ) != materials_.end() ){
643
644 Material& mat = materials_[ _materialName ];
645
646 //get textureIndex Property
647 OpenMesh::FPropHandleT< int > indexProperty;
648
649 if ( hasTexture( currentObject() ) ){
650
651 bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
652
653 if ( textureAllowed ){
654
655 if (! currentPolyMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
656 currentPolyMesh()->add_property(indexProperty,TEXTUREINDEX);
657 }
658 }
659
660 if ( mat.has_Kd() ) {
661 bool colorAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOCOLOR );
662
663 if ( currentPolyMesh()->has_face_colors() && colorAllowed && addedFacePoly_.is_valid() ){
664
665 TriMesh::Color color = OpenMesh::color_cast< OpenMesh::Vec4f >(mat.Kd() );
666
667 // Get alpha if available
668 if (mat.has_Tr() ) {
669 color[3] = mat.Tr();
670 } else {
671 color[3] = 1.0;
672 }
673
674 currentPolyMesh()->set_color(addedFacePoly_, color );
675 objectOptions_[ currentObject() ] |= FACECOLOR;
676 }
677 }
678
679 bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
680
681 // Set the texture index in the face index property
682 if ( mat.has_Texture() ) {
683
684 if ( hasTexture( currentObject() ) && textureAllowed && addedFacePoly_.is_valid())
685 currentPolyMesh()->property(indexProperty, addedFacePoly_) = mat.map_Kd_index();
686
687 } else {
688 // If we don't have the info, set it to no texture
689 if ( hasTexture( currentObject() ) && textureAllowed && addedFacePoly_.is_valid())
690 currentPolyMesh()->property(indexProperty, addedFacePoly_) = 0;
691 }
692 }
693 }
694 }
695
696 //-----------------------------------------------------------------------------
697
698 // force all meshes to be opened with specific type
699 void OBJImporter::forceMeshType( ObjectOptions _meshType ){
700
701 for (unsigned int i=0; i < objectOptions_.size(); i++){
702
703 bool isMesh = (objectOptions_[i] & TRIMESH) | (objectOptions_[i] & POLYMESH);
704 bool correctType = objectOptions_[i] & _meshType;
705
706 if ( isMesh && !correctType )
707 objectOptions_[i] = _meshType;
708 }
709 }
710
711 //-----------------------------------------------------------------------------
712
713 bool OBJImporter::isTriangleMesh(int _objectID){
714 return objectOptions_[ _objectID ] & TRIMESH;
715 }
716
717 //-----------------------------------------------------------------------------
718
719 bool OBJImporter::isPolyMesh(int _objectID){
720 return objectOptions_[ _objectID ] & POLYMESH;
721 }
722
723 //-----------------------------------------------------------------------------
724
725 bool OBJImporter::isCurve(int _objectID){
726 return objectOptions_[ _objectID ] & CURVE;
727 }
728
729 //-----------------------------------------------------------------------------
730
731 bool OBJImporter::isSurface(int _objectID){
732 return objectOptions_[ _objectID ] & SURFACE;
733 }
734
735 //-----------------------------------------------------------------------------
736
737 bool OBJImporter::hasNormals(int _objectID){
738
739 return objectOptions_[ _objectID ] & NORMALS;
740 }
741
742 //-----------------------------------------------------------------------------
743
744 bool OBJImporter::hasTexture(int _objectID){
745
746 return objectOptions_[ _objectID ] & TEXTURE;
747 }
748
749 //-----------------------------------------------------------------------------
750
751 bool OBJImporter::hasTextureCoords(int _objectID){
752 return objectOptions_[ _objectID ] & TEXCOORDS;
753 }
754
755 //-----------------------------------------------------------------------------
756
757 unsigned int OBJImporter::n_vertices(){
758 return vertices_.size();
759 }
760
761 //-----------------------------------------------------------------------------
762
763 unsigned int OBJImporter::n_normals(){
764 return normals_.size();
765 }
766
767 //-----------------------------------------------------------------------------
768
769 unsigned int OBJImporter::n_texCoords(){
770 return texCoords_.size();
771 }
772
773 //-----------------------------------------------------------------------------
774
775 unsigned int OBJImporter::objectCount(){
776 return groupNames_.size();
777 }
778
779 //-----------------------------------------------------------------------------
780
781 BaseObject* OBJImporter::object(int _objectID) {
782
783 if (objectCount() == 0 || objectCount() <= (unsigned int)_objectID)
784 return NULL;
785
786 if(triMeshes_[_objectID] != NULL) return triMeshes_[_objectID];
787 else if(polyMeshes_[_objectID] != NULL) return polyMeshes_[_objectID];
788 #ifdef ENABLE_BSPLINECURVE_SUPPORT
789 else if(bSplineCurves_[_objectID] != NULL) return bSplineCurves_[_objectID];
790 #endif
791 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
792 else if(bSplineSurfaces_[_objectID] != NULL) return bSplineSurfaces_[_objectID];
793 #endif
794
795 return NULL;
796 }
797
798 //-----------------------------------------------------------------------------
799
800 MaterialList& OBJImporter::materials(){
801 return materials_;
802 }
803
804 //-----------------------------------------------------------------------------
805
806 QString OBJImporter::path(){
807 return path_;
808 }
809
810 //-----------------------------------------------------------------------------
811
812 void OBJImporter::setPath(QString _path){
813 path_ = _path;
814 }
815
816 //-----------------------------------------------------------------------------
817
818 void OBJImporter::setObjectOptions(ObjectOptions _options) {
819
820 while((unsigned int)currentGroup_ >= objectOptions_.size()) {
821 objectOptions_.push_back(NONE);
822 }
823
824 objectOptions_[currentGroup_] = _options;
825 }
826
827 //-----------------------------------------------------------------------------
828
829 std::vector< OBJImporter::ObjectOptions >& OBJImporter::objectOptions(){
830 return objectOptions_;
831 }
832
833 //-----------------------------------------------------------------------------
834
835 // check if object with given id has given option
836 bool OBJImporter::hasOption( unsigned int _id, ObjectOptions _option ){
837
838 if (_id >= objectOptions_.size())
839 return false;
840
841 return objectOptions_[_id] & _option;
842 }
843
844 //-----------------------------------------------------------------------------
845
846 void OBJImporter::setObjectName(int _objectID, QString _name){
847
848 BaseObject* obj = object( _objectID );
849
850 if ( obj != 0 )
851 obj->setName( _name );
852 }
853
854 //-----------------------------------------------------------------------------
855
856 int OBJImporter::addGroup(const QString& _groupName) {
857
858 QString group = _groupName.trimmed();
859 int id = groupId(group);
860 if(id == -1) {
861 groupNames_.push_back(group);
862 vertexMapTri_.push_back(std::map<int,TriMesh::VertexHandle>());
863 vertexMapPoly_.push_back(std::map<int,TriMesh::VertexHandle>());
864 invalidFaces_.push_back(std::vector< OMVHandles >());
865 addedFacesTri_.push_back(std::vector< TriMesh::FaceHandle>());
866
867 triMeshes_.push_back(NULL);
868 polyMeshes_.push_back(NULL);
869 #ifdef ENABLE_BSPLINECURVE_SUPPORT
870 bSplineCurves_.push_back(NULL);
871 #endif
872 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
873 bSplineSurfaces_.push_back(NULL);
874 #endif
875 return groupNames_.size() - 1;
876 }
877 return id;
878 }
879
880 //-----------------------------------------------------------------------------
881
882 int OBJImporter::groupId(const QString& _groupName) const {
883
884 for(unsigned int i = 0; i < groupNames_.size(); ++i) {
885 if(groupNames_[i] == _groupName.trimmed()) return i;
886 }
887 return -1;
888 }
889
890 //-----------------------------------------------------------------------------
891
892 const QString OBJImporter::groupName(const int _grpId) const {
893
894 if((unsigned int)_grpId < groupNames_.size()) {
895 return groupNames_[_grpId];
896 }
897 return QString();
898 }
899
900 //-----------------------------------------------------------------------------
901
902 void OBJImporter::setGroupName(const int _grp, const QString& _name) {
903
904 if((unsigned int)_grp >= groupNames_.size()) return;
905
906 groupNames_[_grp] = _name;
907 }
908
909 //-----------------------------------------------------------------------------
910
911 void OBJImporter::setCurrentGroup(const int _current) {
912
913 currentGroup_ = _current;
914 }
915
916 //-----------------------------------------------------------------------------
917
918 int OBJImporter::currentGroup() const {
919
920 return currentGroup_;
921 }
922
923 //-----------------------------------------------------------------------------
924
925 void OBJImporter::finish() {
926
927 // Duplicate vertices of non-manifold faces
928 // and add them as new isolated face
929 if(invalidFaces_[currentGroup_].empty()) return;
930
931 if (isTriangleMesh(currentObject())) {
932
933 // Handle triangle meshes
934 if ( !currentTriMesh() ) return;
935
936 for(std::vector<OMVHandles>::iterator it = invalidFaces_[currentGroup_].begin();
937 it != invalidFaces_[currentGroup_].end(); ++it) {
938
939 OMVHandles& vhandles = *it;
940
941 // double vertices
942 for (unsigned int j = 0; j < vhandles.size(); ++j)
943 {
944 TriMesh::Point p = currentTriMesh()->point(vhandles[j]);
945 vhandles[j] = currentTriMesh()->add_vertex(p);
946 // DO STORE p, reference may not work since vertex array
947 // may be relocated after adding a new vertex !
948
949 // Mark vertices of failed face as non-manifold
950 if (currentTriMesh()->has_vertex_status()) {
951 currentTriMesh()->status(vhandles[j]).set_fixed_nonmanifold(true);
952 }
953 }
954
955 // add face
956 OpenMesh::FaceHandle fh = currentTriMesh()->add_face(vhandles);
957
958 // Mark failed face as non-manifold
959 if (currentTriMesh()->has_face_status())
960 currentTriMesh()->status(fh).set_fixed_nonmanifold(true);
961
962 // Mark edges of failed face as non-two-manifold
963 if (currentTriMesh()->has_edge_status()) {
964 TriMesh::FaceEdgeIter fe_it = currentTriMesh()->fe_iter(fh);
965 for(; fe_it.is_valid(); ++fe_it) {
966 currentTriMesh()->status(*fe_it).set_fixed_nonmanifold(true);
967 }
968 }
969 }
970
971 } else {
972
973 // Handle Polymeshes
974 if ( !currentPolyMesh() ) return;
975
976 for(std::vector<OMVHandles>::iterator it = invalidFaces_[currentGroup_].begin();
977 it != invalidFaces_[currentGroup_].end(); ++it) {
978
979 OMVHandles& vhandles = *it;
980
981 // double vertices
982 for (unsigned int j = 0; j < vhandles.size(); ++j)
983 {
984 PolyMesh::Point p = currentPolyMesh()->point(vhandles[j]);
985 vhandles[j] = currentPolyMesh()->add_vertex(p);
986 // DO STORE p, reference may not work since vertex array
987 // may be relocated after adding a new vertex !
988
989 // Mark vertices of failed face as non-manifold
990 if (currentPolyMesh()->has_vertex_status()) {
991 currentPolyMesh()->status(vhandles[j]).set_fixed_nonmanifold(true);
992 }
993 }
994
995 // add face
996 OpenMesh::FaceHandle fh = currentPolyMesh()->add_face(vhandles);
997
998 // Mark failed face as non-manifold
999 if (currentPolyMesh()->has_face_status())
1000 currentPolyMesh()->status(fh).set_fixed_nonmanifold(true);
1001
1002 // Mark edges of failed face as non-two-manifold
1003 if (currentPolyMesh()->has_edge_status()) {
1004 PolyMesh::FaceEdgeIter fe_it = currentPolyMesh()->fe_iter(fh);
1005 for(; fe_it.is_valid(); ++fe_it) {
1006 currentPolyMesh()->status(*fe_it).set_fixed_nonmanifold(true);
1007 }
1008 }
1009 }
1010 }
1011
1012 // Clear faces
1013 invalidFaces_[currentGroup_].clear();
1014 }
1015
1016 //-----------------------------------------------------------------------------
1017
1018 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1019 void OBJImporter::setCurveGroupId(const unsigned int _count, const int _id) {
1020 curvesMap_[_count] = _id;
1021 }
1022 #endif
1023
1024 //-----------------------------------------------------------------------------
1025
1026 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1027 int OBJImporter::getCurveGroupId(const unsigned int _count) {
1028 return curvesMap_[_count];
1029 }
1030 #endif
1031
1032 //-----------------------------------------------------------------------------
1033
1034 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1035 void OBJImporter::setCurveParentId(const int _curveGroup, const int _parentGroup) {
1036 curveParentGroupMap_[_curveGroup] = _parentGroup;
1037 }
1038 #endif
1039
1040 //-----------------------------------------------------------------------------
1041
1042 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1043 int OBJImporter::getCurveParentId(const int _curveGroup) {
1044 return curveParentGroupMap_[_curveGroup];
1045 }
1046 #endif
1047
1048 //-----------------------------------------------------------------------------
1049
1050 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1051 void OBJImporter::setSurfaceGroupId(const unsigned int _count, const int _id) {
1052 surfacesMap_[_count] = _id;
1053 }
1054 #endif
1055
1056 //-----------------------------------------------------------------------------
1057
1058 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1059 int OBJImporter::getSurfaceGroupId(const unsigned int _count) {
1060 return surfacesMap_[_count];
1061 }
1062 #endif
1063
1064 //-----------------------------------------------------------------------------
1065
1066 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1067 void OBJImporter::setSurfaceParentId(const int _surfaceGroup, const int _parentGroup) {
1068 surfaceParentGroupMap_[_surfaceGroup] = _parentGroup;
1069 }
1070 #endif
1071
1072 //-----------------------------------------------------------------------------
1073
1074 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1075 int OBJImporter::getSurfaceParentId(const int _surfaceGroup) {
1076 return surfaceParentGroupMap_[_surfaceGroup];
1077 }
1078 #endif
1079
1080 //-----------------------------------------------------------------------------
1081
1082 //used materials
1083 const std::vector<std::string> OBJImporter::usedMaterials(unsigned int _objectID){
1084
1085 if (_objectID >= usedMaterials_.size())
1086 return std::vector<std::string>();
1087 else
1088 return usedMaterials_[ _objectID ];
1089 }
1090
1091 //-----------------------------------------------------------------------------
1092
1093 void OBJImporter::useMaterial( std::string _materialName ){
1094
1095 while( (int)usedMaterials_.size() - 1 < currentObject() )
1096 usedMaterials_.push_back( std::vector<std::string>() );
1097
1098 //check that it is not added already
1099 for (unsigned int i=0; i < usedMaterials_[ currentObject() ].size(); i++ )
1100 if ( usedMaterials_[ currentObject() ][i] == _materialName )
1101 return;
1102
1103 usedMaterials_[ currentObject() ].push_back( _materialName );
1104
1105 objectOptions_[ currentObject() ] |= TEXTURE;
1106 }
1107
1109 void OBJImporter::useVertex(int _vertex_index){
1110
1111 while(currentGroup_ >= (int)usedVertices_.size()) {
1112 usedVertices_.push_back(std::map<int,VertexHandle>());
1113 }
1114
1115 usedVertices_[currentGroup_].insert(std::pair<int,VertexHandle>(_vertex_index,-1));
1116
1117 // while( (int)usedVertices_.size() - 1 < (int) objectOptions_.size() )
1118 // usedVertices_.push_back( std::set<VertexHandle>() );
1119 //
1120 // usedVertices_[ objectOptions_.size() ].insert( _vertex );
1121 }
1122
1123 //-----------------------------------------------------------------------------
1124
OpenMesh::Attributes::Color
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:88
OBJImporter::forceMeshType
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
Definition: OBJImporter.cc:699
OBJImporter::path
QString path()
Path of the OBJ file.
Definition: OBJImporter.cc:806
OBJImporter::addMaterial
void addMaterial(std::string _materialName)
Add a material.
Definition: OBJImporter.cc:572
OBJImporter::setObject
void setObject(BaseObject *_object, int _groupId)
add an object
Definition: OBJImporter.cc:128
OBJImporter::~OBJImporter
~OBJImporter()
base class needs virtual destructor
Definition: OBJImporter.cc:56
OBJImporter::finish
void finish()
Definition: OBJImporter.cc:925
OBJImporter::objectOptions
std::vector< ObjectOptions > & objectOptions()
Object Options for all objects.
Definition: OBJImporter.cc:829
OpenMesh::PolyMeshT::FaceEdgeIter
Kernel::FaceEdgeIter FaceEdgeIter
Circulator.
Definition: PolyMeshT.hh:172
ACG::BSplineCurveT
Definition: BSplineCurveT.hh:88
OBJImporter::hasOption
bool hasOption(unsigned int _id, ObjectOptions _option)
check if object with given id has given option
Definition: OBJImporter.cc:836
OBJImporter::currentPolyMesh
PolyMesh * currentPolyMesh()
get a pointer to the active polyMesh
Definition: OBJImporter.cc:173
PluginFunctions::polyMeshObject
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
Definition: PluginFunctionsPolyMesh.cc:155
OpenMesh::vector_cast
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:86
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
OBJImporter::materials
MaterialList & materials()
return all loaded materials
Definition: OBJImporter.cc:800
OBJImporter::hasNormals
bool hasNormals(int _objectID)
Query Object Options.
Definition: OBJImporter.cc:737
OBJImporter::setDegreeV
void setDegreeV(int _degree)
set degree V direction
Definition: OBJImporter.cc:106
OpenMesh::PolyMeshT::TexCoord2D
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition: PolyMeshT.hh:123
OBJImporter::setDegreeU
void setDegreeU(int _degree)
set degree
Definition: OBJImporter.cc:99
OBJImporter::n_vertices
unsigned int n_vertices()
Global Properties.
Definition: OBJImporter.cc:757
OBJImporter::setVertexTexCoord
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
Definition: OBJImporter.cc:266
BaseObject
Definition: BaseObject.hh:94
OpenMesh::Attributes::TexCoord2D
Add 2D texture coordinates (vertices, halfedges)
Definition: Attributes.hh:92
OBJImporter::addFace
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
Definition: OBJImporter.cc:474
ACG::BSplineSurfaceT
Definition: BSplineSurfaceT.hh:88
OpenMesh::VectorT
Definition: Vector11T.hh:83
OBJImporter::vertex
Vec3f vertex(unsigned int _index)
get vertex with given index
Definition: OBJImporter.cc:70
PluginFunctions::triMeshObject
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Definition: PluginFunctionsTriangleMesh.cc:162
OBJImporter::setNormal
void setNormal(int _index, int _normalID)
set vertex normal
Definition: OBJImporter.cc:311
OBJImporter::addUsedVertices
void addUsedVertices(int _groupId)
add all vertices that are used to the mesh (in correct order)
Definition: OBJImporter.cc:211
OBJImporter::addVertex
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
Definition: OBJImporter.cc:63
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:146
OBJImporter::currentTriMesh
TriMesh * currentTriMesh()
get a pointer to the active triMesh
Definition: OBJImporter.cc:181
OBJImporter::object
BaseObject * object(int _objectID)
return object with given index
Definition: OBJImporter.cc:781
OpenMesh::FPropHandleT
Definition: Property.hh:529
OpenMesh::Attributes::Normal
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
OBJImporter::currentObject
int currentObject()
get id of the active object
Definition: OBJImporter.cc:165
OBJImporter::setObjectOptions
void setObjectOptions(ObjectOptions _options)
Definition: OBJImporter.cc:818
PluginFunctions::baseObjectData
BaseObjectData * baseObjectData(BaseObject *_object)
Cast an BaseObject to a BaseObjectData if possible.
Definition: PluginFunctions.cc:1093
OBJImporter::addTexCoord
int addTexCoord(const Vec2f &_coord)
add texture coordinates
Definition: OBJImporter.cc:81
PluginFunctions::bsplineCurveObject
BSplineCurveObject * bsplineCurveObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineCurveObject if possible.
Definition: PluginFunctionsBSplineCurve.cc:106
OpenVolumeMesh::Geometry::VectorT
Definition: Vector11T.hh:78
OBJImporter::usedMaterials
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
Definition: OBJImporter.cc:1083
BaseObject::setName
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
Definition: BaseObject.cc:734
OBJImporter::degreeU
int degreeU()
get current degree
Definition: OBJImporter.cc:114
OBJImporter::setObjectName
void setObjectName(int _objectID, QString _name)
change the name of an object
Definition: OBJImporter.cc:846
OpenMesh::PolyMeshT::FaceHalfedgeIter
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:171
OBJImporter::useVertex
void useVertex(int _vertex_index)
used vertices
Definition: OBJImporter.cc:1109
OBJImporter::degreeV
int degreeV()
get current degree
Definition: OBJImporter.cc:121
PluginFunctions::bsplineSurfaceObject
BSplineSurfaceObject * bsplineSurfaceObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineSurfaceObject if possible.
Definition: PluginFunctionsBSplineSurface.cc:108
BaseObject::id
int id() const
Definition: BaseObject.cc:201
OBJImporter::addNormal
int addNormal(const Vec3f &_normal)
add a normal
Definition: OBJImporter.cc:90