43 #include <ACG/GL/GLState.hh> 48 #include <OpenMesh/Core/IO/IOManager.hh> 50 #include <OpenFlipper/Utils/Memory/RAMInfo.hh> 56 #include <ACG/Utils/SmartPointer.hh> 60 #define TYPEAUTODETECT 0 63 #define TYPETRIANGLE 3 65 using namespace Utils;
70 void remove_duplicated_vertices(VHandles& _indices)
72 VHandles::iterator endIter = _indices.end();
73 for (VHandles::iterator iter = _indices.begin(); iter != endIter; ++iter)
74 endIter = std::remove(iter+1, endIter, *(iter));
76 _indices.erase(endIter,_indices.end());
89 saveFaceColorOverride_(0),
95 saveCreateTexFolder_(0),
96 savePrecisionLabel_(0),
98 saveDefaultButton_(0),
106 loadDefaultButton_(0),
107 forceTriangleMesh_(false),
108 forcePolyMesh_(false),
109 textureIndexPropFetched_(false),
122 return QString( tr(
"Alias/Wavefront ( *.obj )") );
128 return QString( tr(
"Alias/Wavefront ( *.obj )") );
136 #ifdef ENABLE_BSPLINECURVE_SUPPORT 140 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 149 bool FileOBJPlugin::readMaterial(QString _filename,
OBJImporter& _importer)
152 static QString keyWrd;
153 static QString textureName;
158 static QString matName;
162 static float f1,f2,f3;
167 static bool insideDefintion;
168 insideDefintion =
false;
169 static int textureId;
174 QFile matFile(_filename);
175 if (!matFile.open(QFile::ReadOnly))
177 emit log(
LOGERR, tr(
"readMaterial : cannot open file %1").arg(_filename));
181 QTextStream matStream(&matFile);
182 if ( matStream.status()!=QTextStream::Ok ){
183 emit log(
LOGERR, tr(
"readMaterial : cannot open stream %1").arg(_filename) );
191 while( matStream.status() == QTextStream::Ok && !matStream.atEnd() )
193 line = matStream.readLine();
194 if ( matStream.status() != QTextStream::Ok ){
195 emit log(
LOGERR, tr(
"readMaterial : Warning! Could not read file properly!"));
199 if ( line.isEmpty() )
202 QTextStream stream(&line);
206 if( ( line[0].isSpace() && line[0] != QLatin1Char(
'\t') ) || line[0] == QLatin1Char(
'#') )
208 if (insideDefintion && !matName.isEmpty() && mat.is_valid())
210 _importer.
materials()[matName.toStdString()] = mat;
215 else if (keyWrd == QLatin1String(
"newmtl"))
218 insideDefintion =
true;
221 else if (keyWrd == QLatin1String(
"Kd"))
223 f1 = getFloat(stream);
224 f2 = getFloat(stream);
225 f3 = getFloat(stream);
227 if( stream.status()==QTextStream::Ok )
228 mat.set_Kd(f1,f2,f3);
231 else if (keyWrd == QLatin1String(
"Ka"))
233 f1 = getFloat(stream);
234 f2 = getFloat(stream);
235 f3 = getFloat(stream);
237 if( stream.status()==QTextStream::Ok )
238 mat.set_Ka(f1,f2,f3);
241 else if (keyWrd == QLatin1String(
"Ks"))
243 f1 = getFloat(stream);
244 f2 = getFloat(stream);
245 f3 = getFloat(stream);
247 if( stream.status()==QTextStream::Ok )
248 mat.set_Ks(f1,f2,f3);
251 else if (keyWrd == QLatin1String(
"Ke"))
253 f1 = getFloat(stream);
254 f2 = getFloat(stream);
255 f3 = getFloat(stream);
257 if( stream.status()==QTextStream::Ok )
258 mat.set_Ke(f1,f2,f3);
262 else if (keyWrd == QLatin1String(
"illum"))
266 if(stream.status() == QTextStream::Ok)
270 else if (keyWrd == QLatin1String(
"Ns"))
272 f1 = getFloat(stream);
274 if(stream.status() == QTextStream::Ok)
278 else if (keyWrd == QLatin1String(
"Ni"))
280 f1 = getFloat(stream);
282 if(stream.status() == QTextStream::Ok)
286 else if (keyWrd == QLatin1String(
"Tr"))
288 f1 = getFloat(stream);
290 if(stream.status() == QTextStream::Ok)
294 else if (keyWrd == QLatin1String(
"d"))
297 f1 = getFloat(stream);
299 if(stream.status() == QTextStream::Ok && !mat.has_Tr())
303 else if (keyWrd == QLatin1String(
"map_"))
312 else if (keyWrd == QLatin1String(
"map_Kd") ) {
315 textureName = stream.readLine();
316 textureName = textureName.trimmed();
317 if ( ! textureName.isEmpty() )
318 mat.set_map_Kd( textureName.toStdString(), textureId++ );
321 if ( matStream.status() == QTextStream::Ok && insideDefintion && mat.is_valid() && !matName.isEmpty())
322 _importer.
materials()[matName.toStdString()] = mat;
325 emit log( tr(
"%1 materials loaded.").arg( _importer.
materials().size() ) );
332 void FileOBJPlugin::createAllGroupObjects(
OBJImporter& _importer) {
334 for(
unsigned int i = 0; i < _importer.numGroups(); ++i) {
337 QString
name = _importer.groupName(i);
340 if ( _importer.isTriangleMesh( i ) ){
352 object->setPath(_importer.
path());
353 object->setName(name);
356 }
else if (_importer.isPolyMesh( i )) {
367 object->setPath(_importer.
path());
368 object->setName(name);
372 #ifdef ENABLE_BSPLINECURVE_SUPPORT 374 else if (_importer.isCurve( i )) {
385 object->setPath(_importer.
path());
386 object->setName(name);
392 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 394 else if (_importer.isSurface( i )) {
405 object->setPath(_importer.
path());
406 object->setName(name);
413 if (OpenFlipper::Options::gui() && loadOptions_ != 0) {
415 if (!loadFaceColor_->isChecked())
416 _importer.
setOption(OBJImporter::FORCE_NOCOLOR, i);
418 if (!loadNormals_->isChecked())
419 _importer.
setOption(OBJImporter::FORCE_NONORMALS, i);
421 if (!loadTexCoords_->isChecked() || !loadTextures_->isChecked())
422 _importer.
setOption(OBJImporter::FORCE_NOTEXTURES, i);
432 QString n = fi.baseName();
434 _name = n.trimmed() +
".obj";
438 template <
class MeshT>
442 if (_mesh.has_vertex_texcoords2D()) {
445 if (!_mesh.get_property_handle(oldVertexCoords,
"Original Per Vertex Texture Coords"))
446 _mesh.add_property(oldVertexCoords,
"Original Per Vertex Texture Coords");
448 for (
typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
449 _mesh.property(oldVertexCoords, *v_it) = _mesh.texcoord2D(*v_it);
454 if (_mesh.has_halfedge_texcoords2D()) {
457 if (!_mesh.get_property_handle(oldHalfedgeCoords,
"Original Per Face Texture Coords"))
458 _mesh.add_property(oldHalfedgeCoords,
"Original Per Face Texture Coords");
460 for (
typename MeshT::HalfedgeIter he_it = _mesh.halfedges_begin(); he_it != _mesh.halfedges_end(); ++he_it)
461 _mesh.property(oldHalfedgeCoords, *he_it) = _mesh.texcoord2D(*he_it);
468 void FileOBJPlugin::addTextures(
OBJImporter& _importer,
int _objectID ){
478 std::map< int,int > newMapping;
482 const std::vector<std::string> matNames = _importer.
usedMaterials( _objectID );
484 for (
unsigned int i=0; i < matNames.size(); i++){
486 Material& material = _importer.
materials()[ matNames[i] ];
490 QString textureBlock = QString( material.map_Kd().c_str());
494 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 495 QStringList options = textureBlock.split(
" ",QString::SkipEmptyParts);
497 QStringList options = textureBlock.split(
" ",Qt::SkipEmptyParts);
500 while ( options.size() > 1 ) {
501 if ( options[0] ==
"-blendu" ) {
504 }
else if ( options[0] ==
"-blendv" ) {
507 }
else if ( options[0] ==
"-cc" ) {
510 }
else if ( options[0] ==
"-clamp" ) {
513 }
else if ( options[0] ==
"-mm" ) {
517 }
else if ( options[0] ==
"-o" ) {
522 }
else if ( options[0] ==
"-s" ) {
527 }
else if ( options[0] ==
"-t" ) {
532 }
else if ( options[0] ==
"-texres" ) {
540 QString fullName = _importer.
path() + QDir::separator() + options.join(
" ");
542 QFileInfo info(fullName);
543 if ( info.exists() ) {
544 emit addMultiTexture(
"OBJ Data", info.baseName().trimmed(), fullName,
object->id(), textureId );
546 emit log(
LOGWARN, tr(
"Unable to load texture image %1").arg( QString(material.map_Kd().c_str()) ) );
547 addMultiTexture(
"OBJ Data",
"Unknown Texture image " + QString::number(textureId),
"unknown.png", object->
id(), textureId );
550 newMapping[ material.map_Kd_index() ] = textureId;
564 PolyMesh::FaceIter f_it;
565 PolyMesh::FaceIter f_end = mesh.faces_end();
567 if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
570 for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
571 mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
585 TriMesh::FaceIter f_it;
586 TriMesh::FaceIter f_end = mesh.faces_end();
588 if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
591 for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
592 mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
601 void FileOBJPlugin::readOBJFile(QByteArray& _bufferedFile, QString _filename,
OBJImporter& _importer)
603 QString path = QFileInfo(_filename).absolutePath();
604 ptr::shared_ptr<QTextStream> streamPointer;
605 ptr::shared_ptr<QFile> sourceFile;
608 if (_bufferedFile.isNull())
610 sourceFile.reset(
new QFile(_filename) );
611 if(!sourceFile->open(QFile::ReadOnly))
613 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1").arg(_filename) );
618 streamPointer.reset(
new QTextStream(sourceFile.get()));
622 streamPointer.reset(
new QTextStream(&_bufferedFile));
624 QTextStream input(streamPointer->device());
627 QTextStream lineData;
629 if ( input.status() != QTextStream::Ok){
630 emit log(
LOGERR, tr(
"readOBJFile : cannot read file %1 is the file corrupt?").arg(_filename) );
634 QString currentFileName = QFileInfo(_filename).fileName() ;
636 ReaderMode mode = NONE;
640 QString nextKeyWrd = QLatin1String(
"");
642 #ifdef ENABLE_BSPLINECURVE_SUPPORT 643 unsigned int curveCount = 0;
646 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 647 unsigned int surfaceCount = 0;
653 std::vector<VertexHandle> vhandles;
654 std::vector<int> face_texcoords;
656 QString lastMaterial;
658 #if defined (ENABLE_BSPLINECURVE_SUPPORT) || defined (ENABLE_BSPLINESURFACE_SUPPORT) 659 std::vector< int > cpIndices;
660 std::vector< double > knotsU,knotsV;
666 int currentVertexCount = 0;
669 int currentTextureCoordCount = 0;
672 int currentNormalCount = 0;
675 bool inGroup =
false;
677 bool firstFace =
true;
679 _importer.setPath( path );
682 _importer.setGroupName(0, currentFileName);
685 createAllGroupObjects(_importer);
687 bool bSuppNoVertCoord =
false;
688 bool bSuppTooManyTexCoord =
false;
689 bool bSuppTooManyNormal =
false;
690 bool bSuppErrorSettingTexCoord =
false;
692 while( !input.atEnd() )
694 line=input.readLine();
695 if ( input.status() == QTextStream::ReadCorruptData ){
696 emit log(
LOGERR, tr(
"readOBJFile : Warning! Could not read file properly!"));
701 line = line.trimmed();
704 if ( line.isEmpty() || line[0] == QLatin1Char(
'#') || line[0].isSpace() ) {
708 stream.setString(&line,QIODevice::ReadOnly);
712 if (nextKeyWrd == QLatin1String(
""))
716 nextKeyWrd = QLatin1String(
"");
720 if (mode == NONE && keyWrd == QLatin1String(
"mtllib"))
725 matString = stream.readLine();
727 QString matFile = path + QDir::separator() + matString.trimmed();
729 emit log( tr(
"Loading material file: %1").arg( matFile ) );
731 readMaterial( matFile, _importer );
735 else if (mode == NONE && keyWrd == QLatin1String(
"usemtl"))
740 emit log(
LOGERR, tr(
"Warning! Material '%1' not defined in material file").arg( matname ) );
741 matname=QLatin1String(
"");
745 Material& mat = _importer.
materials()[matname.toStdString()];
747 if ( mat.has_Texture() ){
750 _importer.useMaterial( matname.toStdString() );
754 lastMaterial = matname;
757 else if (mode == NONE && keyWrd == QLatin1String(
"v"))
762 currentVertexCount++;
765 else if (mode == NONE && keyWrd == QLatin1String(
"vt"))
771 currentTextureCoordCount++;
773 u = getFloat(stream);
774 v = getFloat(stream);
776 if ( stream.status() == QTextStream::Ok ){
782 emit log(
LOGERR, tr(
"Could not add TexCoord. Possible NaN or Inf?\nOnly single 2D texture coordinate per vertex allowed"));
788 else if (mode == NONE && keyWrd == QLatin1String(
"vn"))
794 currentNormalCount++;
796 x = getFloat(stream);
797 y = getFloat(stream);
798 z = getFloat(stream);
800 if ( stream.status() == QTextStream::Ok ){
803 emit log(
LOGERR, tr(
"Could not read normal. Possible NaN or Inf?"));
808 else if (mode == NONE && keyWrd == QLatin1String(
"deg"))
812 if ( stream.status() == QTextStream::Ok )
817 if ( stream.status() == QTextStream::Ok )
822 else if (mode == NONE && keyWrd == QLatin1String(
"g")){
827 groupName = stream.readLine();
830 currentFileName = groupName;
833 int id = _importer.groupId(groupName);
835 std::cerr <<
"Error: Group has not been added before!" << std::endl;
838 _importer.setCurrentGroup(
id);
843 if (lastMaterial !=
"" ) {
844 _importer.useMaterial(lastMaterial.toStdString());
849 else if (mode == NONE && keyWrd == QLatin1String(
"f"))
854 _importer.setCurrentGroup(0);
859 int component(0), nV(0);
863 face_texcoords.clear();
867 faceLine = stream.readLine();
868 lineData.setString(&faceLine);
871 while ( !lineData.atEnd() )
880 int found=vertex.indexOf(QLatin1String(
"/"));
886 QString vertexEntry = vertex.left(found);
887 tmp.setString( &vertexEntry );
890 if ( vertexEntry.isEmpty() ) {
892 vertex = vertex.right(vertex.length()-(found+1));
905 vertex = vertex.right(vertex.length()-(found+1));
910 tmp.setString( &vertex );
914 vertex=QLatin1String(
"");
917 if ( tmp.status() != QTextStream::Ok ) {
930 value = currentVertexCount + value + 1;
934 vhandles.push_back( value-1 );
942 value = currentTextureCoordCount + value + 1;
944 if (vhandles.empty())
946 if(!bSuppNoVertCoord) {
947 emit log (
LOGWARN, tr(
"Texture coordinates defined, but no vertex coordinates found!"));
948 bSuppNoVertCoord=
true;
952 if ((
unsigned int)(value-1) >= _importer.n_texCoords())
954 if(!bSuppTooManyTexCoord) {
955 emit log(
LOGWARN, tr(
"Too many texcoords defined, skipping the rest"));
956 bSuppTooManyTexCoord=
true;
961 if ( _importer.n_texCoords() > 0 ) {
964 face_texcoords.push_back( value-1 );
965 }
else if(bSuppErrorSettingTexCoord){
966 emit log(
LOGERR, tr(
"Error setting Texture coordinates") );
967 bSuppErrorSettingTexCoord=
true;
977 value = currentNormalCount + value + 1;
980 if (vhandles.empty())
982 if(!bSuppNoVertCoord) {
983 emit log (
LOGWARN, tr(
"Texture coordinates defined, but no vertex coordinates found!"));
984 bSuppNoVertCoord=
true;
989 if ((
unsigned int)(value-1) >= _importer.n_normals())
991 if(!bSuppTooManyNormal)
993 emit log (
LOGWARN, tr(
"Too many normals defined, skipping the rest"));
994 bSuppTooManyNormal=
true;
1000 _importer.
setNormal(vhandles.back(), value-1);
1008 }
while ( !vertex.isEmpty() );
1015 remove_duplicated_vertices(vhandles);
1018 if( vhandles.size() > 2 ){
1020 if ( !face_texcoords.empty() )
1022 _importer.
addFace(vhandles, face_texcoords );
1036 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1038 else if ( (mode == CURVE && keyWrd == QLatin1String(
"parm")) || (mode == CURVE && keyWrd == QLatin1String(
"parm_add")) ){
1044 paramLine = stream.readLine();
1047 if ( paramLine.endsWith(QLatin1String(
"\\"))){
1048 paramLine = paramLine.left( paramLine.length()-1);
1049 nextKeyWrd = QLatin1String(
"parm_add");
1052 lineData.setString( ¶mLine );
1054 if ( keyWrd != QLatin1String(
"parm_add"))
1058 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1063 knot = getDouble(lineData);
1065 if ( lineData.status() == QTextStream::Ok )
1066 knotsU.push_back( knot );
1071 else if ( (mode == NONE && keyWrd == QLatin1String(
"curv")) || (mode == CURVE && keyWrd == QLatin1String(
"curv_add")) ){
1079 if ( keyWrd == QLatin1String(
"curv") )
1081 int id = _importer.getCurveGroupId(curveCount);
1083 std::cerr <<
"Error: Group has not been added before!" << std::endl;
1086 _importer.setCurrentGroup(
id);
1093 curveLine = stream.readLine();
1096 if ( curveLine.endsWith(QLatin1String(
"\\"))){
1097 curveLine = curveLine.left(curveLine.length()-1);
1098 nextKeyWrd = QLatin1String(
"curv_add");
1101 lineData.setString( &curveLine );
1104 if ( keyWrd == QLatin1String(
"curv") ) {
1106 getDouble(lineData);
1107 getDouble(lineData);
1113 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1123 index = currentVertexCount + index + 1;
1126 if ( lineData.status()==QTextStream::Ok )
1127 cpIndices.push_back( index -1 );
1132 else if (mode == CURVE && keyWrd == QLatin1String(
"end")){
1136 _importer.currentCurve()->set_degree( _importer.
degreeU() );
1137 _importer.currentCurve()->autocompute_knotvector(
false);
1140 std::vector< ACG::Vec3d > controlPolygon;
1142 for (
unsigned int i = 0; i < cpIndices.size(); ++i)
1145 _importer.currentCurve()->set_control_polygon( controlPolygon );
1147 _importer.currentCurve()->set_knots(knotsU);
1157 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1159 else if ( (mode == SURFACE && keyWrd == QLatin1String(
"parm")) || (mode == SURFACE && keyWrd == QLatin1String(
"parm_add")) ){
1165 paramLine = stream.readLine();
1168 if ( paramLine.endsWith(QLatin1String(
"\\"))){
1169 paramLine = paramLine.left(paramLine.length()-1);
1170 nextKeyWrd = QLatin1String(
"parm_add");
1173 lineData.setString( ¶mLine );
1175 if ( keyWrd == QLatin1String(
"parm_add_u"))
1176 tmp = QLatin1String(
"u");
1177 else if ( keyWrd == QLatin1String(
"parm_add_v"))
1178 tmp = QLatin1String(
"v");
1182 std::vector< double >* knots;
1185 if (tmp == QLatin1String(
"u"))
1190 if (nextKeyWrd != QLatin1String(
""))
1191 nextKeyWrd += QLatin1String(
"_") + tmp;
1194 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1199 knot = getDouble(lineData);
1201 if ( lineData.status()==QTextStream::Ok ) {
1202 knots->push_back( knot );
1208 else if ( (mode == NONE && keyWrd == QLatin1String(
"surf")) || (mode == SURFACE && keyWrd == QLatin1String(
"surf_add")) ){
1216 if ( keyWrd == QLatin1String(
"surf") )
1218 int id = _importer.getSurfaceGroupId(surfaceCount);
1220 std::cerr <<
"Error: Group has not been added before!" << std::endl;
1223 _importer.setCurrentGroup(
id);
1230 surfLine = stream.readLine();
1233 if ( surfLine.endsWith(QLatin1String(
"\\"))){
1234 surfLine = surfLine.left(surfLine.length()-1);
1235 nextKeyWrd = QLatin1String(
"surf_add");
1238 lineData.setString( &surfLine );
1241 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1251 index = currentVertexCount + index + 1;
1254 if ( lineData.status()==QTextStream::Ok )
1255 cpIndices.push_back( index -1 );
1260 else if (mode == SURFACE && keyWrd == QLatin1String(
"end")){
1262 if ( _importer.isSurface( _importer.
currentGroup() ) ){
1265 cpIndices.erase(cpIndices.begin());
1266 cpIndices.erase(cpIndices.begin());
1267 cpIndices.erase(cpIndices.begin());
1268 cpIndices.erase(cpIndices.begin());
1271 _importer.currentSurface()->set_degree( _importer.
degreeU(), _importer.
degreeV() );
1274 int dimU = knotsU.size() - _importer.
degreeU() - 1;
1275 int dimV = knotsV.size() - _importer.
degreeV() - 1;
1278 std::vector< ACG::Vec3d > controlPolygon;
1280 for (
int i = 0; i < dimU; ++i)
1282 controlPolygon.clear();
1284 for (
int j = 0; j < dimV; ++j){
1285 controlPolygon.push_back( (
ACG::Vec3d) _importer.
vertex( cpIndices[dimU * j + i] ) );
1288 _importer.currentSurface()->add_vector_m(controlPolygon);
1291 _importer.currentSurface()->set_knots_m(knotsU);
1292 _importer.currentSurface()->set_knots_n(knotsV);
1307 bool isType = faceCount != 0;
1309 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1310 isType = isType || curveCount != 0;
1313 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1314 isType = isType || surfaceCount != 0;
1319 if (!isType && currentVertexCount != 0 ) {
1322 _importer.setCurrentGroup(0);
1330 ptr::shared_ptr<QTextStream> streamPointer;
1331 ptr::shared_ptr<QFile> sourceFile;
1333 if (_bufferedFile.isNull() || _bufferedFile.isEmpty())
1336 sourceFile.reset(
new QFile(_filename));
1337 if(!sourceFile->open(QFile::ReadOnly))
1339 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1 while checking Types").arg(_filename) );
1342 streamPointer.reset(
new QTextStream(sourceFile.get()));
1346 streamPointer.reset(
new QTextStream(&_bufferedFile));
1348 QTextStream input(streamPointer->device());
1350 QTextStream lineData;
1353 if ( input.status()!=QTextStream::Ok ){
1354 emit log(
LOGERR, tr(
"readOBJFile : cannot read file %1 while checking Types (is the file corrupt?)").arg(_filename) );
1358 ReaderMode mode = NONE;
1362 QString nextKeyWrd = QLatin1String(
"");
1364 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1365 unsigned int curveCount = 0;
1368 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1369 unsigned int surfaceCount = 0;
1375 int PolyMeshCount = 0;
1376 int TriMeshCount = 0;
1378 OBJImporter::ObjectOptions options = OBJImporter::NONE;
1381 bool inGroup =
false;
1383 bool firstFace =
true;
1385 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1386 QString currentGroupName;
1390 while( !input.atEnd())
1392 line = input.readLine();
1393 if ( input.status()!=QTextStream::Ok ){
1394 emit log(
LOGERR, tr(
"readOBJFile : Warning! Could not read file properly!"));
1399 line = line.trimmed();
1402 if ( line.isEmpty() || line[0] == QLatin1Char(
'#') || line[0].isSpace() ) {
1406 stream.setString(&line);
1410 if (nextKeyWrd == QLatin1String(
""))
1413 keyWrd = nextKeyWrd;
1414 nextKeyWrd = QLatin1String(
"");
1418 if (mode == NONE && keyWrd == QLatin1String(
"call")){
1422 include =stream.readLine();
1425 QString includeStr = include.trimmed();
1427 if ( !includeStr.isEmpty() ){
1429 if (includeStr[0] == QLatin1Char(
'.')){
1430 includeStr = includeStr.right( includeStr.length()-1 );
1432 QFileInfo fi(_filename);
1434 includeStr = fi.path() + QDir::separator() + includeStr;
1437 _includes.append( includeStr );
1444 else if (mode == NONE && keyWrd == QLatin1String(
"v"))
1449 x = getFloat(stream);
1450 y = getFloat(stream);
1451 z = getFloat(stream);
1453 if ( stream.status()==QTextStream::Ok )
1456 emit log(
LOGERR, tr(
"Could not add Vertex %1. Possible NaN or Inf?").arg(_importer.
n_vertices()));
1460 else if (mode == NONE && keyWrd == QLatin1String(
"g")){
1468 grpName = stream.readLine();
1470 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1471 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1473 int id = _importer.addGroup(grpName);
1474 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1476 currentGroupName = grpName;
1477 currentGroupName.remove(QLatin1String(
".obj"));
1479 _importer.setCurrentGroup(
id);
1486 options = OBJImporter::NONE;
1491 else if (mode == NONE && keyWrd == QLatin1String(
"f")){
1496 _importer.setCurrentGroup(0);
1502 int verticesPerFace = 0;
1507 faceLine = stream.readLine();
1508 lineData.setString( &faceLine );
1511 while ( !lineData.atEnd() )
1521 int found=vertex.indexOf(QLatin1String(
"/"));
1527 QString vertexEntry = vertex.left(found);
1528 tmp.setString( &vertexEntry );
1533 if ( tmp.status()!=QTextStream::Ok )
1534 emit log(
LOGERR, tr(
"readOBJFile : Error reading vertex index!"));
1539 tmp.setString( &vertex );
1542 if ( tmp.status()!=QTextStream::Ok )
1543 emit log(
LOGERR, tr(
"readOBJFile : Error reading vertex index!"));
1560 if( verticesPerFace > 3 ) {
1561 options = OBJImporter::POLYMESH;
1563 }
else if ( verticesPerFace == 3 ) {
1564 options = OBJImporter::TRIMESH;
1569 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1572 if ( (mode == NONE && keyWrd == QLatin1String(
"curv")) || (mode == CURVE && keyWrd == QLatin1String(
"curv_add")) ){
1580 if ( keyWrd == QLatin1String(
"curv") ) {
1584 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1585 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1587 QString
name = currentGroupName;
1588 if (name.size() == 0)
1589 name = QLatin1String(
"DefaultGroup");
1591 name.append(QString(
"_curve_%1").arg(curveCount));
1592 int id = _importer.addGroup(name);
1594 if (_importer.numCurves() == 0) {
1595 if (currentGroupName.size() == 0)
1596 _importer.setGroupName(
id, QString(
"DefaultGroup"));
1598 _importer.setGroupName(
id, currentGroupName);
1600 if (curveCount == 1) {
1601 int first = _importer.getCurveGroupId(0);
1602 QString tmp = _importer.groupName(first);
1603 tmp.append(QString(
"_curve_0"));
1604 _importer.setGroupName(first, tmp);
1606 _importer.setGroupName(
id, name);
1608 _importer.setCurveParentId(
id, parentId);
1609 _importer.setCurrentGroup(
id);
1610 _importer.setCurveGroupId(curveCount,
id);
1615 options = OBJImporter::CURVE;
1621 curveLine=stream.readLine();
1624 if ( curveLine.endsWith(QLatin1String(
"\\"))){
1625 curveLine = curveLine.left( curveLine.length()-1);
1626 nextKeyWrd = QLatin1String(
"curv_add");
1629 lineData.setString( &curveLine );
1632 if ( keyWrd == QLatin1String(
"curv") ) {
1634 getDouble(lineData);
1635 getDouble(lineData);
1639 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1645 if ( lineData.status()==QTextStream::Ok ){
1654 else if (mode == CURVE && keyWrd == QLatin1String(
"end")){
1659 options = OBJImporter::TRIMESH;
1664 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1667 if ( (mode == NONE && keyWrd == QLatin1String(
"surf")) || (mode == SURFACE && keyWrd == QLatin1String(
"surf_add")) ){
1675 if ( keyWrd == QLatin1String(
"surf") ){
1679 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1680 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1682 QString
name = currentGroupName;
1683 if (name.size() == 0)
1684 name = QLatin1String(
"DefaultGroup");
1686 name.append(QString(
"_surface_%1").arg(surfaceCount));
1687 int id = _importer.addGroup(name);
1689 if (_importer.numSurfaces() == 0) {
1690 if (currentGroupName.size() == 0)
1691 _importer.setGroupName(
id,
"DefaultGroup");
1693 _importer.setGroupName(
id, currentGroupName);
1695 if (surfaceCount == 1) {
1696 int first = _importer.getSurfaceGroupId(0);
1697 QString tmp = _importer.groupName(first);
1698 tmp.append(QString(
"_surface_0"));
1699 _importer.setGroupName(first, tmp);
1701 _importer.setGroupName(
id, name);
1703 _importer.setSurfaceParentId(
id, parentId);
1704 _importer.setCurrentGroup(
id);
1705 _importer.setSurfaceGroupId(surfaceCount,
id);
1710 options = OBJImporter::SURFACE;
1716 surfLine = stream.readLine();
1719 if ( surfLine.endsWith(QLatin1String(
"\\"))){
1720 surfLine = surfLine.left(surfLine.length()-1);
1721 nextKeyWrd = QLatin1String(
"surf_add");
1724 lineData.setString( &surfLine );
1727 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1733 if ( lineData.status()==QTextStream::Ok ){
1741 else if (mode == SURFACE && keyWrd == QLatin1String(
"end")){
1746 options = OBJImporter::TRIMESH;
1754 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1755 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1760 if (keyWrd != QLatin1String(
"call")) {
1762 if (keyWrd == QLatin1String(
"v") && !inGroup) {
1763 _importer.setCurrentGroup(0);
1765 forceTriangleMesh_ =
false;
1766 forcePolyMesh_ =
true;
1769 for (
unsigned int i = 0; i < _importer.
n_vertices(); ++i)
1782 if (TriMeshCount == 0 && PolyMeshCount == 0)
1787 if (forceTriangleMesh_){
1792 if (forcePolyMesh_){
1799 if ( OpenFlipper::Options::gui() && triMeshHandling_ != 0 ){
1801 switch( triMeshHandling_->currentIndex() ){
1802 case TYPEAUTODETECT :
1806 QMetaObject::invokeMethod(
this,
"handleTrimeshDialog",Qt::BlockingQueuedConnection);
1807 if (trimeshOptions_ == OBJImporter::TRIMESH )
1809 else if (trimeshOptions_ == OBJImporter::POLYMESH)
1828 void FileOBJPlugin::handleTrimeshDialog()
1831 QPushButton *detectButton = msgBox.addButton(tr(
"Auto-Detect"), QMessageBox::ActionRole);
1832 QPushButton *triButton = msgBox.addButton(tr(
"Open as triangle mesh"), QMessageBox::ActionRole);
1833 QPushButton *polyButton = msgBox.addButton(tr(
"Open as poly mesh"), QMessageBox::ActionRole);
1834 msgBox.setWindowTitle( tr(
"Mesh types in file") );
1835 msgBox.setText( tr(
"You are about to open a file containing one or more mesh types. \n\n Which mesh type should be used?") );
1836 msgBox.setDefaultButton( detectButton );
1840 if (msgBox.clickedButton() == triButton)
1841 trimeshOptions_ = OBJImporter::TRIMESH ;
1842 else if (msgBox.clickedButton() == polyButton)
1843 trimeshOptions_ = OBJImporter::POLYMESH ;
1853 QStringList includes;
1855 QFile sourceFile(_filename);
1856 if (!sourceFile.open(QFile::ReadOnly))
1858 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1 while checking Types").arg(_filename));
1861 QByteArray bufferedFile = QByteArray();
1864 unsigned long freeMem = Utils::Memory::queryFreeRAM();
1865 unsigned long fs = sourceFile.size() / 1024 / 1024;
1866 if (freeMem >= 2*fs)
1868 bufferedFile = sourceFile.readAll();
1872 checkTypes( bufferedFile, _filename, importer, includes );
1877 for (
int i=0; i < includes.size(); i++){
1883 objIDs.push_back(
id );
1887 if ( ! includes.empty() )
1888 importer.addGroup( QFileInfo(_filename).fileName() );
1891 if ( importer.
noOptions() && objIDs.empty() ){
1893 forceTriangleMesh_ =
false;
1894 forcePolyMesh_ =
false;
1900 readOBJFile( bufferedFile, _filename, importer );
1908 if ( importer.numGroups() > 1){
1910 bool dataControlExists =
false;
1911 pluginExists(
"datacontrol", dataControlExists );
1913 if ( dataControlExists ){
1914 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1915 std::map<int, QString> groupNames;
1918 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1919 std::vector< std::vector<int> > curveGroups;
1920 std::vector<int> curveIds;
1921 int lastCurveParent = -2;
1924 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1925 std::vector< std::vector<int> > surfaceGroups;
1926 std::vector<int> surfaceIds;
1927 int lastSurfaceParent = -2;
1929 for(
unsigned int i = 0; i < importer.
groupCount(); i++) {
1932 if ( !importer.isNone(i) ) {
1935 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1936 if ( importer.isCurve(i) ) {
1938 groupNames[obj->
id()] = importer.groupName(importer.getCurveParentId(i));
1941 if (lastCurveParent == -2) {
1942 lastCurveParent = importer.getCurveParentId(i);
1943 curveIds.push_back(obj->
id());
1946 curveIds.push_back(parent->
id());
1948 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1949 if (pos != objIDs.end())
1953 }
else if (lastCurveParent != importer.getCurveParentId(i)) {
1954 lastCurveParent = importer.getCurveParentId(i);
1955 curveGroups.push_back(curveIds);
1957 curveIds.push_back(obj->
id());
1960 curveIds.push_back(parent->
id());
1962 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1963 if (pos != objIDs.end())
1968 curveIds.push_back(obj->
id());
1972 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1973 if ( importer.isSurface(i)) {
1975 groupNames[obj->
id()] = importer.groupName(importer.getSurfaceParentId(i));
1978 if (lastSurfaceParent == -2) {
1979 lastSurfaceParent = importer.getSurfaceParentId(i);
1980 surfaceIds.push_back(obj->
id());
1983 surfaceIds.push_back(parent->
id());
1984 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1985 if (pos != objIDs.end())
1989 }
else if (lastSurfaceParent != importer.getSurfaceParentId(i)) {
1990 lastSurfaceParent = importer.getSurfaceParentId(i);
1991 surfaceGroups.push_back(surfaceIds);
1993 surfaceIds.push_back(obj->
id());
1996 surfaceIds.push_back(parent->
id());
1997 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1998 if (pos != objIDs.end())
2003 surfaceIds.push_back(obj->
id());
2007 if ( (importer.isTriangleMesh(i) || importer.isPolyMesh(i) ) )
2008 objIDs.push_back( obj->
id() );
2010 std::cerr <<
"Object is NULL!" << std::endl;
2015 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2017 curveGroups.push_back(curveIds);
2018 std::vector< std::vector<int> >::iterator it = curveGroups.begin();
2019 for (; it != curveGroups.end(); ++it) {
2021 if (it->size() > 2) {
2022 if (groupNames[it->back()].size() == 0)
2023 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it, QFileInfo(_filename).fileName());
2025 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it, groupNames[it->back()]);
2030 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 2032 surfaceGroups.push_back(surfaceIds);
2033 std::vector< std::vector<int> >::iterator it2 = surfaceGroups.begin();
2034 for (; it2 != surfaceGroups.end(); ++it2) {
2036 if (it2->size() > 2) {
2037 if (groupNames[it2->back()].size() == 0)
2038 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it2, QFileInfo(_filename).fileName());
2040 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it2, groupNames[it2->back()]);
2046 if (objIDs.size() > 1)
2047 returnID = RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", objIDs, importer.groupName(0));
2052 for(
unsigned int i=0; i < importer.
groupCount(); i++){
2055 if(
object == NULL)
continue;
2060 if ( returnID == -1)
2061 returnID =
object->id();
2085 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2096 if ( importer.hasTexture(i) && !importer.
hasOption( i, OBJImporter::FORCE_NOTEXTURES ) ){
2099 addTextures( importer, i );
2102 emit setTextureMode(
"OBJ Data",
"indexProperty=OriginalTexIndexMapping", object->
id() );
2104 emit switchTexture(
"OBJ Data", object->
id() );
2112 emit openedFile( object->
id() );
2115 forceTriangleMesh_ =
false;
2116 forcePolyMesh_ =
false;
2129 forceTriangleMesh_ =
true;
2131 forcePolyMesh_ =
true;
2138 bool FileOBJPlugin::saveObject(
int _id, QString _filename)
2142 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2147 std::string filename = std::string( _filename.toUtf8() );
2149 std::fstream objStream( filename.c_str(), std::ios_base::out );
2153 emit log(
LOGERR, tr(
"saveObject : cannot not open file %1").arg(_filename) );
2160 object->setFromFileName(_filename);
2161 object->setName(object->
filename());
2166 if ( writeMesh( objStream, _filename, *polyObj->
mesh(), polyObj->
id() ) ){
2168 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2174 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2181 object->setFromFileName(_filename);
2182 object->setName(object->
filename());
2187 if ( writeMesh( objStream, _filename, *triObj->
mesh(), triObj->
id() )) {
2189 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2195 emit log(
LOGERR, tr(
"Unable to save ") + _filename );
2200 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2203 object->setFromFileName(_filename);
2204 object->setName(object->
filename());
2209 if ( writeCurve( objStream, _filename, bscObj->
splineCurve()) ) {
2211 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2217 emit log(
LOGERR, tr(
"Unable to save ") + _filename );
2223 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 2226 object->setFromFileName(_filename);
2227 object->setName(object->
filename());
2232 if ( writeSurface( objStream, _filename, bssObj->
splineSurface()) ) {
2234 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2240 emit log(
LOGERR, tr(
"Unable to save ") + object->
path() + OpenFlipper::Options::dirSeparator() +
object->name());
2248 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2256 void FileOBJPlugin::slotHandleCheckBoxes(
bool _checked) {
2258 if(saveCopyTextures_) {
2259 saveCreateTexFolder_->setEnabled(_checked);
2260 saveCreateTexFolder_->setChecked(_checked);
2268 if (saveOptions_ == 0){
2270 saveOptions_ =
new QWidget();
2271 QVBoxLayout* layout =
new QVBoxLayout();
2272 layout->setAlignment(Qt::AlignTop);
2274 saveFaceColor_ =
new QCheckBox(
"Save Face Colors");
2275 layout->addWidget(saveFaceColor_);
2277 saveFaceColorOverride_ =
new QCheckBox(
"Save Face Colors Error Override (Save, even if colors contain errors!)");
2278 saveFaceColorOverride_->setToolTip(
"If color values of a mesh are not initialized, OpenFlipper will detect that and stop writing materials. This option will force it to write them anyway.");
2279 layout->addWidget(saveFaceColorOverride_);
2281 saveAlpha_ =
new QCheckBox(
"Save Color Alpha");
2282 layout->addWidget(saveAlpha_);
2284 saveNormals_ =
new QCheckBox(
"Save Normals");
2285 layout->addWidget(saveNormals_);
2287 saveTexCoords_ =
new QCheckBox(
"Save Texture Coordinates");
2288 layout->addWidget(saveTexCoords_);
2290 saveTextures_ =
new QCheckBox(
"Save Textures");
2291 layout->addWidget(saveTextures_);
2293 saveCopyTextures_ =
new QCheckBox(
"Copy Texture Files");
2294 layout->addWidget(saveCopyTextures_);
2296 saveCreateTexFolder_ =
new QCheckBox(
"Create Textures Folder");
2297 layout->addWidget(saveCreateTexFolder_);
2299 savePrecisionLabel_ =
new QLabel(
"Writer Precision");
2300 layout->addWidget(savePrecisionLabel_);
2302 savePrecision_ =
new QSpinBox();
2303 savePrecision_->setMinimum(1);
2304 savePrecision_->setMaximum(12);
2305 savePrecision_->setValue(6);
2306 layout->addWidget(savePrecision_);
2308 saveDefaultButton_ =
new QPushButton(
"Make Default");
2309 layout->addWidget(saveDefaultButton_);
2311 saveOptions_->setLayout(layout);
2313 connect(saveDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotSaveDefault()));
2314 connect(saveCopyTextures_, SIGNAL(toggled(
bool)),
this, SLOT(slotHandleCheckBoxes(
bool)));
2316 saveFaceColor_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/FaceColor",
true).toBool() );
2317 saveFaceColorOverride_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/FaceColorOverrise",
false).toBool() );
2318 saveAlpha_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Alpha",
true).toBool() );
2319 saveNormals_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Normals",
true).toBool() );
2320 saveTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/TexCoords",
true).toBool() );
2321 saveTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Textures",
true).toBool() );
2322 saveCopyTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/CopyTextures",
true).toBool() );
2323 saveCreateTexFolder_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/CreateTexFolder",
true).toBool() );
2325 slotHandleCheckBoxes(saveCopyTextures_->isChecked());
2328 return saveOptions_;
2335 if (loadOptions_ == 0){
2337 loadOptions_ =
new QWidget();
2338 QVBoxLayout* layout =
new QVBoxLayout();
2339 layout->setAlignment(Qt::AlignTop);
2341 QLabel* label =
new QLabel(tr(
"If file contains meshes:"));
2343 layout->addWidget(label);
2345 triMeshHandling_ =
new QComboBox();
2346 triMeshHandling_->addItem( tr(
"Detect correct type") );
2347 triMeshHandling_->addItem( tr(
"Ask") );
2348 triMeshHandling_->addItem( tr(
"Open as PolyMesh") );
2349 triMeshHandling_->addItem( tr(
"Open as TriangleMesh") );
2351 layout->addWidget(triMeshHandling_);
2353 loadFaceColor_ =
new QCheckBox(
"Load Face Colors");
2354 layout->addWidget(loadFaceColor_);
2356 loadNormals_ =
new QCheckBox(
"Load Normals");
2357 layout->addWidget(loadNormals_);
2359 loadTexCoords_ =
new QCheckBox(
"Load Texture Coordinates");
2360 layout->addWidget(loadTexCoords_);
2362 loadTextures_ =
new QCheckBox(
"Load Textures");
2363 layout->addWidget(loadTextures_);
2365 loadDefaultButton_ =
new QPushButton(
"Make Default");
2366 layout->addWidget(loadDefaultButton_);
2368 loadOptions_->setLayout(layout);
2370 connect(loadDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotLoadDefault()));
2373 triMeshHandling_->setCurrentIndex(
OpenFlipperSettings().value(
"FileObj/Load/TriMeshHandling",TYPEAUTODETECT).toInt() );
2375 loadFaceColor_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/FaceColor",
true).toBool() );
2376 loadNormals_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/Normals",
true).toBool() );
2377 loadTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/TexCoords",
true).toBool() );
2378 loadTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/Textures",
true).toBool() );
2381 return loadOptions_;
void slotLoadDefault()
Slot called when user wants to save the given Load options as default.
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
#define DATA_TRIANGLE_MESH
QString path() const
return the path to the object ( defaults to "." if unset )
void setObjectOptions(ObjectOptions _options)
void setNormal(int _index, int _normalID)
set vertex normal
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void addMaterial(std::string _materialName)
Add a material.
Type for a Meshobject containing a poly mesh.
Vec3f vertex(unsigned int _index)
get vertex with given index
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
void initializePlugin()
Initialize Plugin.
void checkTypes(QByteArray &_bufferedFile, QString _filename, OBJImporter &_importer, QStringList &_includes)
Reader functions.
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
QWidget * loadOptionsWidget(QString)
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
BSplineSurface * splineSurface()
return a pointer to the spline curve
QString name()
Return a name for the plugin.
void useVertex(int _vertex_index)
used vertices
BaseObject * object(int _groupId)
return object for the given group
DrawMode SOLID_2DTEXTURED_FACE_SHADED
draw per halfedge textured faces
const DataType DATA_GROUP(1)
Items used for Grouping.
int addTexCoord(const Vec2f &_coord)
add texture coordinates
QString filename() const
return the filename of the object
QWidget * saveOptionsWidget(QString)
void setOption(ObjectOptionsE _option)
Set Object Option.
MeshT * mesh()
return a pointer to the mesh
void setDegreeV(int _degree)
set degree V direction
bool dataType(DataType _type) const
std::vector< int > IdList
Standard Type for id Lists used for scripting.
#define DATA_BSPLINE_SURFACE
FileOBJPlugin()
Constructor.
void setObject(BaseObject *_object, int _groupId)
add an object
#define DATA_BSPLINE_CURVE
int currentGroup()
Get the id of the current group.
BSplineCurve * splineCurve()
return a pointer to the spline curve
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
Type for a MeshObject containing a triangle mesh.
ACG::SceneGraph::BSplineCurveNodeT< BSplineCurve > * splineCurveNode()
Get the scenegraph Node.
void update_normals()
Compute normals for all primitives.
void update_face_normals()
Update normal vectors for all faces.
void setDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, int _viewer)
Set the draw Mode of a Viewer. .
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
bool hasOption(unsigned int _id, ObjectOptions _option)
check if object with given id has given option
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
int addNormal(const Vec3f &_normal)
add a normal
unsigned int n_vertices()
Global Properties.
bool hasNormals(int _objectID)
Query Object Options.
QString path()
Path of the OBJ file.
unsigned int groupCount()
Number of groups currently stored in the importer.
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
void backupTextureCoordinates(MeshT &_mesh)
creates a backup of the original per vertex/face texture coordinates
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
int degreeU()
get current degree
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
int degreeV()
get current degree
void convertToOBJName(QString &_name)
Convert non-valid filenames (e.g. of groups that end with .jpg) to valid .objs.
MaterialList & materials()
return all loaded materials
bool noOptions()
Return true if the importer has no options stored.
void setFromFileName(const QString &_filename)
void setDegreeU(int _degree)
set degree