50 #include "OBJImporter.hh"
64 vertices_.push_back( _point );
66 return vertices_.size()-1;
72 if ( vertices_.size() > _index )
73 return vertices_[ _index ];
82 texCoords_.push_back( _coord );
84 return texCoords_.size()-1;
91 normals_.push_back( _normal );
93 return normals_.size()-1;
130 if((
unsigned int)_groupId >= triMeshes_.size()) {
131 std::cerr <<
"Error: Group does not exist!" << std::endl;
145 #ifdef ENABLE_BSPLINECURVE_SUPPORT
151 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
158 std::cerr <<
"Error: Cannot add object. Type is unknown!" << std::endl;
167 return currentGroup_;
175 return polyMeshes_[currentGroup_]->mesh();
183 return triMeshes_[currentGroup_]->mesh();
188 #ifdef ENABLE_BSPLINECURVE_SUPPORT
192 return bSplineCurves_[currentGroup_]->splineCurve();
199 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
203 return bSplineSurfaces_[currentGroup_]->splineSurface();
213 if (isTriangleMesh(_groupId)) {
216 TriMesh* curMesh = triMeshes_[_groupId]->mesh();
222 if(usedVertices_.size() <=
static_cast<size_t>(_groupId))
return;
224 for(std::map<int, VertexHandle>::const_iterator it = usedVertices_[_groupId].begin();
225 it != usedVertices_[_groupId].end(); ++it) {
227 if (it->first >= (
int)vertices_.size()) {
228 std::cerr <<
"Error: Vertex ID too large" << std::endl;
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])));
237 }
else if (isPolyMesh(_groupId)) {
240 PolyMesh* curMesh = polyMeshes_[_groupId]->mesh();
246 if(usedVertices_.size() <=
static_cast<size_t>(_groupId))
return;
248 for(std::map<int, VertexHandle>::const_iterator it = usedVertices_[_groupId].begin();
249 it != usedVertices_[_groupId].end(); ++it) {
251 if (it->first >= (
int)vertices_.size()) {
252 std::cerr <<
"Error: Vertex ID too large" << std::endl;
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])));
273 if ( _texCoordID < (
int) texCoords_.size() ){
280 if ( vertexMapTri_[currentGroup_].find( _vh ) != vertexMapTri_[currentGroup_].end() )
281 currentTriMesh()->set_texcoord2D( vertexMapTri_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
284 std::cerr <<
"Error: TexCoord ID too large" << std::endl;
292 if ( _texCoordID < (
int) texCoords_.size() ){
299 if ( vertexMapPoly_[currentGroup_].find( _vh ) != vertexMapPoly_[currentGroup_].end() )
300 currentPolyMesh()->set_texcoord2D( vertexMapPoly_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
303 std::cerr <<
"Error: TexCoord ID too large" << std::endl;
318 if ( _normalID < (
int) normals_.size() )
320 if ( vertexMapTri_[currentGroup_].find( _index ) != vertexMapTri_[currentGroup_].end() )
322 TriMesh::VertexHandle vh = vertexMapTri_[currentGroup_][_index];
325 currentMesh->set_normal( vh , normal );
326 objectOptions_[ currentGroup_ ] |= NORMALS;
328 storedTriHENormals_[vh] = normal;
332 std::cerr <<
"Error: normal ID too large" << std::endl;
340 if ( _normalID < (
int) normals_.size() )
342 if ( vertexMapPoly_[currentGroup_].find( _index ) != vertexMapPoly_[currentGroup_].end() )
344 PolyMesh::VertexHandle vh = vertexMapPoly_[currentGroup_][_index];
347 currentMesh->set_normal( vh , normal );
348 objectOptions_[ currentGroup_ ] |= NORMALS;
350 storedPolyHENormals_[vh] = normal;
354 std::cerr <<
"Error: normal ID too large" << std::endl;
369 addedFacesTri_[currentGroup_].clear();
371 for (
unsigned int i=0; i < _indices.size(); i++){
373 if ( vertexMapTri_[currentGroup_].find( _indices[i] ) != vertexMapTri_[currentGroup_].end() ){
375 _outTriVertices.push_back( vertexMapTri_[currentGroup_][ _indices[i] ] );
378 std::cerr <<
"Error: cannot add face. undefined index (" << _indices[i] <<
")" << std::endl;
390 invalidFaces_[currentGroup_].push_back(_outTriVertices);
395 addedFacesTri_[currentGroup_].push_back( TriMesh::FaceHandle(n_faces+i) );
402 for (TriMesh::FaceHalfedgeIter fh_iter =
currentTriMesh()->fh_begin(fh);
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())
412 storedTriHENormals_.clear();
423 for (
unsigned int i=0; i < _indices.size(); i++){
425 if ( vertexMapPoly_[currentGroup_].find( _indices[i] ) != vertexMapPoly_[currentGroup_].end() ){
427 _outPolyVertices.push_back( vertexMapPoly_[currentGroup_][ _indices[i] ] );
430 std::cerr <<
"Error: cannot add face. undefined index (" << _indices[i] <<
")" << std::endl;
435 if(!vertexListIsManifold(_outPolyVertices)) {
436 std::cerr <<
"Face consists of multiple occurrences of the same vertex!" << std::endl;
444 invalidFaces_[currentGroup_].push_back(_outPolyVertices);
457 PolyMesh::HalfedgeHandle heh = *fh_iter;
459 std::map<PolyMesh::VertexHandle,PolyMesh::Normal>::iterator iter = storedTriHENormals_.find(vh);
460 if (iter != storedTriHENormals_.end())
463 storedPolyHENormals_.clear();
476 std::vector< TriMesh::VertexHandle > triVertices;
477 std::vector< PolyMesh::VertexHandle > polyVertices;
478 addFace(_indices,fh,triVertices,polyVertices);
484 bool OBJImporter::vertexListIsManifold(
const std::vector<PolyMesh::VertexHandle>& _vertices)
const {
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) {
492 return (check.size() == _vertices.size());
502 std::vector< TriMesh::VertexHandle > triVertices;
503 std::vector< PolyMesh::VertexHandle > polyVertices;
504 if(!
addFace(_indices, fh, triVertices, polyVertices) || !fh.
is_valid())
516 TriMesh::HalfedgeHandle cur_heh =
currentTriMesh()->halfedge_handle( addedFacesTri_[currentGroup_][0] );
517 TriMesh::HalfedgeHandle end_heh =
currentTriMesh()->prev_halfedge_handle(cur_heh);
520 while(
currentTriMesh()->to_vertex_handle(cur_heh) != triVertices[0] && cur_heh != end_heh )
523 for(
unsigned int i=0; i<_face_texcoords.size(); ++i)
525 if ( _face_texcoords[i] < (
int)texCoords_.size() ){
533 std::cerr <<
"Error: cannot set texture coordinates. undefined index." << std::endl;
545 if ( addedFacePoly_.is_valid() ) {
547 PolyMesh::HalfedgeHandle cur_heh =
currentPolyMesh()->halfedge_handle( addedFacePoly_ );
548 PolyMesh::HalfedgeHandle end_heh =
currentPolyMesh()->prev_halfedge_handle(cur_heh);
551 while(
currentPolyMesh()->to_vertex_handle(cur_heh) != polyVertices[0] && cur_heh != end_heh )
554 for(
unsigned int i=0; i<_face_texcoords.size(); ++i)
556 if ( _face_texcoords[i] < (
int)texCoords_.size() ){
564 std::cerr <<
"Error: cannot set texture coordinates. undefined index." << std::endl;
581 if ( materials_.find( _materialName ) != materials_.end() ){
583 Material& mat = materials_[ _materialName ];
590 bool textureAllowed = ! ( objectOptions_[
currentObject() ] & FORCE_NOTEXTURES );
592 if ( textureAllowed ){
595 if (!
currentTriMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
600 for (
unsigned int i=0; i < addedFacesTri_[currentGroup_].size(); i++){
602 if ( mat.has_Kd() ) {
603 bool colorAllowed = ! ( objectOptions_[
currentObject() ] & FORCE_NOCOLOR );
616 currentTriMesh()->set_color(addedFacesTri_[currentGroup_][i], color );
621 bool textureAllowed = ! ( objectOptions_[
currentObject() ] & FORCE_NOTEXTURES );
624 if ( mat.has_Texture() ) {
627 currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = mat.map_Kd_index();
632 currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = 0;
642 if ( materials_.find( _materialName ) != materials_.end() ){
644 Material& mat = materials_[ _materialName ];
651 bool textureAllowed = ! ( objectOptions_[
currentObject() ] & FORCE_NOTEXTURES );
653 if ( textureAllowed ){
655 if (!
currentPolyMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
660 if ( mat.has_Kd() ) {
661 bool colorAllowed = ! ( objectOptions_[
currentObject() ] & FORCE_NOCOLOR );
663 if (
currentPolyMesh()->has_face_colors() && colorAllowed && addedFacePoly_.is_valid() ){
679 bool textureAllowed = ! ( objectOptions_[
currentObject() ] & FORCE_NOTEXTURES );
682 if ( mat.has_Texture() ) {
684 if ( hasTexture(
currentObject() ) && textureAllowed && addedFacePoly_.is_valid())
685 currentPolyMesh()->property(indexProperty, addedFacePoly_) = mat.map_Kd_index();
689 if ( hasTexture(
currentObject() ) && textureAllowed && addedFacePoly_.is_valid())
701 for (
unsigned int i=0; i < objectOptions_.size(); i++){
703 bool isMesh = (objectOptions_[i] & TRIMESH) | (objectOptions_[i] & POLYMESH);
704 bool correctType = objectOptions_[i] & _meshType;
706 if ( isMesh && !correctType )
707 objectOptions_[i] = _meshType;
713 bool OBJImporter::isTriangleMesh(
int _objectID){
714 return objectOptions_[ _objectID ] & TRIMESH;
719 bool OBJImporter::isPolyMesh(
int _objectID){
720 return objectOptions_[ _objectID ] & POLYMESH;
725 bool OBJImporter::isCurve(
int _objectID){
726 return objectOptions_[ _objectID ] & CURVE;
731 bool OBJImporter::isSurface(
int _objectID){
732 return objectOptions_[ _objectID ] & SURFACE;
739 return objectOptions_[ _objectID ] & NORMALS;
744 bool OBJImporter::hasTexture(
int _objectID){
746 return objectOptions_[ _objectID ] & TEXTURE;
751 bool OBJImporter::hasTextureCoords(
int _objectID){
752 return objectOptions_[ _objectID ] & TEXCOORDS;
758 return vertices_.size();
763 unsigned int OBJImporter::n_normals(){
764 return normals_.size();
769 unsigned int OBJImporter::n_texCoords(){
770 return texCoords_.size();
775 unsigned int OBJImporter::objectCount(){
776 return groupNames_.size();
783 if (objectCount() == 0 || objectCount() <= (
unsigned int)_objectID)
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];
791 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
792 else if(bSplineSurfaces_[_objectID] != NULL)
return bSplineSurfaces_[_objectID];
812 void OBJImporter::setPath(QString _path){
820 while((
unsigned int)currentGroup_ >= objectOptions_.size()) {
821 objectOptions_.push_back(NONE);
824 objectOptions_[currentGroup_] = _options;
830 return objectOptions_;
838 if (_id >= objectOptions_.size())
841 return objectOptions_[_id] & _option;
856 int OBJImporter::addGroup(
const QString& _groupName) {
858 QString group = _groupName.trimmed();
859 int id = groupId(group);
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>());
867 triMeshes_.push_back(NULL);
868 polyMeshes_.push_back(NULL);
869 #ifdef ENABLE_BSPLINECURVE_SUPPORT
870 bSplineCurves_.push_back(NULL);
872 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
873 bSplineSurfaces_.push_back(NULL);
875 return groupNames_.size() - 1;
882 int OBJImporter::groupId(
const QString& _groupName)
const {
884 for(
unsigned int i = 0; i < groupNames_.size(); ++i) {
885 if(groupNames_[i] == _groupName.trimmed())
return i;
892 const QString OBJImporter::groupName(
const int _grpId)
const {
894 if((
unsigned int)_grpId < groupNames_.size()) {
895 return groupNames_[_grpId];
902 void OBJImporter::setGroupName(
const int _grp,
const QString& _name) {
904 if((
unsigned int)_grp >= groupNames_.size())
return;
906 groupNames_[_grp] = _name;
911 void OBJImporter::setCurrentGroup(
const int _current) {
913 currentGroup_ = _current;
918 int OBJImporter::currentGroup()
const {
920 return currentGroup_;
929 if(invalidFaces_[currentGroup_].empty())
return;
936 for(std::vector<OMVHandles>::iterator it = invalidFaces_[currentGroup_].begin();
937 it != invalidFaces_[currentGroup_].end(); ++it) {
939 OMVHandles& vhandles = *it;
942 for (
unsigned int j = 0; j < vhandles.size(); ++j)
951 currentTriMesh()->status(vhandles[j]).set_fixed_nonmanifold(
true);
965 for(; fe_it.is_valid(); ++fe_it) {
976 for(std::vector<OMVHandles>::iterator it = invalidFaces_[currentGroup_].begin();
977 it != invalidFaces_[currentGroup_].end(); ++it) {
979 OMVHandles& vhandles = *it;
982 for (
unsigned int j = 0; j < vhandles.size(); ++j)
1005 for(; fe_it.is_valid(); ++fe_it) {
1013 invalidFaces_[currentGroup_].clear();
1018 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1019 void OBJImporter::setCurveGroupId(
const unsigned int _count,
const int _id) {
1020 curvesMap_[_count] = _id;
1026 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1027 int OBJImporter::getCurveGroupId(
const unsigned int _count) {
1028 return curvesMap_[_count];
1034 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1035 void OBJImporter::setCurveParentId(
const int _curveGroup,
const int _parentGroup) {
1036 curveParentGroupMap_[_curveGroup] = _parentGroup;
1042 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1043 int OBJImporter::getCurveParentId(
const int _curveGroup) {
1044 return curveParentGroupMap_[_curveGroup];
1050 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1051 void OBJImporter::setSurfaceGroupId(
const unsigned int _count,
const int _id) {
1052 surfacesMap_[_count] = _id;
1058 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1059 int OBJImporter::getSurfaceGroupId(
const unsigned int _count) {
1060 return surfacesMap_[_count];
1066 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1067 void OBJImporter::setSurfaceParentId(
const int _surfaceGroup,
const int _parentGroup) {
1068 surfaceParentGroupMap_[_surfaceGroup] = _parentGroup;
1074 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1075 int OBJImporter::getSurfaceParentId(
const int _surfaceGroup) {
1076 return surfaceParentGroupMap_[_surfaceGroup];
1085 if (_objectID >= usedMaterials_.size())
1086 return std::vector<std::string>();
1088 return usedMaterials_[ _objectID ];
1093 void OBJImporter::useMaterial( std::string _materialName ){
1096 usedMaterials_.push_back( std::vector<std::string>() );
1099 for (
unsigned int i=0; i < usedMaterials_[
currentObject() ].size(); i++ )
1100 if ( usedMaterials_[
currentObject() ][i] == _materialName )
1103 usedMaterials_[
currentObject() ].push_back( _materialName );
1111 while(currentGroup_ >= (
int)usedVertices_.size()) {
1112 usedVertices_.push_back(std::map<int,VertexHandle>());
1115 usedVertices_[currentGroup_].insert(std::pair<int,VertexHandle>(_vertex_index,-1));
Add colors to mesh item (vertices/faces/edges)
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
QString path()
Path of the OBJ file.
void addMaterial(std::string _materialName)
Add a material.
void setObject(BaseObject *_object, int _groupId)
add an object
~OBJImporter()
base class needs virtual destructor
std::vector< ObjectOptions > & objectOptions()
Object Options for all objects.
Kernel::FaceEdgeIter FaceEdgeIter
Circulator.
bool hasOption(unsigned int _id, ObjectOptions _option)
check if object with given id has given option
PolyMesh * currentPolyMesh()
get a pointer to the active polyMesh
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
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.
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Kernel::Point Point
Coordinate type.
MaterialList & materials()
return all loaded materials
bool hasNormals(int _objectID)
Query Object Options.
void setDegreeV(int _degree)
set degree V direction
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
void setDegreeU(int _degree)
set degree
unsigned int n_vertices()
Global Properties.
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
Add 2D texture coordinates (vertices, halfedges)
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
Vec3f vertex(unsigned int _index)
get vertex with given index
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
void setNormal(int _index, int _normalID)
set vertex normal
void addUsedVertices(int _groupId)
add all vertices that are used to the mesh (in correct order)
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
Handle for a face entity.
TriMesh * currentTriMesh()
get a pointer to the active triMesh
BaseObject * object(int _objectID)
return object with given index
Add normals to mesh item (vertices/faces)
int currentObject()
get id of the active object
void setObjectOptions(ObjectOptions _options)
BaseObjectData * baseObjectData(BaseObject *_object)
Cast an BaseObject to a BaseObjectData if possible.
int addTexCoord(const Vec2f &_coord)
add texture coordinates
BSplineCurveObject * bsplineCurveObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineCurveObject if possible.
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
int degreeU()
get current degree
void setObjectName(int _objectID, QString _name)
change the name of an object
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
void useVertex(int _vertex_index)
used vertices
int degreeV()
get current degree
BSplineSurfaceObject * bsplineSurfaceObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineSurfaceObject if possible.
int addNormal(const Vec3f &_normal)
add a normal