44 #include "OBJImporter.hh" 58 vertices_.push_back( _point );
60 return vertices_.size()-1;
66 if ( vertices_.size() > _index )
67 return vertices_[ _index ];
76 texCoords_.push_back( _coord );
78 return texCoords_.size()-1;
85 normals_.push_back( _normal );
87 return normals_.size()-1;
124 if((
unsigned int)_groupId >= triMeshes_.size()) {
125 std::cerr <<
"Error: Group does not exist!" << std::endl;
139 #ifdef ENABLE_BSPLINECURVE_SUPPORT 145 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 152 std::cerr <<
"Error: Cannot add object. Type is unknown!" << std::endl;
161 return currentGroup_;
169 return polyMeshes_[currentGroup_]->mesh();
177 return triMeshes_[currentGroup_]->mesh();
182 #ifdef ENABLE_BSPLINECURVE_SUPPORT 186 return bSplineCurves_[currentGroup_]->splineCurve();
193 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 197 return bSplineSurfaces_[currentGroup_]->splineSurface();
207 if (isTriangleMesh(_groupId)) {
210 TriMesh* curMesh = triMeshes_[_groupId]->mesh();
216 if(usedVertices_.size() <=
static_cast<size_t>(_groupId))
return;
218 for(std::map<int, VertexHandle>::const_iterator it = usedVertices_[_groupId].begin();
219 it != usedVertices_[_groupId].end(); ++it) {
221 if (it->first >= (
int)vertices_.size()) {
222 std::cerr <<
"Error: Vertex ID too large" << std::endl;
226 if (vertexMapTri_[_groupId].find(it->first) == vertexMapTri_[_groupId].end()) {
227 vertexMapTri_[_groupId].insert(std::pair<int, TriMesh::VertexHandle>(it->first, curMesh->
add_vertex((
TriMesh::Point)vertices_[it->first])));
231 }
else if (isPolyMesh(_groupId)) {
234 PolyMesh* curMesh = polyMeshes_[_groupId]->mesh();
240 if(usedVertices_.size() <=
static_cast<size_t>(_groupId))
return;
242 for(std::map<int, VertexHandle>::const_iterator it = usedVertices_[_groupId].begin();
243 it != usedVertices_[_groupId].end(); ++it) {
245 if (it->first >= (
int)vertices_.size()) {
246 std::cerr <<
"Error: Vertex ID too large" << std::endl;
250 if (vertexMapPoly_[_groupId].find(it->first) == vertexMapPoly_[_groupId].end()) {
251 vertexMapPoly_[_groupId].insert(std::pair<int, PolyMesh::VertexHandle>(it->first, curMesh->
add_vertex((
PolyMesh::Point)vertices_[it->first])));
267 if ( _texCoordID < (
int) texCoords_.size() ){
274 if ( vertexMapTri_[currentGroup_].find( _vh ) != vertexMapTri_[currentGroup_].end() )
275 currentTriMesh()->set_texcoord2D( vertexMapTri_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
278 std::cerr <<
"Error: TexCoord ID too large" << std::endl;
286 if ( _texCoordID < (
int) texCoords_.size() ){
293 if ( vertexMapPoly_[currentGroup_].find( _vh ) != vertexMapPoly_[currentGroup_].end() )
294 currentPolyMesh()->set_texcoord2D( vertexMapPoly_[currentGroup_][_vh], texCoords_[ _texCoordID ] );
297 std::cerr <<
"Error: TexCoord ID too large" << std::endl;
312 if ( _normalID < (
int) normals_.size() )
314 if ( vertexMapTri_[currentGroup_].find( _index ) != vertexMapTri_[currentGroup_].end() )
316 TriMesh::VertexHandle vh = vertexMapTri_[currentGroup_][_index];
317 TriMesh::Normal normal =
static_cast<TriMesh::Normal
>( normals_[ _normalID ] );
319 currentMesh->set_normal( vh , normal );
320 objectOptions_[ currentGroup_ ] |= NORMALS;
322 storedTriHENormals_[vh] = normal;
326 std::cerr <<
"Error: normal ID too large" << std::endl;
334 if ( _normalID < (
int) normals_.size() )
336 if ( vertexMapPoly_[currentGroup_].find( _index ) != vertexMapPoly_[currentGroup_].end() )
338 PolyMesh::VertexHandle vh = vertexMapPoly_[currentGroup_][_index];
341 currentMesh->set_normal( vh , normal );
342 objectOptions_[ currentGroup_ ] |= NORMALS;
344 storedPolyHENormals_[vh] = normal;
348 std::cerr <<
"Error: normal ID too large" << std::endl;
363 addedFacesTri_[currentGroup_].clear();
365 for (
unsigned int i=0; i < _indices.size(); i++){
367 if ( vertexMapTri_[currentGroup_].find( _indices[i] ) != vertexMapTri_[currentGroup_].end() ){
369 _outTriVertices.push_back( vertexMapTri_[currentGroup_][ _indices[i] ] );
372 std::cerr <<
"Error: cannot add face. undefined index (" << _indices[i] <<
")" << std::endl;
384 invalidFaces_[currentGroup_].push_back(_outTriVertices);
389 addedFacesTri_[currentGroup_].push_back( TriMesh::FaceHandle(n_faces+i) );
400 TriMesh::HalfedgeHandle heh = *fh_iter;
401 TriMesh::VertexHandle vh =
currentTriMesh()->to_vertex_handle(heh);
402 std::map<TriMesh::VertexHandle,TriMesh::Normal>::iterator iter = storedTriHENormals_.find(vh);
403 if (iter != storedTriHENormals_.end())
406 storedTriHENormals_.clear();
417 for (
unsigned int i=0; i < _indices.size(); i++){
419 if ( vertexMapPoly_[currentGroup_].find( _indices[i] ) != vertexMapPoly_[currentGroup_].end() ){
421 _outPolyVertices.push_back( vertexMapPoly_[currentGroup_][ _indices[i] ] );
424 std::cerr <<
"Error: cannot add face. undefined index (" << _indices[i] <<
")" << std::endl;
429 if(!vertexListIsManifold(_outPolyVertices)) {
430 std::cerr <<
"Face consists of multiple occurrences of the same vertex!" << std::endl;
438 invalidFaces_[currentGroup_].push_back(_outPolyVertices);
451 PolyMesh::HalfedgeHandle heh = *fh_iter;
453 std::map<PolyMesh::VertexHandle,PolyMesh::Normal>::iterator iter = storedTriHENormals_.find(vh);
454 if (iter != storedTriHENormals_.end())
457 storedPolyHENormals_.clear();
470 std::vector< TriMesh::VertexHandle > triVertices;
471 std::vector< PolyMesh::VertexHandle > polyVertices;
472 addFace(_indices,fh,triVertices,polyVertices);
478 bool OBJImporter::vertexListIsManifold(
const std::vector<PolyMesh::VertexHandle>& _vertices)
const {
480 std::set<PolyMesh::VertexHandle> check;
481 for(std::vector<PolyMesh::VertexHandle>::const_iterator v_it = _vertices.begin();
482 v_it != _vertices.end(); ++v_it) {
486 return (check.size() == _vertices.size());
496 std::vector< TriMesh::VertexHandle > triVertices;
497 std::vector< PolyMesh::VertexHandle > polyVertices;
498 if(!
addFace(_indices, fh, triVertices, polyVertices) || !fh.
is_valid())
510 TriMesh::HalfedgeHandle cur_heh =
currentTriMesh()->halfedge_handle( addedFacesTri_[currentGroup_][0] );
511 TriMesh::HalfedgeHandle end_heh =
currentTriMesh()->prev_halfedge_handle(cur_heh);
514 while(
currentTriMesh()->to_vertex_handle(cur_heh) != triVertices[0] && cur_heh != end_heh )
517 for(
unsigned int i=0; i<_face_texcoords.size(); ++i)
519 if ( _face_texcoords[i] < (
int)texCoords_.size() ){
527 std::cerr <<
"Error: cannot set texture coordinates. undefined index." << std::endl;
539 if ( addedFacePoly_.is_valid() ) {
541 PolyMesh::HalfedgeHandle cur_heh =
currentPolyMesh()->halfedge_handle( addedFacePoly_ );
542 PolyMesh::HalfedgeHandle end_heh =
currentPolyMesh()->prev_halfedge_handle(cur_heh);
545 while(
currentPolyMesh()->to_vertex_handle(cur_heh) != polyVertices[0] && cur_heh != end_heh )
548 for(
unsigned int i=0; i<_face_texcoords.size(); ++i)
550 if ( _face_texcoords[i] < (
int)texCoords_.size() ){
558 std::cerr <<
"Error: cannot set texture coordinates. undefined index." << std::endl;
575 if ( materials_.find( _materialName ) != materials_.end() ){
577 Material& mat = materials_[ _materialName ];
586 bool textureAllowed = ! ( objectOptions_[
currentGroup() ] & FORCE_NOTEXTURES );
588 if ( textureAllowed ){
591 if (!
currentTriMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
623 float shininess = mat.Ns();
627 if (mat.has_illum()) {
632 for (
unsigned int i=0; i < addedFacesTri_[currentGroup_].size(); i++){
634 if ( mat.has_Kd() ) {
635 bool colorAllowed = ! ( objectOptions_[
currentGroup() ] & FORCE_NOCOLOR );
647 currentTriMesh()->set_color(addedFacesTri_[currentGroup_][i], color );
652 bool textureAllowed = ! ( objectOptions_[
currentGroup() ] & FORCE_NOTEXTURES );
655 if ( mat.has_Texture() ) {
658 currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = mat.map_Kd_index();
663 currentTriMesh()->property(indexProperty, addedFacesTri_[currentGroup_][i]) = 0;
674 if ( materials_.find( _materialName ) != materials_.end() ){
676 Material& mat = materials_[ _materialName ];
685 bool textureAllowed = ! ( objectOptions_[
currentGroup() ] & FORCE_NOTEXTURES );
687 if ( textureAllowed ){
689 if (!
currentPolyMesh()->get_property_handle(indexProperty,TEXTUREINDEX) )
694 if ( mat.has_Kd() ) {
695 bool colorAllowed = ! ( objectOptions_[
currentGroup() ] & FORCE_NOCOLOR );
697 if (
currentPolyMesh()->has_face_colors() && colorAllowed && addedFacePoly_.is_valid() ){
736 float shininess = mat.Ns();
740 if (mat.has_illum()) {
744 bool textureAllowed = ! ( objectOptions_[
currentGroup() ] & FORCE_NOTEXTURES );
747 if ( mat.has_Texture() ) {
749 if ( hasTexture(
currentGroup() ) && textureAllowed && addedFacePoly_.is_valid())
750 currentPolyMesh()->property(indexProperty, addedFacePoly_) = mat.map_Kd_index();
754 if ( hasTexture(
currentGroup() ) && textureAllowed && addedFacePoly_.is_valid())
767 bool isMesh = (objectOptions_[currentGroup_] & TRIMESH) | (objectOptions_[currentGroup_] & POLYMESH);
768 bool correctType = objectOptions_[currentGroup_] & _meshType;
770 if ( isMesh && !correctType ) {
771 ObjectOptions options = objectOptions_[currentGroup_];
777 options |= _meshType;
779 objectOptions_[currentGroup_] = options;
786 bool OBJImporter::isTriangleMesh(
int _objectID){
787 return objectOptions_[ _objectID ] & TRIMESH;
792 bool OBJImporter::isPolyMesh(
int _objectID){
793 return objectOptions_[ _objectID ] & POLYMESH;
798 bool OBJImporter::isCurve(
int _objectID){
799 return objectOptions_[ _objectID ] & CURVE;
804 bool OBJImporter::isSurface(
int _objectID){
805 return objectOptions_[ _objectID ] & SURFACE;
808 bool OBJImporter::isNone(
int _objectID) {
809 return objectOptions_[ _objectID ] == NONE;
816 return objectOptions_[ _objectID ] & NORMALS;
821 bool OBJImporter::hasTexture(
int _objectID){
823 return objectOptions_[ _objectID ] & TEXTURE;
828 bool OBJImporter::hasTextureCoords(
int _objectID){
829 return objectOptions_[ _objectID ] & TEXCOORDS;
835 objectOptions_[ currentGroup_ ] |= _option;
840 objectOptions_[ _groupId ] |= _option;
846 return vertices_.size();
851 unsigned int OBJImporter::n_normals(){
852 return normals_.size();
857 unsigned int OBJImporter::n_texCoords(){
858 return texCoords_.size();
864 return groupNames_.size();
874 if(triMeshes_[_groupId] != NULL)
return triMeshes_[_groupId];
875 else if(polyMeshes_[_groupId] != NULL)
return polyMeshes_[_groupId];
876 #ifdef ENABLE_BSPLINECURVE_SUPPORT 877 else if(bSplineCurves_[_groupId] != NULL)
return bSplineCurves_[_groupId];
879 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 880 else if(bSplineSurfaces_[_groupId] != NULL)
return bSplineSurfaces_[_groupId];
900 void OBJImporter::setPath(QString _path){
908 while((
unsigned int)currentGroup_ >= objectOptions_.size()) {
909 objectOptions_.push_back(NONE);
912 objectOptions_[currentGroup_] = _options;
918 return objectOptions_.empty();
926 if (_id >= objectOptions_.size())
929 return objectOptions_[_id] & _option;
944 int OBJImporter::addGroup(
const QString& _groupName) {
946 QString group = _groupName.trimmed();
947 int id = groupId(group);
949 groupNames_.push_back(group);
950 vertexMapTri_.push_back(std::map<int,TriMesh::VertexHandle>());
951 vertexMapPoly_.push_back(std::map<int,TriMesh::VertexHandle>());
952 invalidFaces_.push_back(std::vector< OMVHandles >());
953 addedFacesTri_.push_back(std::vector< TriMesh::FaceHandle>());
955 triMeshes_.push_back(NULL);
956 polyMeshes_.push_back(NULL);
957 #ifdef ENABLE_BSPLINECURVE_SUPPORT 958 bSplineCurves_.push_back(NULL);
960 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 961 bSplineSurfaces_.push_back(NULL);
963 return groupNames_.size() - 1;
970 int OBJImporter::groupId(
const QString& _groupName)
const {
972 for(
unsigned int i = 0; i < groupNames_.size(); ++i) {
973 if(groupNames_[i] == _groupName.trimmed())
return i;
980 const QString OBJImporter::groupName(
const int _grpId)
const {
982 if((
unsigned int)_grpId < groupNames_.size()) {
983 return groupNames_[_grpId];
990 void OBJImporter::setGroupName(
const int _grp,
const QString& _name) {
992 if((
unsigned int)_grp >= groupNames_.size())
return;
994 groupNames_[_grp] = _name;
999 void OBJImporter::setCurrentGroup(
const int _current) {
1001 currentGroup_ = _current;
1008 return currentGroup_;
1017 if(invalidFaces_[currentGroup_].empty())
return;
1024 for(std::vector<OMVHandles>::iterator it = invalidFaces_[currentGroup_].begin();
1025 it != invalidFaces_[currentGroup_].end(); ++it) {
1027 OMVHandles& vhandles = *it;
1030 for (
unsigned int j = 0; j < vhandles.size(); ++j)
1039 currentTriMesh()->status(vhandles[j]).set_fixed_nonmanifold(
true);
1053 for(; fe_it.is_valid(); ++fe_it) {
1064 for(std::vector<OMVHandles>::iterator it = invalidFaces_[currentGroup_].begin();
1065 it != invalidFaces_[currentGroup_].end(); ++it) {
1067 OMVHandles& vhandles = *it;
1070 for (
unsigned int j = 0; j < vhandles.size(); ++j)
1093 for(; fe_it.is_valid(); ++fe_it) {
1101 invalidFaces_[currentGroup_].clear();
1106 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1107 void OBJImporter::setCurveGroupId(
const unsigned int _count,
const int _id) {
1108 curvesMap_[_count] = _id;
1114 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1115 int OBJImporter::getCurveGroupId(
const unsigned int _count) {
1116 return curvesMap_[_count];
1122 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1123 void OBJImporter::setCurveParentId(
const int _curveGroup,
const int _parentGroup) {
1124 curveParentGroupMap_[_curveGroup] = _parentGroup;
1130 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1131 int OBJImporter::getCurveParentId(
const int _curveGroup) {
1132 return curveParentGroupMap_[_curveGroup];
1138 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1139 void OBJImporter::setSurfaceGroupId(
const unsigned int _count,
const int _id) {
1140 surfacesMap_[_count] = _id;
1146 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1147 int OBJImporter::getSurfaceGroupId(
const unsigned int _count) {
1148 return surfacesMap_[_count];
1154 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1155 void OBJImporter::setSurfaceParentId(
const int _surfaceGroup,
const int _parentGroup) {
1156 surfaceParentGroupMap_[_surfaceGroup] = _parentGroup;
1162 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1163 int OBJImporter::getSurfaceParentId(
const int _surfaceGroup) {
1164 return surfaceParentGroupMap_[_surfaceGroup];
1173 if (_objectID >= usedMaterials_.size())
1174 return std::vector<std::string>();
1176 return usedMaterials_[ _objectID ];
1181 void OBJImporter::useMaterial( std::string _materialName ){
1183 while( (
int)usedMaterials_.size() - 1 <
currentGroup() )
1184 usedMaterials_.push_back( std::vector<std::string>() );
1187 for (
unsigned int i=0; i < usedMaterials_[
currentGroup() ].size(); i++ )
1188 if ( usedMaterials_[
currentGroup() ][i] == _materialName )
1191 usedMaterials_[
currentGroup() ].push_back( _materialName );
1200 while(currentGroup_ >= (
int)usedVertices_.size()) {
1201 usedVertices_.push_back(std::map<int,VertexHandle>());
1204 usedVertices_[currentGroup_].insert(std::pair<int,VertexHandle>(_vertex_index,-1));
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
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.
QString path()
Path of the OBJ file.
void setObjectName(int _objectID, QString _name)
change the name of an object
BaseObject * object(int _groupId)
return object for the given group
void set_diffuse_color(const Vec4f &_d)
set the diffuse color.
TriMesh * currentTriMesh()
get a pointer to the active triMesh
Kernel::Point Point
Coordinate type.
void set_specular_color(const Vec4f &_s)
set the specular color
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
Kernel::Color Color
Color type.
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
MaterialNode * materialNode()
get a pointer to the materialnode
int addTexCoord(const Vec2f &_coord)
add texture coordinates
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
void setDegreeU(int _degree)
set degree
Vec3f vertex(unsigned int _index)
get vertex with given index
void set_emission(const Vec4f &_c)
set emission ( same as set_base_color(const Vec4f& _c) )
bool noOptions()
Return true if the importer has no options stored.
void addUsedVertices(int _groupId)
add all vertices that are used to the mesh (in correct order)
void setObject(BaseObject *_object, int _groupId)
add an object
int degreeV()
get current degree
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
int currentGroup()
Get the id of the current group.
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
BSplineCurveObject * bsplineCurveObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineCurveObject if possible.
unsigned int groupCount()
Number of groups currently stored in the importer.
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
void addMaterial(std::string _materialName)
Add a material.
MaterialList & materials()
return all loaded materials
Kernel::FaceEdgeIter FaceEdgeIter
Circulator.
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
void useVertex(int _vertex_index)
used vertices
int degreeU()
get current degree
void setDegreeV(int _degree)
set degree V direction
void set_indexOfRefraction(double _m)
set index of refraction
Handle for a face entity.
unsigned int n_vertices()
Global Properties.
void setObjectOptions(ObjectOptions _options)
BaseObjectData * baseObjectData(BaseObject *_object)
Cast an BaseObject to a BaseObjectData if possible.
PolyMesh * currentPolyMesh()
get a pointer to the active polyMesh
void set_shininess(float _s)
set shininess
void set_refractive(bool _r)
set refractive flag
void set_ambient_color(const Vec4f &_a)
set the ambient color.
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
int addNormal(const Vec3f &_normal)
add a normal
bool is_valid() const
The handle is valid iff the index is not negative.
void setNormal(int _index, int _normalID)
set vertex normal
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
bool hasOption(unsigned int _id, ObjectOptions _option)
check if object with given id has given option
void setOption(ObjectOptionsE _option)
Set Object Option.
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
BSplineSurfaceObject * bsplineSurfaceObject(BaseObjectData *_object)
Cast an BaseObject to a BSplineSurfaceObject if possible.
~OBJImporter()
base class needs virtual destructor
bool hasNormals(int _objectID)
Query Object Options.