49 #include <ACG/GL/GLState.hh> 54 #include <OpenMesh/Core/IO/IOManager.hh> 56 #include <OpenFlipper/Utils/Memory/RAMInfo.hh> 58 #if QT_VERSION >= 0x050000 66 #include <ACG/Utils/SmartPointer.hh> 70 #define TYPEAUTODETECT 0 73 #define TYPETRIANGLE 3 75 using namespace Utils;
80 void remove_duplicated_vertices(VHandles& _indices)
82 VHandles::iterator endIter = _indices.end();
83 for (VHandles::iterator iter = _indices.begin(); iter != endIter; ++iter)
84 endIter = std::remove(iter+1, endIter, *(iter));
86 _indices.erase(endIter,_indices.end());
102 saveCopyTextures_(0),
103 saveCreateTexFolder_(0),
104 savePrecisionLabel_(0),
106 saveDefaultButton_(0),
114 loadDefaultButton_(0),
115 forceTriangleMesh_(false),
116 forcePolyMesh_(false),
117 textureIndexPropFetched_(false),
130 return QString( tr(
"Alias/Wavefront ( *.obj )") );
136 return QString( tr(
"Alias/Wavefront ( *.obj )") );
144 #ifdef ENABLE_BSPLINECURVE_SUPPORT 148 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 157 bool FileOBJPlugin::readMaterial(QString _filename,
OBJImporter& _importer)
160 static QString keyWrd;
161 static QString textureName;
166 static QString matName;
170 static float f1,f2,f3;
174 static bool insideDefintion;
175 insideDefintion =
false;
176 static int textureId;
181 QFile matFile(_filename);
182 if (!matFile.open(QFile::ReadOnly))
184 emit log(
LOGERR, tr(
"readMaterial : cannot open file %1").arg(_filename));
188 QTextStream matStream(&matFile);
189 if ( matStream.status()!=QTextStream::Ok ){
190 emit log(
LOGERR, tr(
"readMaterial : cannot open stream %1").arg(_filename) );
198 while( matStream.status() == QTextStream::Ok && !matStream.atEnd() )
200 line = matStream.readLine();
201 if ( matStream.status() != QTextStream::Ok ){
202 emit log(
LOGERR, tr(
"readMaterial : Warning! Could not read file properly!"));
206 if ( line.isEmpty() )
209 QTextStream stream(&line);
213 if( ( line[0].isSpace() && line[0] != QLatin1Char(
'\t') ) || line[0] == QLatin1Char(
'#') )
215 if (insideDefintion && !matName.isEmpty() && mat.is_valid())
217 _importer.
materials()[matName.toStdString()] = mat;
222 else if (keyWrd == QLatin1String(
"newmtl"))
225 insideDefintion =
true;
228 else if (keyWrd == QLatin1String(
"Kd"))
230 f1 = getFloat(stream);
231 f2 = getFloat(stream);
232 f3 = getFloat(stream);
234 if( stream.status()==QTextStream::Ok )
235 mat.set_Kd(f1,f2,f3);
238 else if (keyWrd == QLatin1String(
"Ka"))
240 f1 = getFloat(stream);
241 f2 = getFloat(stream);
242 f3 = getFloat(stream);
244 if( stream.status()!=QTextStream::Ok )
245 mat.set_Ka(f1,f2,f3);
248 else if (keyWrd == QLatin1String(
"Ks"))
250 f1 = getFloat(stream);
251 f2 = getFloat(stream);
252 f3 = getFloat(stream);
254 if( stream.status()!=QTextStream::Ok )
255 mat.set_Ks(f1,f2,f3);
258 else if (keyWrd == QLatin1String(
"illum")
263 else if (keyWrd == QLatin1String(
"Ns")
268 else if (keyWrd == QLatin1String(
"map_")
277 else if (keyWrd == QLatin1String(
"map_Kd") ) {
280 textureName = stream.readLine();
281 textureName = textureName.trimmed();
282 if ( ! textureName.isEmpty() )
283 mat.set_map_Kd( textureName.toStdString(), textureId++ );
285 else if (keyWrd == QLatin1String(
"Tr"))
287 f1 = getFloat(stream);
289 if( stream.status() == QTextStream::Ok )
292 else if (keyWrd == QLatin1String(
"d"))
294 f1 = getFloat(stream);
296 if( stream.status() == QTextStream::Ok )
300 if ( matStream.status() == QTextStream::Ok && insideDefintion && mat.is_valid() && !matName.isEmpty())
301 _importer.
materials()[matName.toStdString()] = mat;
304 emit log( tr(
"%1 materials loaded.").arg( _importer.
materials().size() ) );
311 void FileOBJPlugin::createAllGroupObjects(
OBJImporter& _importer) {
313 for(
unsigned int i = 0; i < _importer.numGroups(); ++i) {
316 QString
name = _importer.groupName(i);
319 if ( _importer.isTriangleMesh( i ) ){
331 object->setPath(_importer.
path());
332 object->setName(name);
335 }
else if (_importer.isPolyMesh( i )) {
346 object->setPath(_importer.
path());
347 object->setName(name);
351 #ifdef ENABLE_BSPLINECURVE_SUPPORT 353 else if (_importer.isCurve( i )) {
364 object->setPath(_importer.
path());
365 object->setName(name);
371 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 373 else if (_importer.isSurface( i )) {
384 object->setPath(_importer.
path());
385 object->setName(name);
392 if (OpenFlipper::Options::gui() && loadOptions_ != 0) {
394 if (!loadFaceColor_->isChecked())
395 _importer.
objectOptions()[ i ] |= OBJImporter::FORCE_NOCOLOR;
397 if (!loadNormals_->isChecked())
398 _importer.
objectOptions()[ i ] |= OBJImporter::FORCE_NONORMALS;
400 if (!loadTexCoords_->isChecked() || !loadTextures_->isChecked())
401 _importer.
objectOptions()[ i ] |= OBJImporter::FORCE_NOTEXTURES;
410 QString n = fi.baseName();
412 _name = n.trimmed() +
".obj";
416 template <
class MeshT>
420 if (_mesh.has_vertex_texcoords2D()) {
423 if (!_mesh.get_property_handle(oldVertexCoords,
"Original Per Vertex Texture Coords"))
424 _mesh.add_property(oldVertexCoords,
"Original Per Vertex Texture Coords");
426 for (
typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
427 _mesh.property(oldVertexCoords, *v_it) = _mesh.texcoord2D(*v_it);
432 if (_mesh.has_halfedge_texcoords2D()) {
435 if (!_mesh.get_property_handle(oldHalfedgeCoords,
"Original Per Face Texture Coords"))
436 _mesh.add_property(oldHalfedgeCoords,
"Original Per Face Texture Coords");
438 for (
typename MeshT::HalfedgeIter he_it = _mesh.halfedges_begin(); he_it != _mesh.halfedges_end(); ++he_it)
439 _mesh.property(oldHalfedgeCoords, *he_it) = _mesh.texcoord2D(*he_it);
446 void FileOBJPlugin::addTextures(
OBJImporter& _importer,
int _objectID ){
456 std::map< int,int > newMapping;
460 const std::vector<std::string> matNames = _importer.
usedMaterials( _objectID );
462 for (
unsigned int i=0; i < matNames.size(); i++){
464 Material& material = _importer.
materials()[ matNames[i] ];
468 QString textureBlock = QString( material.map_Kd().c_str());
471 QStringList options = textureBlock.split(
" ",QString::SkipEmptyParts);
473 while ( options.size() > 1 ) {
474 if ( options[0] ==
"-blendu" ) {
477 }
else if ( options[0] ==
"-blendv" ) {
480 }
else if ( options[0] ==
"-cc" ) {
483 }
else if ( options[0] ==
"-clamp" ) {
486 }
else if ( options[0] ==
"-mm" ) {
490 }
else if ( options[0] ==
"-o" ) {
495 }
else if ( options[0] ==
"-s" ) {
500 }
else if ( options[0] ==
"-t" ) {
505 }
else if ( options[0] ==
"-texres" ) {
513 QString fullName = _importer.
path() + QDir::separator() + options.join(
" ");
515 QFileInfo info(fullName);
517 emit addMultiTexture(
"OBJ Data", info.baseName().trimmed(), fullName,
object->id(), textureId );
519 emit log(
LOGWARN, tr(
"Unable to load texture image %1").arg( QString(material.map_Kd().c_str()) ) );
520 addMultiTexture(
"OBJ Data",
"Unknown Texture image " + QString::number(textureId),
"unknown.png", object->
id(), textureId );
523 newMapping[ material.map_Kd_index() ] = textureId;
537 PolyMesh::FaceIter f_it;
538 PolyMesh::FaceIter f_end = mesh.faces_end();
540 if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
543 for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
544 mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
558 TriMesh::FaceIter f_it;
559 TriMesh::FaceIter f_end = mesh.faces_end();
561 if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
564 for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
565 mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
574 void FileOBJPlugin::readOBJFile(QByteArray& _bufferedFile, QString _filename,
OBJImporter& _importer)
576 QString path = QFileInfo(_filename).absolutePath();
577 ptr::shared_ptr<QTextStream> streamPointer;
578 ptr::shared_ptr<QFile> sourceFile;
581 if (_bufferedFile.isNull())
583 sourceFile.reset(
new QFile(_filename) );
584 if(!sourceFile->open(QFile::ReadOnly))
586 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1").arg(_filename) );
591 streamPointer.reset(
new QTextStream(sourceFile.get()));
595 streamPointer.reset(
new QTextStream(&_bufferedFile));
597 QTextStream input(streamPointer->device());
600 QTextStream lineData;
602 if ( input.status() != QTextStream::Ok){
603 emit log(
LOGERR, tr(
"readOBJFile : cannot read file %1 is the file corrupt?").arg(_filename) );
607 QString currentFileName = QFileInfo(_filename).fileName() ;
609 ReaderMode mode = NONE;
613 QString nextKeyWrd = QLatin1String(
"");
615 #ifdef ENABLE_BSPLINECURVE_SUPPORT 616 unsigned int curveCount = 0;
619 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 620 unsigned int surfaceCount = 0;
626 std::vector<VertexHandle> vhandles;
627 std::vector<int> face_texcoords;
630 #if defined (ENABLE_BSPLINECURVE_SUPPORT) || defined (ENABLE_BSPLINESURFACE_SUPPORT) 631 std::vector< int > cpIndices;
632 std::vector< double > knotsU,knotsV;
638 int currentVertexCount = 0;
641 int currentTextureCoordCount = 0;
644 int currentNormalCount = 0;
647 bool inGroup =
false;
649 bool firstFace =
true;
651 _importer.setPath( path );
654 _importer.setGroupName(0, currentFileName);
657 createAllGroupObjects(_importer);
659 while( !input.atEnd() )
661 line=input.readLine();
662 if ( input.status() == QTextStream::ReadCorruptData ){
663 emit log(
LOGERR, tr(
"readOBJFile : Warning! Could not read file properly!"));
668 line = line.trimmed();
671 if ( line.isEmpty() || line[0] == QLatin1Char(
'#') || line[0].isSpace() ) {
675 stream.setString(&line,QIODevice::ReadOnly);
679 if (nextKeyWrd == QLatin1String(
""))
683 nextKeyWrd = QLatin1String(
"");
687 if (mode == NONE && keyWrd == QLatin1String(
"mtllib"))
692 matString = stream.readLine();
694 QString matFile = path + QDir::separator() + matString.trimmed();
696 emit log( tr(
"Loading material file: %1").arg( matFile ) );
698 readMaterial( matFile, _importer );
702 else if (mode == NONE && keyWrd == QLatin1String(
"usemtl"))
707 emit log(
LOGERR, tr(
"Warning! Material '%1' not defined in material file").arg( matname ) );
708 matname=QLatin1String(
"");
712 Material& mat = _importer.
materials()[matname.toStdString()];
714 if ( mat.has_Texture() ){
716 _importer.useMaterial( matname.toStdString() );
720 else if (mode == NONE && keyWrd == QLatin1String(
"v"))
725 currentVertexCount++;
728 else if (mode == NONE && keyWrd == QLatin1String(
"vt"))
734 currentTextureCoordCount++;
736 u = getFloat(stream);
737 v = getFloat(stream);
739 if ( stream.status() == QTextStream::Ok ){
745 emit log(
LOGERR, tr(
"Could not add TexCoord. Possible NaN or Inf?\nOnly single 2D texture coordinate per vertex allowed"));
751 else if (mode == NONE && keyWrd == QLatin1String(
"vn"))
757 currentNormalCount++;
759 x = getFloat(stream);
760 y = getFloat(stream);
761 z = getFloat(stream);
763 if ( stream.status() == QTextStream::Ok ){
766 emit log(
LOGERR, tr(
"Could not read normal. Possible NaN or Inf?"));
771 else if (mode == NONE && keyWrd == QLatin1String(
"deg"))
775 if ( stream.status() == QTextStream::Ok )
780 if ( stream.status() == QTextStream::Ok )
785 else if (mode == NONE && keyWrd == QLatin1String(
"g")){
790 groupName = stream.readLine();
793 currentFileName = groupName;
796 int id = _importer.groupId(groupName);
798 std::cerr <<
"Error: Group has not been added before!" << std::endl;
801 _importer.setCurrentGroup(
id);
808 else if (mode == NONE && keyWrd == QLatin1String(
"f"))
813 _importer.setCurrentGroup(0);
818 int component(0), nV(0);
822 face_texcoords.clear();
826 faceLine = stream.readLine();
827 lineData.setString(&faceLine);
830 while ( !lineData.atEnd() )
839 int found=vertex.indexOf(QLatin1String(
"/"));
845 QString vertexEntry = vertex.left(found);
846 tmp.setString( &vertexEntry );
849 if ( vertexEntry.isEmpty() ) {
851 vertex = vertex.right(vertex.length()-(found+1));
864 vertex = vertex.right(vertex.length()-(found+1));
869 tmp.setString( &vertex );
873 vertex=QLatin1String(
"");
876 if ( tmp.status() != QTextStream::Ok ) {
889 value = currentVertexCount + value + 1;
893 vhandles.push_back( value-1 );
901 value = currentTextureCoordCount + value + 1;
904 if (vhandles.empty())
906 emit log (
LOGWARN, tr(
"Texture coordinates defined, but no vertex coordinates found!"));
909 if ((
unsigned int)(value-1) >= _importer.n_texCoords())
911 emit log (
LOGWARN, tr(
"Too many texcoords defined, skipping the rest"));
915 if ( _importer.n_texCoords() > 0 ) {
918 face_texcoords.push_back( value-1 );
920 emit log(
LOGERR, tr(
"Error setting Texture coordinates") );
930 value = currentNormalCount + value + 1;
933 if (vhandles.empty())
935 emit log (
LOGWARN, tr(
"Texture coordinates defined, but no vertex coordinates found!"));
939 if ((
unsigned int)(value-1) >= _importer.n_normals())
941 emit log (
LOGWARN, tr(
"Too many normals defined, skipping the rest"));
946 _importer.
setNormal(vhandles.back(), value-1);
954 }
while ( !vertex.isEmpty() );
961 remove_duplicated_vertices(vhandles);
964 if( vhandles.size() > 2 ){
966 if ( !face_texcoords.empty() )
968 _importer.
addFace(vhandles, face_texcoords );
982 #ifdef ENABLE_BSPLINECURVE_SUPPORT 984 else if ( (mode == CURVE && keyWrd == QLatin1String(
"parm")) || (mode == CURVE && keyWrd == QLatin1String(
"parm_add")) ){
990 paramLine = stream.readLine();
993 if ( paramLine.endsWith(QLatin1String(
"\\"))){
994 paramLine = paramLine.left( paramLine.length()-1);
995 nextKeyWrd = QLatin1String(
"parm_add");
998 lineData.setString( ¶mLine );
1000 if ( keyWrd != QLatin1String(
"parm_add"))
1004 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1009 knot = getDouble(lineData);
1011 if ( lineData.status() == QTextStream::Ok )
1012 knotsU.push_back( knot );
1017 else if ( (mode == NONE && keyWrd == QLatin1String(
"curv")) || (mode == CURVE && keyWrd == QLatin1String(
"curv_add")) ){
1025 if ( keyWrd == QLatin1String(
"curv") )
1027 int id = _importer.getCurveGroupId(curveCount);
1029 std::cerr <<
"Error: Group has not been added before!" << std::endl;
1032 _importer.setCurrentGroup(
id);
1039 curveLine = stream.readLine();
1042 if ( curveLine.endsWith(QLatin1String(
"\\"))){
1043 curveLine = curveLine.left(curveLine.length()-1);
1044 nextKeyWrd = QLatin1String(
"curv_add");
1047 lineData.setString( &curveLine );
1050 if ( keyWrd == QLatin1String(
"curv") ) {
1052 trash = getDouble(lineData);
1053 trash = getDouble(lineData);
1059 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1069 index = currentVertexCount + index + 1;
1072 if ( lineData.status()==QTextStream::Ok )
1073 cpIndices.push_back( index -1 );
1078 else if (mode == CURVE && keyWrd == QLatin1String(
"end")){
1082 _importer.currentCurve()->set_degree( _importer.
degreeU() );
1083 _importer.currentCurve()->autocompute_knotvector(
false);
1086 std::vector< ACG::Vec3d > controlPolygon;
1088 for (
unsigned int i = 0; i < cpIndices.size(); ++i)
1091 _importer.currentCurve()->set_control_polygon( controlPolygon );
1093 _importer.currentCurve()->set_knots(knotsU);
1103 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1105 else if ( (mode == SURFACE && keyWrd == QLatin1String(
"parm")) || (mode == SURFACE && keyWrd == QLatin1String(
"parm_add")) ){
1111 paramLine = stream.readLine();
1114 if ( paramLine.endsWith(QLatin1String(
"\\"))){
1115 paramLine = paramLine.left(paramLine.length()-1);
1116 nextKeyWrd = QLatin1String(
"parm_add");
1119 lineData.setString( ¶mLine );
1121 if ( keyWrd == QLatin1String(
"parm_add_u"))
1122 tmp = QLatin1String(
"u");
1123 else if ( keyWrd == QLatin1String(
"parm_add_v"))
1124 tmp = QLatin1String(
"v");
1128 std::vector< double >* knots;
1131 if (tmp == QLatin1String(
"u"))
1136 if (nextKeyWrd != QLatin1String(
""))
1137 nextKeyWrd += QLatin1String(
"_") + tmp;
1140 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1145 knot = getDouble(lineData);
1147 if ( lineData.status()==QTextStream::Ok ) {
1148 knots->push_back( knot );
1154 else if ( (mode == NONE && keyWrd == QLatin1String(
"surf")) || (mode == SURFACE && keyWrd == QLatin1String(
"surf_add")) ){
1162 if ( keyWrd == QLatin1String(
"surf") )
1164 int id = _importer.getSurfaceGroupId(surfaceCount);
1166 std::cerr <<
"Error: Group has not been added before!" << std::endl;
1169 _importer.setCurrentGroup(
id);
1176 surfLine = stream.readLine();
1179 if ( surfLine.endsWith(QLatin1String(
"\\"))){
1180 surfLine = surfLine.left(surfLine.length()-1);
1181 nextKeyWrd = QLatin1String(
"surf_add");
1184 lineData.setString( &surfLine );
1187 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1197 index = currentVertexCount + index + 1;
1200 if ( lineData.status()==QTextStream::Ok )
1201 cpIndices.push_back( index -1 );
1206 else if (mode == SURFACE && keyWrd == QLatin1String(
"end")){
1211 cpIndices.erase(cpIndices.begin());
1212 cpIndices.erase(cpIndices.begin());
1213 cpIndices.erase(cpIndices.begin());
1214 cpIndices.erase(cpIndices.begin());
1217 _importer.currentSurface()->set_degree( _importer.
degreeU(), _importer.
degreeV() );
1220 int dimU = knotsU.size() - _importer.
degreeU() - 1;
1221 int dimV = knotsV.size() - _importer.
degreeV() - 1;
1224 std::vector< ACG::Vec3d > controlPolygon;
1226 for (
int i = 0; i < dimU; ++i)
1228 controlPolygon.clear();
1230 for (
int j = 0; j < dimV; ++j){
1231 controlPolygon.push_back( (
ACG::Vec3d) _importer.
vertex( cpIndices[dimU * j + i] ) );
1234 _importer.currentSurface()->add_vector_m(controlPolygon);
1237 _importer.currentSurface()->set_knots_m(knotsU);
1238 _importer.currentSurface()->set_knots_n(knotsV);
1255 bool isType = faceCount != 0;
1256 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1257 isType = isType || curveCount != 0;
1260 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1261 isType = isType || surfaceCount != 0;
1266 if (!isType && currentVertexCount != 0 ) {
1269 _importer.setCurrentGroup(0);
1276 ptr::shared_ptr<QTextStream> streamPointer;
1277 ptr::shared_ptr<QFile> sourceFile;
1279 if (_bufferedFile.isNull() || _bufferedFile.isEmpty())
1282 sourceFile.reset(
new QFile(_filename));
1283 if(!sourceFile->open(QFile::ReadOnly))
1285 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1 while checking Types").arg(_filename) );
1288 streamPointer.reset(
new QTextStream(sourceFile.get()));
1292 streamPointer.reset(
new QTextStream(&_bufferedFile));
1294 QTextStream input(streamPointer->device());
1296 QTextStream lineData;
1299 if ( input.status()!=QTextStream::Ok ){
1300 emit log(
LOGERR, tr(
"readOBJFile : cannot read file %1 while checking Types (is the file corrupt?)").arg(_filename) );
1304 ReaderMode mode = NONE;
1308 QString nextKeyWrd = QLatin1String(
"");
1310 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1311 unsigned int curveCount = 0;
1314 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1315 unsigned int surfaceCount = 0;
1321 int PolyMeshCount = 0;
1322 int TriMeshCount = 0;
1324 OBJImporter::ObjectOptions options = OBJImporter::NONE;
1327 bool inGroup =
false;
1329 bool firstFace =
true;
1331 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1332 QString currentGroupName;
1336 while( !input.atEnd())
1338 line = input.readLine();
1339 if ( input.status()!=QTextStream::Ok ){
1340 emit log(
LOGERR, tr(
"readOBJFile : Warning! Could not read file properly!"));
1345 line = line.trimmed();
1348 if ( line.isEmpty() || line[0] == QLatin1Char(
'#') || line[0].isSpace() ) {
1352 stream.setString(&line);
1356 if (nextKeyWrd == QLatin1String(
""))
1359 keyWrd = nextKeyWrd;
1360 nextKeyWrd = QLatin1String(
"");
1364 if (mode == NONE && keyWrd == QLatin1String(
"call")){
1368 include =stream.readLine();
1371 QString includeStr = include.trimmed();
1373 if ( !includeStr.isEmpty() ){
1375 if (includeStr[0] == QLatin1Char(
'.')){
1376 includeStr = includeStr.right( includeStr.length()-1 );
1378 QFileInfo fi(_filename);
1380 includeStr = fi.path() + QDir::separator() + includeStr;
1383 _includes.append( includeStr );
1390 else if (mode == NONE && keyWrd == QLatin1String(
"v"))
1395 x = getFloat(stream);
1396 y = getFloat(stream);
1397 z = getFloat(stream);
1399 if ( stream.status()==QTextStream::Ok )
1402 emit log(
LOGERR, tr(
"Could not add Vertex %1. Possible NaN or Inf?").arg(_importer.
n_vertices()));
1406 else if (mode == NONE && keyWrd == QLatin1String(
"g")){
1414 grpName = stream.readLine();
1416 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1417 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1419 int id = _importer.addGroup(grpName);
1420 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1422 currentGroupName = grpName;
1423 currentGroupName.remove(QLatin1String(
".obj"));
1425 _importer.setCurrentGroup(
id);
1432 options = OBJImporter::NONE;
1437 else if (mode == NONE && keyWrd == QLatin1String(
"f")){
1442 _importer.setCurrentGroup(0);
1448 int verticesPerFace = 0;
1453 faceLine = stream.readLine();
1454 lineData.setString( &faceLine );
1457 while ( !lineData.atEnd() )
1467 int found=vertex.indexOf(QLatin1String(
"/"));
1473 QString vertexEntry = vertex.left(found);
1474 tmp.setString( &vertexEntry );
1479 if ( tmp.status()!=QTextStream::Ok )
1480 emit log(
LOGERR, tr(
"readOBJFile : Error reading vertex index!"));
1485 tmp.setString( &vertex );
1488 if ( tmp.status()!=QTextStream::Ok )
1489 emit log(
LOGERR, tr(
"readOBJFile : Error reading vertex index!"));
1506 if( verticesPerFace > 3 ) {
1507 options = OBJImporter::POLYMESH;
1509 }
else if ( verticesPerFace == 3 ) {
1510 options = OBJImporter::TRIMESH;
1515 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1518 if ( (mode == NONE && keyWrd == QLatin1String(
"curv")) || (mode == CURVE && keyWrd == QLatin1String(
"curv_add")) ){
1526 if ( keyWrd == QLatin1String(
"curv") ) {
1530 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1531 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1533 QString
name = currentGroupName;
1534 if (name.size() == 0)
1535 name = QLatin1String(
"DefaultGroup");
1537 name.append(QString(
"_curve_%1").arg(curveCount));
1538 int id = _importer.addGroup(name);
1540 if (_importer.numCurves() == 0) {
1541 if (currentGroupName.size() == 0)
1542 _importer.setGroupName(
id, QString(
"DefaultGroup"));
1544 _importer.setGroupName(
id, currentGroupName);
1546 if (curveCount == 1) {
1547 int first = _importer.getCurveGroupId(0);
1548 QString tmp = _importer.groupName(first);
1549 tmp.append(QString(
"_curve_0"));
1550 _importer.setGroupName(first, tmp);
1552 _importer.setGroupName(
id, name);
1554 _importer.setCurveParentId(
id, parentId);
1555 _importer.setCurrentGroup(
id);
1556 _importer.setCurveGroupId(curveCount,
id);
1561 options = OBJImporter::CURVE;
1567 curveLine=stream.readLine();
1570 if ( curveLine.endsWith(QLatin1String(
"\\"))){
1571 curveLine = curveLine.left( curveLine.length()-1);
1572 nextKeyWrd = QLatin1String(
"curv_add");
1575 lineData.setString( &curveLine );
1578 if ( keyWrd == QLatin1String(
"curv") ) {
1580 trash = getDouble(lineData);
1581 trash = getDouble(lineData);
1585 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1591 if ( lineData.status()==QTextStream::Ok ){
1600 else if (mode == CURVE && keyWrd == QLatin1String(
"end")){
1605 options = OBJImporter::TRIMESH;
1610 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1613 if ( (mode == NONE && keyWrd == QLatin1String(
"surf")) || (mode == SURFACE && keyWrd == QLatin1String(
"surf_add")) ){
1621 if ( keyWrd == QLatin1String(
"surf") ){
1625 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1626 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1628 QString
name = currentGroupName;
1629 if (name.size() == 0)
1630 name = QLatin1String(
"DefaultGroup");
1632 name.append(QString(
"_surface_%1").arg(surfaceCount));
1633 int id = _importer.addGroup(name);
1635 if (_importer.numSurfaces() == 0) {
1636 if (currentGroupName.size() == 0)
1637 _importer.setGroupName(
id,
"DefaultGroup");
1639 _importer.setGroupName(
id, currentGroupName);
1641 if (surfaceCount == 1) {
1642 int first = _importer.getSurfaceGroupId(0);
1643 QString tmp = _importer.groupName(first);
1644 tmp.append(QString(
"_surface_0"));
1645 _importer.setGroupName(first, tmp);
1647 _importer.setGroupName(
id, name);
1649 _importer.setSurfaceParentId(
id, parentId);
1650 _importer.setCurrentGroup(
id);
1651 _importer.setSurfaceGroupId(surfaceCount,
id);
1656 options = OBJImporter::SURFACE;
1662 surfLine = stream.readLine();
1665 if ( surfLine.endsWith(QLatin1String(
"\\"))){
1666 surfLine = surfLine.left(surfLine.length()-1);
1667 nextKeyWrd = QLatin1String(
"surf_add");
1670 lineData.setString( &surfLine );
1673 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1679 if ( lineData.status()==QTextStream::Ok ){
1687 else if (mode == SURFACE && keyWrd == QLatin1String(
"end")){
1692 options = OBJImporter::TRIMESH;
1700 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1701 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1706 if (keyWrd != QLatin1String(
"call")) {
1708 if (keyWrd == QLatin1String(
"v") && !inGroup) {
1709 _importer.setCurrentGroup(0);
1711 forceTriangleMesh_ =
false;
1712 forcePolyMesh_ =
true;
1715 for (
unsigned int i = 0; i < _importer.
n_vertices(); ++i)
1721 if (!(currentOptions & OBJImporter::CURVE) &&
1722 !(currentOptions & OBJImporter::SURFACE) &&
1723 (currentOptions != OBJImporter::NONE))
1729 if (TriMeshCount == 0 && PolyMeshCount == 0)
1734 if (forceTriangleMesh_){
1739 if (forcePolyMesh_){
1746 if ( OpenFlipper::Options::gui() && triMeshHandling_ != 0 ){
1748 switch( triMeshHandling_->currentIndex() ){
1749 case TYPEAUTODETECT :
1753 QMetaObject::invokeMethod(
this,
"handleTrimeshDialog",Qt::BlockingQueuedConnection);
1754 if (trimeshOptions_ == OBJImporter::TRIMESH )
1756 else if (trimeshOptions_ == OBJImporter::POLYMESH)
1775 void FileOBJPlugin::handleTrimeshDialog()
1778 QPushButton *detectButton = msgBox.addButton(tr(
"Auto-Detect"), QMessageBox::ActionRole);
1779 QPushButton *triButton = msgBox.addButton(tr(
"Open as triangle mesh"), QMessageBox::ActionRole);
1780 QPushButton *polyButton = msgBox.addButton(tr(
"Open as poly mesh"), QMessageBox::ActionRole);
1781 msgBox.setWindowTitle( tr(
"Mesh types in file") );
1782 msgBox.setText( tr(
"You are about to open a file containing one or more mesh types. \n\n Which mesh type should be used?") );
1783 msgBox.setDefaultButton( detectButton );
1787 if (msgBox.clickedButton() == triButton)
1788 trimeshOptions_ = OBJImporter::TRIMESH ;
1789 else if (msgBox.clickedButton() == polyButton)
1790 trimeshOptions_ = OBJImporter::POLYMESH ;
1800 QStringList includes;
1802 QFile sourceFile(_filename);
1803 if (!sourceFile.open(QFile::ReadOnly))
1805 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1 while checking Types").arg(_filename));
1808 QByteArray bufferedFile = QByteArray();
1811 unsigned long freeMem = Utils::Memory::queryFreeRAM();
1812 unsigned long fs = sourceFile.size() / 1024 / 1024;
1813 if (freeMem >= 2*fs)
1815 bufferedFile = sourceFile.readAll();
1819 checkTypes( bufferedFile, _filename, importer, includes );
1824 for (
int i=0; i < includes.size(); i++){
1830 objIDs.push_back(
id );
1834 if ( ! includes.empty() )
1835 importer.addGroup( QFileInfo(_filename).fileName() );
1840 forceTriangleMesh_ =
false;
1841 forcePolyMesh_ =
false;
1847 readOBJFile( bufferedFile, _filename, importer );
1855 if ( importer.numGroups() > 1){
1857 bool dataControlExists =
false;
1858 pluginExists(
"datacontrol", dataControlExists );
1860 if ( dataControlExists ){
1862 std::vector<OBJImporter::ObjectOptions> options = importer.
objectOptions();
1863 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1864 std::map<int, QString> groupNames;
1867 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1868 std::vector< std::vector<int> > curveGroups;
1869 std::vector<int> curveIds;
1870 int lastCurveParent = -2;
1873 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1874 std::vector< std::vector<int> > surfaceGroups;
1875 std::vector<int> surfaceIds;
1876 int lastSurfaceParent = -2;
1878 for(
unsigned int i = 0; i < importer.objectCount(); i++) {
1881 if (options[i] != NONE) {
1884 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1885 if (options[i] & OBJImporter::CURVE) {
1887 groupNames[obj->
id()] = importer.groupName(importer.getCurveParentId(i));
1890 if (lastCurveParent == -2) {
1891 lastCurveParent = importer.getCurveParentId(i);
1892 curveIds.push_back(obj->
id());
1895 curveIds.push_back(parent->
id());
1897 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1898 if (pos != objIDs.end())
1902 }
else if (lastCurveParent != importer.getCurveParentId(i)) {
1903 lastCurveParent = importer.getCurveParentId(i);
1904 curveGroups.push_back(curveIds);
1906 curveIds.push_back(obj->
id());
1909 curveIds.push_back(parent->
id());
1911 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1912 if (pos != objIDs.end())
1917 curveIds.push_back(obj->
id());
1921 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1922 if (options[i] & OBJImporter::SURFACE) {
1924 groupNames[obj->
id()] = importer.groupName(importer.getSurfaceParentId(i));
1927 if (lastSurfaceParent == -2) {
1928 lastSurfaceParent = importer.getSurfaceParentId(i);
1929 surfaceIds.push_back(obj->
id());
1932 surfaceIds.push_back(parent->
id());
1933 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1934 if (pos != objIDs.end())
1938 }
else if (lastSurfaceParent != importer.getSurfaceParentId(i)) {
1939 lastSurfaceParent = importer.getSurfaceParentId(i);
1940 surfaceGroups.push_back(surfaceIds);
1942 surfaceIds.push_back(obj->
id());
1945 surfaceIds.push_back(parent->
id());
1946 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1947 if (pos != objIDs.end())
1952 surfaceIds.push_back(obj->
id());
1956 if ( (options[i] & OBJImporter::TRIMESH) || (options[i] & OBJImporter::POLYMESH) )
1957 objIDs.push_back( obj->
id() );
1959 std::cerr <<
"Object is NULL!" << std::endl;
1964 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1966 curveGroups.push_back(curveIds);
1967 std::vector< std::vector<int> >::iterator it = curveGroups.begin();
1968 for (; it != curveGroups.end(); ++it) {
1970 if (it->size() > 2) {
1971 if (groupNames[it->back()].size() == 0)
1972 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it, QFileInfo(_filename).fileName());
1974 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it, groupNames[it->back()]);
1979 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1981 surfaceGroups.push_back(surfaceIds);
1982 std::vector< std::vector<int> >::iterator it2 = surfaceGroups.begin();
1983 for (; it2 != surfaceGroups.end(); ++it2) {
1985 if (it2->size() > 2) {
1986 if (groupNames[it2->back()].size() == 0)
1987 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it2, QFileInfo(_filename).fileName());
1989 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it2, groupNames[it2->back()]);
1995 if (objIDs.size() > 1)
1996 returnID = RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", objIDs, importer.groupName(0));
2001 for(
unsigned int i=0; i < importer.objectCount(); i++){
2004 if(
object == NULL)
continue;
2009 if ( returnID == -1)
2010 returnID =
object->id();
2034 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2044 if ( importer.hasTexture(i) && !importer.
hasOption( i, OBJImporter::FORCE_NOTEXTURES ) ){
2047 addTextures( importer, i );
2050 emit setTextureMode(
"OBJ Data",
"indexProperty=OriginalTexIndexMapping", object->
id() );
2052 emit switchTexture(
"OBJ Data", object->
id() );
2060 emit openedFile( object->
id() );
2063 forceTriangleMesh_ =
false;
2064 forcePolyMesh_ =
false;
2077 forceTriangleMesh_ =
true;
2079 forcePolyMesh_ =
true;
2086 bool FileOBJPlugin::saveObject(
int _id, QString _filename)
2090 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2095 std::string filename = std::string( _filename.toUtf8() );
2097 std::fstream objStream( filename.c_str(), std::ios_base::out );
2101 emit log(
LOGERR, tr(
"saveObject : cannot not open file %1").arg(_filename) );
2108 object->setFromFileName(_filename);
2109 object->setName(object->
filename());
2114 if ( writeMesh( objStream, _filename, *polyObj->
mesh(), polyObj->
id() ) ){
2116 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2122 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2129 object->setFromFileName(_filename);
2130 object->setName(object->
filename());
2135 if ( writeMesh( objStream, _filename, *triObj->
mesh(), triObj->
id() )) {
2137 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2143 emit log(
LOGERR, tr(
"Unable to save ") + _filename );
2148 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2151 object->setFromFileName(_filename);
2152 object->setName(object->
filename());
2157 if ( writeCurve( objStream, _filename, bscObj->
splineCurve()) ) {
2159 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2165 emit log(
LOGERR, tr(
"Unable to save ") + _filename );
2171 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 2174 object->setFromFileName(_filename);
2175 object->setName(object->
filename());
2180 if ( writeSurface( objStream, _filename, bssObj->
splineSurface()) ) {
2182 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2188 emit log(
LOGERR, tr(
"Unable to save ") + object->
path() + OpenFlipper::Options::dirSeparator() +
object->name());
2196 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2204 void FileOBJPlugin::slotHandleCheckBoxes(
bool _checked) {
2206 if(saveCopyTextures_) {
2207 saveCreateTexFolder_->setEnabled(_checked);
2208 saveCreateTexFolder_->setChecked(_checked);
2216 if (saveOptions_ == 0){
2218 saveOptions_ =
new QWidget();
2219 QVBoxLayout* layout =
new QVBoxLayout();
2220 layout->setAlignment(Qt::AlignTop);
2222 saveFaceColor_ =
new QCheckBox(
"Save Face Colors");
2223 layout->addWidget(saveFaceColor_);
2225 saveAlpha_ =
new QCheckBox(
"Save Color Alpha");
2226 layout->addWidget(saveAlpha_);
2228 saveNormals_ =
new QCheckBox(
"Save Normals");
2229 layout->addWidget(saveNormals_);
2231 saveTexCoords_ =
new QCheckBox(
"Save Texture Coordinates");
2232 layout->addWidget(saveTexCoords_);
2234 saveTextures_ =
new QCheckBox(
"Save Textures");
2235 layout->addWidget(saveTextures_);
2237 saveCopyTextures_ =
new QCheckBox(
"Copy Texture Files");
2238 layout->addWidget(saveCopyTextures_);
2240 saveCreateTexFolder_ =
new QCheckBox(
"Create Textures Folder");
2241 layout->addWidget(saveCreateTexFolder_);
2243 savePrecisionLabel_ =
new QLabel(
"Writer Precision");
2244 layout->addWidget(savePrecisionLabel_);
2246 savePrecision_ =
new QSpinBox();
2247 savePrecision_->setMinimum(1);
2248 savePrecision_->setMaximum(12);
2249 savePrecision_->setValue(6);
2250 layout->addWidget(savePrecision_);
2252 saveDefaultButton_ =
new QPushButton(
"Make Default");
2253 layout->addWidget(saveDefaultButton_);
2255 saveOptions_->setLayout(layout);
2257 connect(saveDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotSaveDefault()));
2258 connect(saveCopyTextures_, SIGNAL(toggled(
bool)),
this, SLOT(slotHandleCheckBoxes(
bool)));
2260 saveFaceColor_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/FaceColor",
true).toBool() );
2261 saveAlpha_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Alpha",
true).toBool() );
2262 saveNormals_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Normals",
true).toBool() );
2263 saveTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/TexCoords",
true).toBool() );
2264 saveTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Textures",
true).toBool() );
2265 saveCopyTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/CopyTextures",
true).toBool() );
2266 saveCreateTexFolder_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/CreateTexFolder",
true).toBool() );
2268 slotHandleCheckBoxes(saveCopyTextures_->isChecked());
2271 return saveOptions_;
2278 if (loadOptions_ == 0){
2280 loadOptions_ =
new QWidget();
2281 QVBoxLayout* layout =
new QVBoxLayout();
2282 layout->setAlignment(Qt::AlignTop);
2284 QLabel* label =
new QLabel(tr(
"If file contains meshes:"));
2286 layout->addWidget(label);
2288 triMeshHandling_ =
new QComboBox();
2289 triMeshHandling_->addItem( tr(
"Detect correct type") );
2290 triMeshHandling_->addItem( tr(
"Ask") );
2291 triMeshHandling_->addItem( tr(
"Open as PolyMesh") );
2292 triMeshHandling_->addItem( tr(
"Open as TriangleMesh") );
2294 layout->addWidget(triMeshHandling_);
2296 loadFaceColor_ =
new QCheckBox(
"Load Face Colors");
2297 layout->addWidget(loadFaceColor_);
2299 loadNormals_ =
new QCheckBox(
"Load Normals");
2300 layout->addWidget(loadNormals_);
2302 loadTexCoords_ =
new QCheckBox(
"Load Texture Coordinates");
2303 layout->addWidget(loadTexCoords_);
2305 loadTextures_ =
new QCheckBox(
"Load Textures");
2306 layout->addWidget(loadTextures_);
2308 loadDefaultButton_ =
new QPushButton(
"Make Default");
2309 layout->addWidget(loadDefaultButton_);
2311 loadOptions_->setLayout(layout);
2313 connect(loadDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotLoadDefault()));
2316 triMeshHandling_->setCurrentIndex(
OpenFlipperSettings().value(
"FileObj/Load/TriMeshHandling",TYPEAUTODETECT).toInt() );
2318 loadFaceColor_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/FaceColor",
true).toBool() );
2319 loadNormals_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/Normals",
true).toBool() );
2320 loadTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/TexCoords",
true).toBool() );
2321 loadTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/Textures",
true).toBool() );
2324 return loadOptions_;
2348 #if QT_VERSION < 0x050000 int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
void setDegreeV(int _degree)
set degree V direction
void useVertex(int _vertex_index)
used vertices
void slotLoadDefault()
Slot called when user wants to save the given Load options as default.
Type for a MeshObject containing a triangle mesh.
void setNormal(int _index, int _normalID)
set vertex normal
QWidget * saveOptionsWidget(QString)
int currentObject()
get id of the active object
void update_normals()
Compute normals for all primitives.
QString filename() const
return the filename of the object
bool getObject(int _identifier, BSplineCurveObject *&_object)
bool dataType(DataType _type) const
VertexHandle addVertex(const Vec3f &_point)
add a vertex with coordinate _point
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
QString path() const
return the path to the object ( defaults to "." if unset )
unsigned int n_vertices()
Global Properties.
void setObjectOptions(ObjectOptions _options)
DrawMode SOLID_2DTEXTURED_FACE_SHADED
draw per halfedge textured faces
void setFromFileName(const QString &_filename)
QWidget * loadOptionsWidget(QString)
MeshT * mesh()
return a pointer to the mesh
void initializePlugin()
Initialize Plugin.
QString path()
Path of the OBJ file.
void setDegreeU(int _degree)
set degree
int addTexCoord(const Vec2f &_coord)
add texture coordinates
int degreeV()
get current degree
void checkTypes(QByteArray &_bufferedFile, QString _filename, OBJImporter &_importer, QStringList &_includes)
Reader functions.
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void backupTextureCoordinates(MeshT &_mesh)
creates a backup of the original per vertex/face texture coordinates
Vec3f vertex(unsigned int _index)
get vertex with given index
const DataType DATA_GROUP(1)
Items used for Grouping.
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
ACG::SceneGraph::BSplineCurveNodeT< BSplineCurve > * splineCurveNode()
Get the scenegraph Node.
bool hasNormals(int _objectID)
Query Object Options.
BaseObject * object(int _objectID)
return object with given index
std::vector< int > IdList
Standard Type for id Lists used for scripting.
int degreeU()
get current degree
FileOBJPlugin()
Constructor.
#define DATA_BSPLINE_CURVE
void convertToOBJName(QString &_name)
Convert non-valid filenames (e.g. of groups that end with .jpg) to valid .objs.
void update_face_normals()
Update normal vectors for all faces.
Type for a Meshobject containing a poly mesh.
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
BSplineCurve * splineCurve()
return a pointer to the spline curve
QString name()
Return a name for the plugin.
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
#define DATA_BSPLINE_SURFACE
#define DATA_TRIANGLE_MESH
void setDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, int _viewer)
Set the draw Mode of a Viewer. .
std::vector< ObjectOptions > & objectOptions()
Object Options for all objects.
BSplineSurface * splineSurface()
return a pointer to the spline curve
void setObject(BaseObject *_object, int _groupId)
add an object
void addMaterial(std::string _materialName)
Add a material.
bool hasOption(unsigned int _id, ObjectOptions _option)
check if object with given id has given option
int addNormal(const Vec3f &_normal)
add a normal
MaterialList & materials()
return all loaded materials