/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see . *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#include "OBJImporter.hh"
#include
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// base class needs virtual destructor
OBJImporter::~OBJImporter(){
}
//-----------------------------------------------------------------------------
/// add a vertex with coordinate \c _point
VertexHandle OBJImporter::addVertex(const Vec3f& _point){
vertices_.push_back( _point );
return vertices_.size()-1;
}
/// get vertex with given index
Vec3f OBJImporter::vertex(unsigned int _index){
if ( vertices_.size() > _index )
return vertices_[ _index ];
else
return Vec3f();
}
//-----------------------------------------------------------------------------
/// add texture coordinates
int OBJImporter::addTexCoord(const Vec2f& _coord){
texCoords_.push_back( _coord );
return texCoords_.size()-1;
}
//-----------------------------------------------------------------------------
/// add a normal
int OBJImporter::addNormal(const Vec3f& _normal){
normals_.push_back( _normal );
return normals_.size()-1;
}
//-----------------------------------------------------------------------------
/// set degree U direction
void OBJImporter::setDegreeU(int _degree){
degreeU_ = _degree;
}
//-----------------------------------------------------------------------------
/// set degree V direction
void OBJImporter::setDegreeV(int _degree){
degreeV_ = _degree;
}
//-----------------------------------------------------------------------------
/// get current degree
int OBJImporter::degreeU(){
return degreeU_;
}
//-----------------------------------------------------------------------------
/// get current degree
int OBJImporter::degreeV(){
return degreeV_;
}
//-----------------------------------------------------------------------------
/// add a mesh
void OBJImporter::setObject(BaseObject* _object, int _groupId) {
if((unsigned int)_groupId >= triMeshes_.size()) {
std::cerr << "Error: Group does not exist!" << std::endl;
return;
}
if(PluginFunctions::polyMeshObject(_object->id()) != NULL) {
polyMeshes_[_groupId] = PluginFunctions::polyMeshObject(_object->id());
addUsedVertices(_groupId);
} else if(PluginFunctions::triMeshObject(_object->id()) != NULL) {
triMeshes_[_groupId] = PluginFunctions::triMeshObject(_object->id());
addUsedVertices(_groupId);
}
#ifdef ENABLE_BSPLINECURVE_SUPPORT
else if(PluginFunctions::bsplineCurveObject(PluginFunctions::baseObjectData(_object)) != NULL) {
bSplineCurves_[_groupId] = PluginFunctions::bsplineCurveObject(PluginFunctions::baseObjectData(_object));
}
#endif
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
else if(PluginFunctions::bsplineSurfaceObject(PluginFunctions::baseObjectData(_object)) != NULL) {
bSplineSurfaces_[_groupId] = PluginFunctions::bsplineSurfaceObject(PluginFunctions::baseObjectData(_object));
}
#endif
else {
std::cerr << "Error: Cannot add object. Type is unknown!" << std::endl;
}
}
//-----------------------------------------------------------------------------
/// get id of the active object
int OBJImporter::currentObject(){
return currentGroup_;
}
//-----------------------------------------------------------------------------
/// get the active polyMesh
PolyMesh* OBJImporter::currentPolyMesh(){
return polyMeshes_[currentGroup_]->mesh();
}
//-----------------------------------------------------------------------------
/// get the active triMesh
TriMesh* OBJImporter::currentTriMesh(){
return triMeshes_[currentGroup_]->mesh();
}
//-----------------------------------------------------------------------------
#ifdef ENABLE_BSPLINECURVE_SUPPORT
BSplineCurve* OBJImporter::currentCurve(){
return bSplineCurves_[currentGroup_]->splineCurve();
}
#endif
//-----------------------------------------------------------------------------
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
BSplineSurface* OBJImporter::currentSurface(){
return bSplineSurfaces_[currentGroup_]->splineSurface();
}
#endif
//-----------------------------------------------------------------------------
/// add all vertices that are used to the mesh (in correct order)
void OBJImporter::addUsedVertices(int _groupId) {
if (isTriangleMesh(_groupId)) {
//handle triangle meshes
TriMesh* curMesh = triMeshes_[_groupId]->mesh();
if (curMesh == NULL)
return;
// add all vertices to the mesh
if(usedVertices_.size() <= (unsigned int)_groupId) return;
for(std::map::const_iterator it = usedVertices_[_groupId].begin();
it != usedVertices_[_groupId].end(); ++it) {
if (it->first >= (int)vertices_.size()) {
std::cerr << "Error: Vertex ID too large" << std::endl;
continue;
}
if (vertexMapTri_[_groupId].find(it->first) == vertexMapTri_[_groupId].end()) {
vertexMapTri_[_groupId].insert(std::pair(it->first, curMesh->add_vertex((TriMesh::Point)vertices_[it->first])));
}
}
} else if (isPolyMesh(_groupId)) {
//handle triangle meshes
PolyMesh* curMesh = polyMeshes_[_groupId]->mesh();
if (curMesh == NULL)
return;
//add all vertices to the mesh
if(usedVertices_.size() <= (unsigned int)currentObject()) return;
for(std::map::const_iterator it = usedVertices_[_groupId].begin();
it != usedVertices_[_groupId].end(); ++it) {
if (it->first >= (int)vertices_.size()) {
std::cerr << "Error: Vertex ID too large" << std::endl;
continue;
}
if (vertexMapPoly_[_groupId].find(it->first) == vertexMapPoly_[_groupId].end()) {
vertexMapPoly_[_groupId].insert(std::pair(it->first, curMesh->add_vertex((PolyMesh::Point)vertices_[it->first])));
}
}
}
}
//-----------------------------------------------------------------------------
/// set vertex texture coordinate
void OBJImporter::setVertexTexCoord(VertexHandle _vh, int _texCoordID){
if ( isTriangleMesh( currentObject() ) ){
//handle triangle meshes
if ( !currentTriMesh() ) return;
if ( _texCoordID < (int) texCoords_.size() ){
//perhaps request texCoords for the mesh
if ( !currentTriMesh()->has_vertex_texcoords2D() )
currentTriMesh()->request_vertex_texcoords2D();
//set the texCoords
if ( vertexMapTri_[currentGroup_].find( _vh ) != vertexMapTri_[currentGroup_].end() )
currentTriMesh()->set_texcoord2D( vertexMapTri_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
}else{
std::cerr << "Error: TexCoord ID too large" << std::endl;
}
} else if ( isPolyMesh( currentObject() ) ){
//handle poly meshes
if ( !currentPolyMesh() ) return;
if ( _texCoordID < (int) texCoords_.size() ){
//perhaps request texCoords for the mesh
if ( !currentPolyMesh()->has_vertex_texcoords2D() )
currentPolyMesh()->request_vertex_texcoords2D();
//set the texCoords
if ( vertexMapPoly_[currentGroup_].find( _vh ) != vertexMapPoly_[currentGroup_].end() )
currentPolyMesh()->set_texcoord2D( vertexMapPoly_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
}else{
std::cerr << "Error: TexCoord ID too large" << std::endl;
}
}
}
//-----------------------------------------------------------------------------
/// set vertex normal
void OBJImporter::setNormal(int _index, int _normalID){
if ( isTriangleMesh( currentObject() ) ){
//handle triangle meshes
if ( !currentTriMesh() ) return;
if ( _normalID < (int) normals_.size() ){
if ( vertexMapTri_[currentGroup_].find( _index ) != vertexMapTri_[currentGroup_].end() ){
currentTriMesh()->set_normal( vertexMapTri_[currentGroup_][_index], (TriMesh::Point) normals_[ _normalID ] );
objectOptions_[ currentGroup_ ] |= NORMALS;
}
}else{
std::cerr << "Error: normal ID too large" << std::endl;
}
} else if ( isPolyMesh( currentObject() ) ){
//handle poly meshes
if ( !currentPolyMesh() ) return;
if ( _normalID < (int) normals_.size() ){
if ( vertexMapPoly_[currentGroup_].find( _index ) != vertexMapPoly_[currentGroup_].end() ){
currentPolyMesh()->set_normal( vertexMapPoly_[currentGroup_][_index], (PolyMesh::Point) normals_[ _normalID ] );
objectOptions_[ currentGroup_ ] |= NORMALS;
}
}else{
std::cerr << "Error: normal ID too large" << std::endl;
}
}
}
//-----------------------------------------------------------------------------
/// add a face with indices _indices refering to vertices
void OBJImporter::addFace(const VHandles& _indices){
if ( isTriangleMesh( currentObject() ) ){
//handle triangle meshes
if ( !currentTriMesh() ) return;
addedFacesTri_[currentGroup_].clear();
std::vector< TriMesh::VertexHandle > vertices;
for (unsigned int i=0; i < _indices.size(); i++){
if ( vertexMapTri_[currentGroup_].find( _indices[i] ) != vertexMapTri_[currentGroup_].end() ){
vertices.push_back( vertexMapTri_[currentGroup_][ _indices[i] ] );
}else{
std::cerr << "Error: cannot add face. undefined index (" << _indices[i] << ")" << std::endl;
return;
}
}
size_t n_faces = currentTriMesh()->n_faces();
OpenMesh::FaceHandle fh = currentTriMesh()->add_face( vertices );
//remember all new faces
if(!fh.is_valid()) {
// Store non-manifold face
invalidFaces_.push_back(vertices);
} else {
// Store recently added face
for( size_t i=0; i < currentTriMesh()->n_faces()-n_faces; ++i )
addedFacesTri_[currentGroup_].push_back( TriMesh::FaceHandle(n_faces+i) );
}
} else if ( isPolyMesh( currentObject() ) ){
//handle poly meshes
if ( !currentPolyMesh() ) return;
std::vector< PolyMesh::VertexHandle > vertices;
for (unsigned int i=0; i < _indices.size(); i++){
if ( vertexMapPoly_[currentGroup_].find( _indices[i] ) != vertexMapPoly_[currentGroup_].end() ){
vertices.push_back( vertexMapPoly_[currentGroup_][ _indices[i] ] );
}else{
std::cerr << "Error: cannot add face. undefined index (" << _indices[i] << ")" << std::endl;
return;
}
}
OpenMesh::FaceHandle fh = currentPolyMesh()->add_face( vertices );
if(!fh.is_valid()) {
// Store non-manifold face
invalidFaces_.push_back(vertices);
} else {
addedFacePoly_ = fh;
}
}
}
//-----------------------------------------------------------------------------
/// add face and texture coordinates
void OBJImporter::addFace(const VHandles& _indices, const std::vector& _face_texcoords){
if ( isTriangleMesh( currentObject() ) ){
//handle triangle meshes
if ( !currentTriMesh() ) return;
addedFacesTri_[currentGroup_].clear();
std::vector< TriMesh::VertexHandle > vertices;
for (unsigned int i=0; i < _indices.size(); i++){
if ( vertexMapTri_[currentGroup_].find( _indices[i] ) != vertexMapTri_[currentGroup_].end() ){
vertices.push_back( vertexMapTri_[currentGroup_][ _indices[i] ] );
}else{
std::cerr << "Error: cannot add face. undefined index (" << _indices[i] << ")" << std::endl;
return;
}
}
size_t n_faces = currentTriMesh()->n_faces();
OpenMesh::FaceHandle fh = currentTriMesh()->add_face( vertices );
//remember all new faces
if(!fh.is_valid()) {
// Store non-manifold face
invalidFaces_.push_back(vertices);
std::cerr << "Error: Unable to add face " << std::endl;
} else {
// Store recently added face
for( size_t i=0; i < currentTriMesh()->n_faces()-n_faces; ++i )
addedFacesTri_[currentGroup_].push_back( TriMesh::FaceHandle(n_faces+i) );
//perhaps request texCoords for the mesh
if ( !currentTriMesh()->has_halfedge_texcoords2D() )
currentTriMesh()->request_halfedge_texcoords2D();
//now add texCoords
// get first halfedge handle
TriMesh::HalfedgeHandle cur_heh = currentTriMesh()->halfedge_handle( addedFacesTri_[currentGroup_][0] );
TriMesh::HalfedgeHandle end_heh = currentTriMesh()->prev_halfedge_handle(cur_heh);
// find start heh
while( currentTriMesh()->to_vertex_handle(cur_heh) != vertices[0] && cur_heh != end_heh )
cur_heh = currentTriMesh()->next_halfedge_handle( cur_heh);
for(unsigned int i=0; i<_face_texcoords.size(); ++i)
{
if ( _face_texcoords[i] < (int)texCoords_.size() ){
PolyMesh::TexCoord2D tex = OpenMesh::vector_cast( texCoords_[ _face_texcoords[i] ] );
currentTriMesh()->set_texcoord2D(cur_heh, tex);
cur_heh = currentTriMesh()->next_halfedge_handle(cur_heh);
} else
std::cerr << "Error: cannot set texture coordinates. undefined index." << std::endl;
}
}
} else if ( isPolyMesh( currentObject() ) ){
//handle poly meshes
if ( !currentPolyMesh() ) return;
std::vector< PolyMesh::VertexHandle > vertices;
for (unsigned int i=0; i < _indices.size(); i++) {
if ( vertexMapPoly_[currentGroup_].find( _indices[i] ) != vertexMapPoly_[currentGroup_].end() ){
vertices.push_back( vertexMapPoly_[currentGroup_][ _indices[i] ] );
} else {
std::cerr << "Error: cannot add face poly mesh. undefined index(" << _indices[i] << ")" << std::endl;
std::cerr << "Vertices in index map: " << vertexMapPoly_[currentGroup_].size() << std::endl;
return;
}
}
OpenMesh::FaceHandle fh = currentPolyMesh()->add_face( vertices );
if(!fh.is_valid()) {
// Store non-manifold face
invalidFaces_.push_back(vertices);
} else {
addedFacePoly_ = fh;
//perhaps request texCoords for the mesh
if ( !currentPolyMesh()->has_halfedge_texcoords2D() )
currentPolyMesh()->request_halfedge_texcoords2D();
//now add texCoords
if ( addedFacePoly_.is_valid() ) {
// get first halfedge handle
PolyMesh::HalfedgeHandle cur_heh = currentPolyMesh()->halfedge_handle( addedFacePoly_ );
PolyMesh::HalfedgeHandle end_heh = currentPolyMesh()->prev_halfedge_handle(cur_heh);
// find start heh
while( currentPolyMesh()->to_vertex_handle(cur_heh) != vertices[0] && cur_heh != end_heh )
cur_heh = currentPolyMesh()->next_halfedge_handle( cur_heh);
for(unsigned int i=0; i<_face_texcoords.size(); ++i)
{
if ( _face_texcoords[i] < (int)texCoords_.size() ){
PolyMesh::TexCoord2D tex = OpenMesh::vector_cast( texCoords_[ _face_texcoords[i] ] );
currentPolyMesh()->set_texcoord2D(cur_heh, tex);
cur_heh = currentPolyMesh()->next_halfedge_handle(cur_heh);
}else
std::cerr << "Error: cannot set texture coordinates. undefined index." << std::endl;
}
}
}
}
}
//-----------------------------------------------------------------------------
void OBJImporter::addMaterial(std::string _materialName){
if ( isTriangleMesh( currentObject() ) ){
//handle triangle meshes
if ( !currentTriMesh() ) return;
if ( materials_.find( _materialName ) != materials_.end() ){
Material& mat = materials_[ _materialName ];
//get textureIndex Property
OpenMesh::FPropHandleT< int > indexProperty;
if ( hasTexture( currentObject() ) ){
bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
if ( textureAllowed ){
// Add texture index property if it doesn't exist yet
if (! currentTriMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
currentTriMesh()->add_property(indexProperty,TEXTUREINDEX);
}
}
for (unsigned int i=0; i < addedFacesTri_[currentGroup_].size(); i++){
if ( mat.has_Kd() ) {
bool colorAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOCOLOR );
if ( currentTriMesh()->has_face_colors() && colorAllowed ){
TriMesh::Color color = OpenMesh::color_cast< OpenMesh::Vec4f >(mat.Kd() );
// Get alpha if available
if (mat.has_Tr() ) {
color[3] = mat.Tr();
} else {
color[3] = 1.0;
}
currentTriMesh()->set_color(addedFacesTri_[currentGroup_][i], color );
objectOptions_[ currentObject() ] |= FACECOLOR;
}
}
bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
// Set the texture index in the face index property
if ( mat.has_Texture() ) {
if ( hasTexture( currentObject() ) && textureAllowed )
currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = mat.map_Kd_index();
} else {
// If we don't have the info, set it to no texture
if ( hasTexture( currentObject() ) && textureAllowed )
currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = 0;
}
}
}
} else if ( isPolyMesh( currentObject() ) ){
//handle poly meshes
if ( !currentPolyMesh() ) return;
if ( materials_.find( _materialName ) != materials_.end() ){
Material& mat = materials_[ _materialName ];
//get textureIndex Property
OpenMesh::FPropHandleT< int > indexProperty;
if ( hasTexture( currentObject() ) ){
bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
if ( textureAllowed ){
if (! currentPolyMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
currentPolyMesh()->add_property(indexProperty,TEXTUREINDEX);
}
}
if ( mat.has_Kd() ) {
bool colorAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOCOLOR );
if ( currentPolyMesh()->has_face_colors() && colorAllowed && addedFacePoly_.is_valid() ){
TriMesh::Color color = OpenMesh::color_cast< OpenMesh::Vec4f >(mat.Kd() );
// Get alpha if available
if (mat.has_Tr() ) {
color[3] = mat.Tr();
} else {
color[3] = 1.0;
}
currentPolyMesh()->set_color(addedFacePoly_, color );
objectOptions_[ currentObject() ] |= FACECOLOR;
}
}
bool textureAllowed = ! ( objectOptions_[ currentObject() ] & FORCE_NOTEXTURES );
// Set the texture index in the face index property
if ( mat.has_Texture() ) {
if ( hasTexture( currentObject() ) && textureAllowed && addedFacePoly_.is_valid())
currentPolyMesh()->property(indexProperty, addedFacePoly_) = mat.map_Kd_index();
} else {
// If we don't have the info, set it to no texture
if ( hasTexture( currentObject() ) && textureAllowed && addedFacePoly_.is_valid())
currentPolyMesh()->property(indexProperty, addedFacePoly_) = 0;
}
}
}
}
//-----------------------------------------------------------------------------
// force all meshes to be opened with specific type
void OBJImporter::forceMeshType( ObjectOptions _meshType ){
for (unsigned int i=0; i < objectOptions_.size(); i++){
bool isMesh = (objectOptions_[i] & TRIMESH) | (objectOptions_[i] & POLYMESH);
bool correctType = objectOptions_[i] & _meshType;
if ( isMesh && !correctType )
objectOptions_[i] = _meshType;
}
}
//-----------------------------------------------------------------------------
bool OBJImporter::isTriangleMesh(int _objectID){
return objectOptions_[ _objectID ] & TRIMESH;
}
//-----------------------------------------------------------------------------
bool OBJImporter::isPolyMesh(int _objectID){
return objectOptions_[ _objectID ] & POLYMESH;
}
//-----------------------------------------------------------------------------
bool OBJImporter::isCurve(int _objectID){
return objectOptions_[ _objectID ] & CURVE;
}
//-----------------------------------------------------------------------------
bool OBJImporter::isSurface(int _objectID){
return objectOptions_[ _objectID ] & SURFACE;
}
//-----------------------------------------------------------------------------
bool OBJImporter::hasNormals(int _objectID){
return objectOptions_[ _objectID ] & NORMALS;
}
//-----------------------------------------------------------------------------
bool OBJImporter::hasTexture(int _objectID){
return objectOptions_[ _objectID ] & TEXTURE;
}
//-----------------------------------------------------------------------------
bool OBJImporter::hasTextureCoords(int _objectID){
return objectOptions_[ _objectID ] & TEXCOORDS;
}
//-----------------------------------------------------------------------------
unsigned int OBJImporter::n_vertices(){
return vertices_.size();
}
//-----------------------------------------------------------------------------
unsigned int OBJImporter::n_normals(){
return normals_.size();
}
//-----------------------------------------------------------------------------
unsigned int OBJImporter::n_texCoords(){
return texCoords_.size();
}
//-----------------------------------------------------------------------------
unsigned int OBJImporter::objectCount(){
return groupNames_.size();
}
//-----------------------------------------------------------------------------
BaseObject* OBJImporter::object(int _objectID) {
if (objectCount() == 0 || objectCount() <= (unsigned int)_objectID)
return NULL;
if(triMeshes_[_objectID] != NULL) return triMeshes_[_objectID];
else if(polyMeshes_[_objectID] != NULL) return polyMeshes_[_objectID];
else if(bSplineCurves_[_objectID] != NULL) return bSplineCurves_[_objectID];
else if(bSplineSurfaces_[_objectID] != NULL) return bSplineSurfaces_[_objectID];
return NULL;
}
//-----------------------------------------------------------------------------
MaterialList& OBJImporter::materials(){
return materials_;
}
//-----------------------------------------------------------------------------
QString OBJImporter::path(){
return path_;
}
//-----------------------------------------------------------------------------
void OBJImporter::setPath(QString _path){
path_ = _path;
}
//-----------------------------------------------------------------------------
void OBJImporter::setObjectOptions(ObjectOptions _options) {
while((unsigned int)currentGroup_ >= objectOptions_.size()) {
objectOptions_.push_back(POLYMESH);
}
objectOptions_[currentGroup_] = _options;
}
//-----------------------------------------------------------------------------
std::vector< OBJImporter::ObjectOptions >& OBJImporter::objectOptions(){
return objectOptions_;
}
//-----------------------------------------------------------------------------
// check if object with given id has given option
bool OBJImporter::hasOption( unsigned int _id, ObjectOptions _option ){
if (_id >= objectOptions_.size())
return false;
return objectOptions_[_id] & _option;
}
//-----------------------------------------------------------------------------
void OBJImporter::setObjectName(int _objectID, QString _name){
BaseObject* obj = object( _objectID );
if ( obj != 0 )
obj->setName( _name );
}
//-----------------------------------------------------------------------------
int OBJImporter::addGroup(const QString& _groupName) {
QString group = _groupName.trimmed();
int id = groupId(group);
if(id == -1) {
groupNames_.push_back(group);
vertexMapTri_.push_back(std::map());
vertexMapPoly_.push_back(std::map());
addedFacesTri_.push_back(std::vector< TriMesh::FaceHandle>());
triMeshes_.push_back(NULL);
polyMeshes_.push_back(NULL);
#ifdef ENABLE_BSPLINECURVE_SUPPORT
bSplineCurves_.push_back(NULL);
#endif
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
bSplineSurfaces_.push_back(NULL);
#endif
return groupNames_.size() - 1;
}
return id;
}
//-----------------------------------------------------------------------------
int OBJImporter::groupId(const QString& _groupName) const {
for(unsigned int i = 0; i < groupNames_.size(); ++i) {
if(groupNames_[i] == _groupName.trimmed()) return i;
}
return -1;
}
//-----------------------------------------------------------------------------
const QString OBJImporter::groupName(const int _grpId) const {
if((unsigned int)_grpId < groupNames_.size()) {
return groupNames_[_grpId];
}
return QString();
}
//-----------------------------------------------------------------------------
void OBJImporter::setGroupName(const int _grp, const QString& _name) {
if((unsigned int)_grp >= groupNames_.size()) return;
groupNames_[_grp] = _name;
}
//-----------------------------------------------------------------------------
void OBJImporter::setCurrentGroup(const int _current) {
currentGroup_ = _current;
}
//-----------------------------------------------------------------------------
int OBJImporter::currentGroup() const {
return currentGroup_;
}
//-----------------------------------------------------------------------------
void OBJImporter::finish() {
// Duplicate vertices of non-manifold faces
// and add them as new isolated face
if(invalidFaces_.empty()) return;
if (isTriangleMesh(currentObject())) {
// Handle triangle meshes
if ( !currentTriMesh() ) return;
for(std::vector::iterator it = invalidFaces_.begin();
it != invalidFaces_.end(); ++it) {
OMVHandles& vhandles = *it;
// double vertices
for (unsigned int j = 0; j < vhandles.size(); ++j)
{
TriMesh::Point p = currentTriMesh()->point(vhandles[j]);
vhandles[j] = currentTriMesh()->add_vertex(p);
// DO STORE p, reference may not work since vertex array
// may be relocated after adding a new vertex !
// Mark vertices of failed face as non-manifold
if (currentTriMesh()->has_vertex_status()) {
currentTriMesh()->status(vhandles[j]).set_fixed_nonmanifold(true);
}
}
// add face
OpenMesh::FaceHandle fh = currentTriMesh()->add_face(vhandles);
// Mark failed face as non-manifold
if (currentTriMesh()->has_face_status())
currentTriMesh()->status(fh).set_fixed_nonmanifold(true);
// Mark edges of failed face as non-two-manifold
if (currentTriMesh()->has_edge_status()) {
TriMesh::FaceEdgeIter fe_it = currentTriMesh()->fe_iter(fh);
for(; fe_it; ++fe_it) {
currentTriMesh()->status(fe_it).set_fixed_nonmanifold(true);
}
}
}
} else {
// Handle Polymeshes
if ( !currentPolyMesh() ) return;
for(std::vector::iterator it = invalidFaces_.begin();
it != invalidFaces_.end(); ++it) {
OMVHandles& vhandles = *it;
// double vertices
for (unsigned int j = 0; j < vhandles.size(); ++j)
{
PolyMesh::Point p = currentPolyMesh()->point(vhandles[j]);
vhandles[j] = currentPolyMesh()->add_vertex(p);
// DO STORE p, reference may not work since vertex array
// may be relocated after adding a new vertex !
// Mark vertices of failed face as non-manifold
if (currentPolyMesh()->has_vertex_status()) {
currentPolyMesh()->status(vhandles[j]).set_fixed_nonmanifold(true);
}
}
// add face
OpenMesh::FaceHandle fh = currentPolyMesh()->add_face(vhandles);
// Mark failed face as non-manifold
if (currentPolyMesh()->has_face_status())
currentPolyMesh()->status(fh).set_fixed_nonmanifold(true);
// Mark edges of failed face as non-two-manifold
if (currentPolyMesh()->has_edge_status()) {
PolyMesh::FaceEdgeIter fe_it = currentPolyMesh()->fe_iter(fh);
for(; fe_it; ++fe_it) {
currentPolyMesh()->status(fe_it).set_fixed_nonmanifold(true);
}
}
}
}
// Clear faces
invalidFaces_.clear();
}
//-----------------------------------------------------------------------------
//used materials
const std::vector OBJImporter::usedMaterials(unsigned int _objectID){
if (_objectID >= usedMaterials_.size())
return std::vector();
else
return usedMaterials_[ _objectID ];
}
//-----------------------------------------------------------------------------
void OBJImporter::useMaterial( std::string _materialName ){
while( (int)usedMaterials_.size() - 1 < currentObject() )
usedMaterials_.push_back( std::vector() );
//check that it is not added already
for (unsigned int i=0; i < usedMaterials_[ currentObject() ].size(); i++ )
if ( usedMaterials_[ currentObject() ][i] == _materialName )
return;
usedMaterials_[ currentObject() ].push_back( _materialName );
objectOptions_[ currentObject() ] |= TEXTURE;
}
///used vertices
void OBJImporter::useVertex(int _vertex_index){
while(currentGroup_ >= (int)usedVertices_.size()) {
usedVertices_.push_back(std::map());
}
usedVertices_[currentGroup_].insert(std::pair(_vertex_index,-1));
// while( (int)usedVertices_.size() - 1 < (int) objectOptions_.size() )
// usedVertices_.push_back( std::set() );
//
// usedVertices_[ objectOptions_.size() ].insert( _vertex );
}
//-----------------------------------------------------------------------------