Developer Documentation
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 
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 
115  return degreeU_;
116 }
117 
118 //-----------------------------------------------------------------------------
119 
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
147 
148  bSplineCurves_[_groupId] = PluginFunctions::bsplineCurveObject(PluginFunctions::baseObjectData(_object));
149  }
150 #endif
151 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
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 
166 
167  return currentGroup_;
168 }
169 
170 //-----------------------------------------------------------------------------
171 
174 
175  return polyMeshes_[currentGroup_]->mesh();
176 }
177 
178 //-----------------------------------------------------------------------------
179 
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){
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 
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 
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 
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 
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 
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:171
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
void setDegreeV(int _degree)
set degree V direction
Definition: OBJImporter.cc:106
void useVertex(int _vertex_index)
used vertices
void setNormal(int _index, int _normalID)
set vertex normal
Definition: OBJImporter.cc:311
int currentObject()
get id of the active object
Definition: OBJImporter.cc:165
void setObjectName(int _objectID, QString _name)
change the name of an object
Definition: OBJImporter.cc:846
BSplineSurfaceObject * bsplineSurfaceObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineSurfaceObject if possible.
BaseObjectData * baseObjectData(BaseObject *_object)
Cast an BaseObject to a BaseObjectData if possible.
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
Definition: OBJImporter.cc:63
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
Definition: OBJImporter.cc:699
void addUsedVertices(int _groupId)
add all vertices that are used to the mesh (in correct order)
Definition: OBJImporter.cc:211
Kernel::FaceEdgeIter FaceEdgeIter
Circulator.
Definition: PolyMeshT.hh:172
unsigned int n_vertices()
Global Properties.
Definition: OBJImporter.cc:757
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:119
void setObjectOptions(ObjectOptions _options)
Definition: OBJImporter.cc:818
int id() const
Definition: BaseObject.cc:201
void finish()
Definition: OBJImporter.cc:925
QString path()
Path of the OBJ file.
Definition: OBJImporter.cc:806
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:117
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
void setDegreeU(int _degree)
set degree
Definition: OBJImporter.cc:99
int addTexCoord(const Vec2f &_coord)
add texture coordinates
Definition: OBJImporter.cc:81
int degreeV()
get current degree
Definition: OBJImporter.cc:121
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
Definition: OBJImporter.cc:266
BSplineCurveObject * bsplineCurveObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineCurveObject if possible.
~OBJImporter()
base class needs virtual destructor
Definition: OBJImporter.cc:56
Vec3f vertex(unsigned int _index)
get vertex with given index
Definition: OBJImporter.cc:70
bool hasNormals(int _objectID)
Query Object Options.
Definition: OBJImporter.cc:737
BaseObject * object(int _objectID)
return object with given index
Definition: OBJImporter.cc:781
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
int degreeU()
get current degree
Definition: OBJImporter.cc:114
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition: PolyMeshT.hh:123
PolyMesh * currentPolyMesh()
get a pointer to the active polyMesh
Definition: OBJImporter.cc:173
Handle for a face entity.
Definition: Handles.hh:146
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
Definition: OBJImporter.cc:474
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
TriMesh * currentTriMesh()
get a pointer to the active triMesh
Definition: OBJImporter.cc:181
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
Definition: BaseObject.cc:734
std::vector< ObjectOptions > & objectOptions()
Object Options for all objects.
Definition: OBJImporter.cc:829
void setObject(BaseObject *_object, int _groupId)
add an object
Definition: OBJImporter.cc:128
void addMaterial(std::string _materialName)
Add a material.
Definition: OBJImporter.cc:572
bool hasOption(unsigned int _id, ObjectOptions _option)
check if object with given id has given option
Definition: OBJImporter.cc:836
int addNormal(const Vec3f &_normal)
add a normal
Definition: OBJImporter.cc:90
MaterialList & materials()
return all loaded materials
Definition: OBJImporter.cc:800