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());
93 saveCreateTexFolder_(0),
94 savePrecisionLabel_(0),
96 saveDefaultButton_(0),
104 loadDefaultButton_(0),
105 forceTriangleMesh_(false),
106 forcePolyMesh_(false),
107 textureIndexPropFetched_(false),
120 return QString( tr(
"Alias/Wavefront ( *.obj )") );
126 return QString( tr(
"Alias/Wavefront ( *.obj )") );
134 #ifdef ENABLE_BSPLINECURVE_SUPPORT 138 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 147 bool FileOBJPlugin::readMaterial(QString _filename,
OBJImporter& _importer)
150 static QString keyWrd;
151 static QString textureName;
156 static QString matName;
160 static float f1,f2,f3;
165 static bool insideDefintion;
166 insideDefintion =
false;
167 static int textureId;
172 QFile matFile(_filename);
173 if (!matFile.open(QFile::ReadOnly))
175 emit log(
LOGERR, tr(
"readMaterial : cannot open file %1").arg(_filename));
179 QTextStream matStream(&matFile);
180 if ( matStream.status()!=QTextStream::Ok ){
181 emit log(
LOGERR, tr(
"readMaterial : cannot open stream %1").arg(_filename) );
189 while( matStream.status() == QTextStream::Ok && !matStream.atEnd() )
191 line = matStream.readLine();
192 if ( matStream.status() != QTextStream::Ok ){
193 emit log(
LOGERR, tr(
"readMaterial : Warning! Could not read file properly!"));
197 if ( line.isEmpty() )
200 QTextStream stream(&line);
204 if( ( line[0].isSpace() && line[0] != QLatin1Char(
'\t') ) || line[0] == QLatin1Char(
'#') )
206 if (insideDefintion && !matName.isEmpty() && mat.is_valid())
208 _importer.
materials()[matName.toStdString()] = mat;
213 else if (keyWrd == QLatin1String(
"newmtl"))
216 insideDefintion =
true;
219 else if (keyWrd == QLatin1String(
"Kd"))
221 f1 = getFloat(stream);
222 f2 = getFloat(stream);
223 f3 = getFloat(stream);
225 if( stream.status()==QTextStream::Ok )
226 mat.set_Kd(f1,f2,f3);
229 else if (keyWrd == QLatin1String(
"Ka"))
231 f1 = getFloat(stream);
232 f2 = getFloat(stream);
233 f3 = getFloat(stream);
235 if( stream.status()==QTextStream::Ok )
236 mat.set_Ka(f1,f2,f3);
239 else if (keyWrd == QLatin1String(
"Ks"))
241 f1 = getFloat(stream);
242 f2 = getFloat(stream);
243 f3 = getFloat(stream);
245 if( stream.status()==QTextStream::Ok )
246 mat.set_Ks(f1,f2,f3);
249 else if (keyWrd == QLatin1String(
"Ke"))
251 f1 = getFloat(stream);
252 f2 = getFloat(stream);
253 f3 = getFloat(stream);
255 if( stream.status()==QTextStream::Ok )
256 mat.set_Ke(f1,f2,f3);
260 else if (keyWrd == QLatin1String(
"illum"))
264 if(stream.status() == QTextStream::Ok)
268 else if (keyWrd == QLatin1String(
"Ns"))
270 f1 = getFloat(stream);
272 if(stream.status() == QTextStream::Ok)
276 else if (keyWrd == QLatin1String(
"Ni"))
278 f1 = getFloat(stream);
280 if(stream.status() == QTextStream::Ok)
284 else if (keyWrd == QLatin1String(
"Tr"))
286 f1 = getFloat(stream);
288 if(stream.status() == QTextStream::Ok)
292 else if (keyWrd == QLatin1String(
"d"))
295 f1 = getFloat(stream);
297 if(stream.status() == QTextStream::Ok && !mat.has_Tr())
301 else if (keyWrd == QLatin1String(
"map_"))
310 else if (keyWrd == QLatin1String(
"map_Kd") ) {
313 textureName = stream.readLine();
314 textureName = textureName.trimmed();
315 if ( ! textureName.isEmpty() )
316 mat.set_map_Kd( textureName.toStdString(), textureId++ );
319 if ( matStream.status() == QTextStream::Ok && insideDefintion && mat.is_valid() && !matName.isEmpty())
320 _importer.
materials()[matName.toStdString()] = mat;
323 emit log( tr(
"%1 materials loaded.").arg( _importer.
materials().size() ) );
330 void FileOBJPlugin::createAllGroupObjects(
OBJImporter& _importer) {
332 for(
unsigned int i = 0; i < _importer.numGroups(); ++i) {
335 QString
name = _importer.groupName(i);
338 if ( _importer.isTriangleMesh( i ) ){
350 object->setPath(_importer.
path());
351 object->setName(name);
354 }
else if (_importer.isPolyMesh( i )) {
365 object->setPath(_importer.
path());
366 object->setName(name);
370 #ifdef ENABLE_BSPLINECURVE_SUPPORT 372 else if (_importer.isCurve( i )) {
383 object->setPath(_importer.
path());
384 object->setName(name);
390 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 392 else if (_importer.isSurface( i )) {
403 object->setPath(_importer.
path());
404 object->setName(name);
411 if (OpenFlipper::Options::gui() && loadOptions_ != 0) {
413 if (!loadFaceColor_->isChecked())
414 _importer.
setOption(OBJImporter::FORCE_NOCOLOR, i);
416 if (!loadNormals_->isChecked())
417 _importer.
setOption(OBJImporter::FORCE_NONORMALS, i);
419 if (!loadTexCoords_->isChecked() || !loadTextures_->isChecked())
420 _importer.
setOption(OBJImporter::FORCE_NOTEXTURES, i);
430 QString n = fi.baseName();
432 _name = n.trimmed() +
".obj";
436 template <
class MeshT>
440 if (_mesh.has_vertex_texcoords2D()) {
443 if (!_mesh.get_property_handle(oldVertexCoords,
"Original Per Vertex Texture Coords"))
444 _mesh.add_property(oldVertexCoords,
"Original Per Vertex Texture Coords");
446 for (
typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
447 _mesh.property(oldVertexCoords, *v_it) = _mesh.texcoord2D(*v_it);
452 if (_mesh.has_halfedge_texcoords2D()) {
455 if (!_mesh.get_property_handle(oldHalfedgeCoords,
"Original Per Face Texture Coords"))
456 _mesh.add_property(oldHalfedgeCoords,
"Original Per Face Texture Coords");
458 for (
typename MeshT::HalfedgeIter he_it = _mesh.halfedges_begin(); he_it != _mesh.halfedges_end(); ++he_it)
459 _mesh.property(oldHalfedgeCoords, *he_it) = _mesh.texcoord2D(*he_it);
466 void FileOBJPlugin::addTextures(
OBJImporter& _importer,
int _objectID ){
476 std::map< int,int > newMapping;
480 const std::vector<std::string> matNames = _importer.
usedMaterials( _objectID );
482 for (
unsigned int i=0; i < matNames.size(); i++){
484 Material& material = _importer.
materials()[ matNames[i] ];
488 QString textureBlock = QString( material.map_Kd().c_str());
491 QStringList options = textureBlock.split(
" ",QString::SkipEmptyParts);
493 while ( options.size() > 1 ) {
494 if ( options[0] ==
"-blendu" ) {
497 }
else if ( options[0] ==
"-blendv" ) {
500 }
else if ( options[0] ==
"-cc" ) {
503 }
else if ( options[0] ==
"-clamp" ) {
506 }
else if ( options[0] ==
"-mm" ) {
510 }
else if ( options[0] ==
"-o" ) {
515 }
else if ( options[0] ==
"-s" ) {
520 }
else if ( options[0] ==
"-t" ) {
525 }
else if ( options[0] ==
"-texres" ) {
533 QString fullName = _importer.
path() + QDir::separator() + options.join(
" ");
535 QFileInfo info(fullName);
536 if ( info.exists() ) {
537 emit addMultiTexture(
"OBJ Data", info.baseName().trimmed(), fullName,
object->id(), textureId );
539 emit log(
LOGWARN, tr(
"Unable to load texture image %1").arg( QString(material.map_Kd().c_str()) ) );
540 addMultiTexture(
"OBJ Data",
"Unknown Texture image " + QString::number(textureId),
"unknown.png", object->
id(), textureId );
543 newMapping[ material.map_Kd_index() ] = textureId;
557 PolyMesh::FaceIter f_it;
558 PolyMesh::FaceIter f_end = mesh.faces_end();
560 if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
563 for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
564 mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
578 TriMesh::FaceIter f_it;
579 TriMesh::FaceIter f_end = mesh.faces_end();
581 if (! mesh.get_property_handle(indexProperty,TEXTUREINDEX) )
584 for (f_it = mesh.faces_begin(); f_it != f_end; ++f_it)
585 mesh.property(indexProperty, *f_it) = newMapping[ mesh.property(indexProperty, *f_it) ];
594 void FileOBJPlugin::readOBJFile(QByteArray& _bufferedFile, QString _filename,
OBJImporter& _importer)
596 QString path = QFileInfo(_filename).absolutePath();
597 ptr::shared_ptr<QTextStream> streamPointer;
598 ptr::shared_ptr<QFile> sourceFile;
601 if (_bufferedFile.isNull())
603 sourceFile.reset(
new QFile(_filename) );
604 if(!sourceFile->open(QFile::ReadOnly))
606 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1").arg(_filename) );
611 streamPointer.reset(
new QTextStream(sourceFile.get()));
615 streamPointer.reset(
new QTextStream(&_bufferedFile));
617 QTextStream input(streamPointer->device());
620 QTextStream lineData;
622 if ( input.status() != QTextStream::Ok){
623 emit log(
LOGERR, tr(
"readOBJFile : cannot read file %1 is the file corrupt?").arg(_filename) );
627 QString currentFileName = QFileInfo(_filename).fileName() ;
629 ReaderMode mode = NONE;
633 QString nextKeyWrd = QLatin1String(
"");
635 #ifdef ENABLE_BSPLINECURVE_SUPPORT 636 unsigned int curveCount = 0;
639 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 640 unsigned int surfaceCount = 0;
646 std::vector<VertexHandle> vhandles;
647 std::vector<int> face_texcoords;
650 #if defined (ENABLE_BSPLINECURVE_SUPPORT) || defined (ENABLE_BSPLINESURFACE_SUPPORT) 651 std::vector< int > cpIndices;
652 std::vector< double > knotsU,knotsV;
658 int currentVertexCount = 0;
661 int currentTextureCoordCount = 0;
664 int currentNormalCount = 0;
667 bool inGroup =
false;
669 bool firstFace =
true;
671 _importer.setPath( path );
674 _importer.setGroupName(0, currentFileName);
677 createAllGroupObjects(_importer);
679 while( !input.atEnd() )
681 line=input.readLine();
682 if ( input.status() == QTextStream::ReadCorruptData ){
683 emit log(
LOGERR, tr(
"readOBJFile : Warning! Could not read file properly!"));
688 line = line.trimmed();
691 if ( line.isEmpty() || line[0] == QLatin1Char(
'#') || line[0].isSpace() ) {
695 stream.setString(&line,QIODevice::ReadOnly);
699 if (nextKeyWrd == QLatin1String(
""))
703 nextKeyWrd = QLatin1String(
"");
707 if (mode == NONE && keyWrd == QLatin1String(
"mtllib"))
712 matString = stream.readLine();
714 QString matFile = path + QDir::separator() + matString.trimmed();
716 emit log( tr(
"Loading material file: %1").arg( matFile ) );
718 readMaterial( matFile, _importer );
722 else if (mode == NONE && keyWrd == QLatin1String(
"usemtl"))
727 emit log(
LOGERR, tr(
"Warning! Material '%1' not defined in material file").arg( matname ) );
728 matname=QLatin1String(
"");
732 Material& mat = _importer.
materials()[matname.toStdString()];
734 if ( mat.has_Texture() ){
737 _importer.useMaterial( matname.toStdString() );
743 else if (mode == NONE && keyWrd == QLatin1String(
"v"))
748 currentVertexCount++;
751 else if (mode == NONE && keyWrd == QLatin1String(
"vt"))
757 currentTextureCoordCount++;
759 u = getFloat(stream);
760 v = getFloat(stream);
762 if ( stream.status() == QTextStream::Ok ){
768 emit log(
LOGERR, tr(
"Could not add TexCoord. Possible NaN or Inf?\nOnly single 2D texture coordinate per vertex allowed"));
774 else if (mode == NONE && keyWrd == QLatin1String(
"vn"))
780 currentNormalCount++;
782 x = getFloat(stream);
783 y = getFloat(stream);
784 z = getFloat(stream);
786 if ( stream.status() == QTextStream::Ok ){
789 emit log(
LOGERR, tr(
"Could not read normal. Possible NaN or Inf?"));
794 else if (mode == NONE && keyWrd == QLatin1String(
"deg"))
798 if ( stream.status() == QTextStream::Ok )
803 if ( stream.status() == QTextStream::Ok )
808 else if (mode == NONE && keyWrd == QLatin1String(
"g")){
813 groupName = stream.readLine();
816 currentFileName = groupName;
819 int id = _importer.groupId(groupName);
821 std::cerr <<
"Error: Group has not been added before!" << std::endl;
824 _importer.setCurrentGroup(
id);
831 else if (mode == NONE && keyWrd == QLatin1String(
"f"))
836 _importer.setCurrentGroup(0);
841 int component(0), nV(0);
845 face_texcoords.clear();
849 faceLine = stream.readLine();
850 lineData.setString(&faceLine);
853 while ( !lineData.atEnd() )
862 int found=vertex.indexOf(QLatin1String(
"/"));
868 QString vertexEntry = vertex.left(found);
869 tmp.setString( &vertexEntry );
872 if ( vertexEntry.isEmpty() ) {
874 vertex = vertex.right(vertex.length()-(found+1));
887 vertex = vertex.right(vertex.length()-(found+1));
892 tmp.setString( &vertex );
896 vertex=QLatin1String(
"");
899 if ( tmp.status() != QTextStream::Ok ) {
912 value = currentVertexCount + value + 1;
916 vhandles.push_back( value-1 );
924 value = currentTextureCoordCount + value + 1;
927 if (vhandles.empty())
929 emit log (
LOGWARN, tr(
"Texture coordinates defined, but no vertex coordinates found!"));
932 if ((
unsigned int)(value-1) >= _importer.n_texCoords())
934 emit log (
LOGWARN, tr(
"Too many texcoords defined, skipping the rest"));
938 if ( _importer.n_texCoords() > 0 ) {
941 face_texcoords.push_back( value-1 );
943 emit log(
LOGERR, tr(
"Error setting Texture coordinates") );
953 value = currentNormalCount + value + 1;
956 if (vhandles.empty())
958 emit log (
LOGWARN, tr(
"Texture coordinates defined, but no vertex coordinates found!"));
962 if ((
unsigned int)(value-1) >= _importer.n_normals())
964 emit log (
LOGWARN, tr(
"Too many normals defined, skipping the rest"));
969 _importer.
setNormal(vhandles.back(), value-1);
977 }
while ( !vertex.isEmpty() );
984 remove_duplicated_vertices(vhandles);
987 if( vhandles.size() > 2 ){
989 if ( !face_texcoords.empty() )
991 _importer.
addFace(vhandles, face_texcoords );
1005 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1007 else if ( (mode == CURVE && keyWrd == QLatin1String(
"parm")) || (mode == CURVE && keyWrd == QLatin1String(
"parm_add")) ){
1013 paramLine = stream.readLine();
1016 if ( paramLine.endsWith(QLatin1String(
"\\"))){
1017 paramLine = paramLine.left( paramLine.length()-1);
1018 nextKeyWrd = QLatin1String(
"parm_add");
1021 lineData.setString( ¶mLine );
1023 if ( keyWrd != QLatin1String(
"parm_add"))
1027 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1032 knot = getDouble(lineData);
1034 if ( lineData.status() == QTextStream::Ok )
1035 knotsU.push_back( knot );
1040 else if ( (mode == NONE && keyWrd == QLatin1String(
"curv")) || (mode == CURVE && keyWrd == QLatin1String(
"curv_add")) ){
1048 if ( keyWrd == QLatin1String(
"curv") )
1050 int id = _importer.getCurveGroupId(curveCount);
1052 std::cerr <<
"Error: Group has not been added before!" << std::endl;
1055 _importer.setCurrentGroup(
id);
1062 curveLine = stream.readLine();
1065 if ( curveLine.endsWith(QLatin1String(
"\\"))){
1066 curveLine = curveLine.left(curveLine.length()-1);
1067 nextKeyWrd = QLatin1String(
"curv_add");
1070 lineData.setString( &curveLine );
1073 if ( keyWrd == QLatin1String(
"curv") ) {
1075 getDouble(lineData);
1076 getDouble(lineData);
1082 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1092 index = currentVertexCount + index + 1;
1095 if ( lineData.status()==QTextStream::Ok )
1096 cpIndices.push_back( index -1 );
1101 else if (mode == CURVE && keyWrd == QLatin1String(
"end")){
1105 _importer.currentCurve()->set_degree( _importer.
degreeU() );
1106 _importer.currentCurve()->autocompute_knotvector(
false);
1109 std::vector< ACG::Vec3d > controlPolygon;
1111 for (
unsigned int i = 0; i < cpIndices.size(); ++i)
1114 _importer.currentCurve()->set_control_polygon( controlPolygon );
1116 _importer.currentCurve()->set_knots(knotsU);
1126 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1128 else if ( (mode == SURFACE && keyWrd == QLatin1String(
"parm")) || (mode == SURFACE && keyWrd == QLatin1String(
"parm_add")) ){
1134 paramLine = stream.readLine();
1137 if ( paramLine.endsWith(QLatin1String(
"\\"))){
1138 paramLine = paramLine.left(paramLine.length()-1);
1139 nextKeyWrd = QLatin1String(
"parm_add");
1142 lineData.setString( ¶mLine );
1144 if ( keyWrd == QLatin1String(
"parm_add_u"))
1145 tmp = QLatin1String(
"u");
1146 else if ( keyWrd == QLatin1String(
"parm_add_v"))
1147 tmp = QLatin1String(
"v");
1151 std::vector< double >* knots;
1154 if (tmp == QLatin1String(
"u"))
1159 if (nextKeyWrd != QLatin1String(
""))
1160 nextKeyWrd += QLatin1String(
"_") + tmp;
1163 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1168 knot = getDouble(lineData);
1170 if ( lineData.status()==QTextStream::Ok ) {
1171 knots->push_back( knot );
1177 else if ( (mode == NONE && keyWrd == QLatin1String(
"surf")) || (mode == SURFACE && keyWrd == QLatin1String(
"surf_add")) ){
1185 if ( keyWrd == QLatin1String(
"surf") )
1187 int id = _importer.getSurfaceGroupId(surfaceCount);
1189 std::cerr <<
"Error: Group has not been added before!" << std::endl;
1192 _importer.setCurrentGroup(
id);
1199 surfLine = stream.readLine();
1202 if ( surfLine.endsWith(QLatin1String(
"\\"))){
1203 surfLine = surfLine.left(surfLine.length()-1);
1204 nextKeyWrd = QLatin1String(
"surf_add");
1207 lineData.setString( &surfLine );
1210 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1220 index = currentVertexCount + index + 1;
1223 if ( lineData.status()==QTextStream::Ok )
1224 cpIndices.push_back( index -1 );
1229 else if (mode == SURFACE && keyWrd == QLatin1String(
"end")){
1231 if ( _importer.isSurface( _importer.
currentGroup() ) ){
1234 cpIndices.erase(cpIndices.begin());
1235 cpIndices.erase(cpIndices.begin());
1236 cpIndices.erase(cpIndices.begin());
1237 cpIndices.erase(cpIndices.begin());
1240 _importer.currentSurface()->set_degree( _importer.
degreeU(), _importer.
degreeV() );
1243 int dimU = knotsU.size() - _importer.
degreeU() - 1;
1244 int dimV = knotsV.size() - _importer.
degreeV() - 1;
1247 std::vector< ACG::Vec3d > controlPolygon;
1249 for (
int i = 0; i < dimU; ++i)
1251 controlPolygon.clear();
1253 for (
int j = 0; j < dimV; ++j){
1254 controlPolygon.push_back( (
ACG::Vec3d) _importer.
vertex( cpIndices[dimU * j + i] ) );
1257 _importer.currentSurface()->add_vector_m(controlPolygon);
1260 _importer.currentSurface()->set_knots_m(knotsU);
1261 _importer.currentSurface()->set_knots_n(knotsV);
1276 bool isType = faceCount != 0;
1278 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1279 isType = isType || curveCount != 0;
1282 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1283 isType = isType || surfaceCount != 0;
1288 if (!isType && currentVertexCount != 0 ) {
1291 _importer.setCurrentGroup(0);
1299 ptr::shared_ptr<QTextStream> streamPointer;
1300 ptr::shared_ptr<QFile> sourceFile;
1302 if (_bufferedFile.isNull() || _bufferedFile.isEmpty())
1305 sourceFile.reset(
new QFile(_filename));
1306 if(!sourceFile->open(QFile::ReadOnly))
1308 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1 while checking Types").arg(_filename) );
1311 streamPointer.reset(
new QTextStream(sourceFile.get()));
1315 streamPointer.reset(
new QTextStream(&_bufferedFile));
1317 QTextStream input(streamPointer->device());
1319 QTextStream lineData;
1322 if ( input.status()!=QTextStream::Ok ){
1323 emit log(
LOGERR, tr(
"readOBJFile : cannot read file %1 while checking Types (is the file corrupt?)").arg(_filename) );
1327 ReaderMode mode = NONE;
1331 QString nextKeyWrd = QLatin1String(
"");
1333 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1334 unsigned int curveCount = 0;
1337 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1338 unsigned int surfaceCount = 0;
1344 int PolyMeshCount = 0;
1345 int TriMeshCount = 0;
1347 OBJImporter::ObjectOptions options = OBJImporter::NONE;
1350 bool inGroup =
false;
1352 bool firstFace =
true;
1354 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1355 QString currentGroupName;
1359 while( !input.atEnd())
1361 line = input.readLine();
1362 if ( input.status()!=QTextStream::Ok ){
1363 emit log(
LOGERR, tr(
"readOBJFile : Warning! Could not read file properly!"));
1368 line = line.trimmed();
1371 if ( line.isEmpty() || line[0] == QLatin1Char(
'#') || line[0].isSpace() ) {
1375 stream.setString(&line);
1379 if (nextKeyWrd == QLatin1String(
""))
1382 keyWrd = nextKeyWrd;
1383 nextKeyWrd = QLatin1String(
"");
1387 if (mode == NONE && keyWrd == QLatin1String(
"call")){
1391 include =stream.readLine();
1394 QString includeStr = include.trimmed();
1396 if ( !includeStr.isEmpty() ){
1398 if (includeStr[0] == QLatin1Char(
'.')){
1399 includeStr = includeStr.right( includeStr.length()-1 );
1401 QFileInfo fi(_filename);
1403 includeStr = fi.path() + QDir::separator() + includeStr;
1406 _includes.append( includeStr );
1413 else if (mode == NONE && keyWrd == QLatin1String(
"v"))
1418 x = getFloat(stream);
1419 y = getFloat(stream);
1420 z = getFloat(stream);
1422 if ( stream.status()==QTextStream::Ok )
1425 emit log(
LOGERR, tr(
"Could not add Vertex %1. Possible NaN or Inf?").arg(_importer.
n_vertices()));
1429 else if (mode == NONE && keyWrd == QLatin1String(
"g")){
1437 grpName = stream.readLine();
1439 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1440 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1442 int id = _importer.addGroup(grpName);
1443 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1445 currentGroupName = grpName;
1446 currentGroupName.remove(QLatin1String(
".obj"));
1448 _importer.setCurrentGroup(
id);
1455 options = OBJImporter::NONE;
1460 else if (mode == NONE && keyWrd == QLatin1String(
"f")){
1465 _importer.setCurrentGroup(0);
1471 int verticesPerFace = 0;
1476 faceLine = stream.readLine();
1477 lineData.setString( &faceLine );
1480 while ( !lineData.atEnd() )
1490 int found=vertex.indexOf(QLatin1String(
"/"));
1496 QString vertexEntry = vertex.left(found);
1497 tmp.setString( &vertexEntry );
1502 if ( tmp.status()!=QTextStream::Ok )
1503 emit log(
LOGERR, tr(
"readOBJFile : Error reading vertex index!"));
1508 tmp.setString( &vertex );
1511 if ( tmp.status()!=QTextStream::Ok )
1512 emit log(
LOGERR, tr(
"readOBJFile : Error reading vertex index!"));
1529 if( verticesPerFace > 3 ) {
1530 options = OBJImporter::POLYMESH;
1532 }
else if ( verticesPerFace == 3 ) {
1533 options = OBJImporter::TRIMESH;
1538 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1541 if ( (mode == NONE && keyWrd == QLatin1String(
"curv")) || (mode == CURVE && keyWrd == QLatin1String(
"curv_add")) ){
1549 if ( keyWrd == QLatin1String(
"curv") ) {
1553 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1554 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1556 QString
name = currentGroupName;
1557 if (name.size() == 0)
1558 name = QLatin1String(
"DefaultGroup");
1560 name.append(QString(
"_curve_%1").arg(curveCount));
1561 int id = _importer.addGroup(name);
1563 if (_importer.numCurves() == 0) {
1564 if (currentGroupName.size() == 0)
1565 _importer.setGroupName(
id, QString(
"DefaultGroup"));
1567 _importer.setGroupName(
id, currentGroupName);
1569 if (curveCount == 1) {
1570 int first = _importer.getCurveGroupId(0);
1571 QString tmp = _importer.groupName(first);
1572 tmp.append(QString(
"_curve_0"));
1573 _importer.setGroupName(first, tmp);
1575 _importer.setGroupName(
id, name);
1577 _importer.setCurveParentId(
id, parentId);
1578 _importer.setCurrentGroup(
id);
1579 _importer.setCurveGroupId(curveCount,
id);
1584 options = OBJImporter::CURVE;
1590 curveLine=stream.readLine();
1593 if ( curveLine.endsWith(QLatin1String(
"\\"))){
1594 curveLine = curveLine.left( curveLine.length()-1);
1595 nextKeyWrd = QLatin1String(
"curv_add");
1598 lineData.setString( &curveLine );
1601 if ( keyWrd == QLatin1String(
"curv") ) {
1603 getDouble(lineData);
1604 getDouble(lineData);
1608 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1614 if ( lineData.status()==QTextStream::Ok ){
1623 else if (mode == CURVE && keyWrd == QLatin1String(
"end")){
1628 options = OBJImporter::TRIMESH;
1633 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1636 if ( (mode == NONE && keyWrd == QLatin1String(
"surf")) || (mode == SURFACE && keyWrd == QLatin1String(
"surf_add")) ){
1644 if ( keyWrd == QLatin1String(
"surf") ){
1648 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1649 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1651 QString
name = currentGroupName;
1652 if (name.size() == 0)
1653 name = QLatin1String(
"DefaultGroup");
1655 name.append(QString(
"_surface_%1").arg(surfaceCount));
1656 int id = _importer.addGroup(name);
1658 if (_importer.numSurfaces() == 0) {
1659 if (currentGroupName.size() == 0)
1660 _importer.setGroupName(
id,
"DefaultGroup");
1662 _importer.setGroupName(
id, currentGroupName);
1664 if (surfaceCount == 1) {
1665 int first = _importer.getSurfaceGroupId(0);
1666 QString tmp = _importer.groupName(first);
1667 tmp.append(QString(
"_surface_0"));
1668 _importer.setGroupName(first, tmp);
1670 _importer.setGroupName(
id, name);
1672 _importer.setSurfaceParentId(
id, parentId);
1673 _importer.setCurrentGroup(
id);
1674 _importer.setSurfaceGroupId(surfaceCount,
id);
1679 options = OBJImporter::SURFACE;
1685 surfLine = stream.readLine();
1688 if ( surfLine.endsWith(QLatin1String(
"\\"))){
1689 surfLine = surfLine.left(surfLine.length()-1);
1690 nextKeyWrd = QLatin1String(
"surf_add");
1693 lineData.setString( &surfLine );
1696 while ( !lineData.atEnd() && lineData.status()==QTextStream::Ok )
1702 if ( lineData.status()==QTextStream::Ok ){
1710 else if (mode == SURFACE && keyWrd == QLatin1String(
"end")){
1715 options = OBJImporter::TRIMESH;
1723 if ( options & OBJImporter::TRIMESH ) TriMeshCount++;
1724 if ( options & OBJImporter::POLYMESH ) PolyMeshCount++;
1729 if (keyWrd != QLatin1String(
"call")) {
1731 if (keyWrd == QLatin1String(
"v") && !inGroup) {
1732 _importer.setCurrentGroup(0);
1734 forceTriangleMesh_ =
false;
1735 forcePolyMesh_ =
true;
1738 for (
unsigned int i = 0; i < _importer.
n_vertices(); ++i)
1751 if (TriMeshCount == 0 && PolyMeshCount == 0)
1756 if (forceTriangleMesh_){
1761 if (forcePolyMesh_){
1768 if ( OpenFlipper::Options::gui() && triMeshHandling_ != 0 ){
1770 switch( triMeshHandling_->currentIndex() ){
1771 case TYPEAUTODETECT :
1775 QMetaObject::invokeMethod(
this,
"handleTrimeshDialog",Qt::BlockingQueuedConnection);
1776 if (trimeshOptions_ == OBJImporter::TRIMESH )
1778 else if (trimeshOptions_ == OBJImporter::POLYMESH)
1797 void FileOBJPlugin::handleTrimeshDialog()
1800 QPushButton *detectButton = msgBox.addButton(tr(
"Auto-Detect"), QMessageBox::ActionRole);
1801 QPushButton *triButton = msgBox.addButton(tr(
"Open as triangle mesh"), QMessageBox::ActionRole);
1802 QPushButton *polyButton = msgBox.addButton(tr(
"Open as poly mesh"), QMessageBox::ActionRole);
1803 msgBox.setWindowTitle( tr(
"Mesh types in file") );
1804 msgBox.setText( tr(
"You are about to open a file containing one or more mesh types. \n\n Which mesh type should be used?") );
1805 msgBox.setDefaultButton( detectButton );
1809 if (msgBox.clickedButton() == triButton)
1810 trimeshOptions_ = OBJImporter::TRIMESH ;
1811 else if (msgBox.clickedButton() == polyButton)
1812 trimeshOptions_ = OBJImporter::POLYMESH ;
1822 QStringList includes;
1824 QFile sourceFile(_filename);
1825 if (!sourceFile.open(QFile::ReadOnly))
1827 emit log(
LOGERR, tr(
"readOBJFile : cannot open file %1 while checking Types").arg(_filename));
1830 QByteArray bufferedFile = QByteArray();
1833 unsigned long freeMem = Utils::Memory::queryFreeRAM();
1834 unsigned long fs = sourceFile.size() / 1024 / 1024;
1835 if (freeMem >= 2*fs)
1837 bufferedFile = sourceFile.readAll();
1841 checkTypes( bufferedFile, _filename, importer, includes );
1846 for (
int i=0; i < includes.size(); i++){
1852 objIDs.push_back(
id );
1856 if ( ! includes.empty() )
1857 importer.addGroup( QFileInfo(_filename).fileName() );
1860 if ( importer.
noOptions() && objIDs.empty() ){
1862 forceTriangleMesh_ =
false;
1863 forcePolyMesh_ =
false;
1869 readOBJFile( bufferedFile, _filename, importer );
1877 if ( importer.numGroups() > 1){
1879 bool dataControlExists =
false;
1880 pluginExists(
"datacontrol", dataControlExists );
1882 if ( dataControlExists ){
1883 #if defined ENABLE_BSPLINECURVE_SUPPORT || defined ENABLE_BSPLINESURFACE_SUPPORT 1884 std::map<int, QString> groupNames;
1887 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1888 std::vector< std::vector<int> > curveGroups;
1889 std::vector<int> curveIds;
1890 int lastCurveParent = -2;
1893 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1894 std::vector< std::vector<int> > surfaceGroups;
1895 std::vector<int> surfaceIds;
1896 int lastSurfaceParent = -2;
1898 for(
unsigned int i = 0; i < importer.
groupCount(); i++) {
1901 if ( !importer.isNone(i) ) {
1904 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1905 if ( importer.isCurve(i) ) {
1907 groupNames[obj->
id()] = importer.groupName(importer.getCurveParentId(i));
1910 if (lastCurveParent == -2) {
1911 lastCurveParent = importer.getCurveParentId(i);
1912 curveIds.push_back(obj->
id());
1915 curveIds.push_back(parent->
id());
1917 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1918 if (pos != objIDs.end())
1922 }
else if (lastCurveParent != importer.getCurveParentId(i)) {
1923 lastCurveParent = importer.getCurveParentId(i);
1924 curveGroups.push_back(curveIds);
1926 curveIds.push_back(obj->
id());
1929 curveIds.push_back(parent->
id());
1931 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1932 if (pos != objIDs.end())
1937 curveIds.push_back(obj->
id());
1941 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 1942 if ( importer.isSurface(i)) {
1944 groupNames[obj->
id()] = importer.groupName(importer.getSurfaceParentId(i));
1947 if (lastSurfaceParent == -2) {
1948 lastSurfaceParent = importer.getSurfaceParentId(i);
1949 surfaceIds.push_back(obj->
id());
1952 surfaceIds.push_back(parent->
id());
1953 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1954 if (pos != objIDs.end())
1958 }
else if (lastSurfaceParent != importer.getSurfaceParentId(i)) {
1959 lastSurfaceParent = importer.getSurfaceParentId(i);
1960 surfaceGroups.push_back(surfaceIds);
1962 surfaceIds.push_back(obj->
id());
1965 surfaceIds.push_back(parent->
id());
1966 std::vector<int>::iterator pos = std::find(objIDs.begin(), objIDs.end(), parent->
id());
1967 if (pos != objIDs.end())
1972 surfaceIds.push_back(obj->
id());
1976 if ( (importer.isTriangleMesh(i) || importer.isPolyMesh(i) ) )
1977 objIDs.push_back( obj->
id() );
1979 std::cerr <<
"Object is NULL!" << std::endl;
1984 #ifdef ENABLE_BSPLINECURVE_SUPPORT 1986 curveGroups.push_back(curveIds);
1987 std::vector< std::vector<int> >::iterator it = curveGroups.begin();
1988 for (; it != curveGroups.end(); ++it) {
1990 if (it->size() > 2) {
1991 if (groupNames[it->back()].size() == 0)
1992 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it, QFileInfo(_filename).fileName());
1994 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it, groupNames[it->back()]);
1999 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 2001 surfaceGroups.push_back(surfaceIds);
2002 std::vector< std::vector<int> >::iterator it2 = surfaceGroups.begin();
2003 for (; it2 != surfaceGroups.end(); ++it2) {
2005 if (it2->size() > 2) {
2006 if (groupNames[it2->back()].size() == 0)
2007 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it2, QFileInfo(_filename).fileName());
2009 RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", *it2, groupNames[it2->back()]);
2015 if (objIDs.size() > 1)
2016 returnID = RPC::callFunctionValue<int>(
"datacontrol",
"groupObjects", objIDs, importer.groupName(0));
2021 for(
unsigned int i=0; i < importer.
groupCount(); i++){
2024 if(
object == NULL)
continue;
2029 if ( returnID == -1)
2030 returnID =
object->id();
2054 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2065 if ( importer.hasTexture(i) && !importer.
hasOption( i, OBJImporter::FORCE_NOTEXTURES ) ){
2068 addTextures( importer, i );
2071 emit setTextureMode(
"OBJ Data",
"indexProperty=OriginalTexIndexMapping", object->
id() );
2073 emit switchTexture(
"OBJ Data", object->
id() );
2081 emit openedFile( object->
id() );
2084 forceTriangleMesh_ =
false;
2085 forcePolyMesh_ =
false;
2098 forceTriangleMesh_ =
true;
2100 forcePolyMesh_ =
true;
2107 bool FileOBJPlugin::saveObject(
int _id, QString _filename)
2111 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2116 std::string filename = std::string( _filename.toUtf8() );
2118 std::fstream objStream( filename.c_str(), std::ios_base::out );
2122 emit log(
LOGERR, tr(
"saveObject : cannot not open file %1").arg(_filename) );
2129 object->setFromFileName(_filename);
2130 object->setName(object->
filename());
2135 if ( writeMesh( objStream, _filename, *polyObj->
mesh(), polyObj->
id() ) ){
2137 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2143 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2150 object->setFromFileName(_filename);
2151 object->setName(object->
filename());
2156 if ( writeMesh( objStream, _filename, *triObj->
mesh(), triObj->
id() )) {
2158 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2164 emit log(
LOGERR, tr(
"Unable to save ") + _filename );
2169 #ifdef ENABLE_BSPLINECURVE_SUPPORT 2172 object->setFromFileName(_filename);
2173 object->setName(object->
filename());
2178 if ( writeCurve( objStream, _filename, bscObj->
splineCurve()) ) {
2180 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2186 emit log(
LOGERR, tr(
"Unable to save ") + _filename );
2192 #ifdef ENABLE_BSPLINESURFACE_SUPPORT 2195 object->setFromFileName(_filename);
2196 object->setName(object->
filename());
2201 if ( writeSurface( objStream, _filename, bssObj->
splineSurface()) ) {
2203 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2209 emit log(
LOGERR, tr(
"Unable to save ") + object->
path() + OpenFlipper::Options::dirSeparator() +
object->name());
2217 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2225 void FileOBJPlugin::slotHandleCheckBoxes(
bool _checked) {
2227 if(saveCopyTextures_) {
2228 saveCreateTexFolder_->setEnabled(_checked);
2229 saveCreateTexFolder_->setChecked(_checked);
2237 if (saveOptions_ == 0){
2239 saveOptions_ =
new QWidget();
2240 QVBoxLayout* layout =
new QVBoxLayout();
2241 layout->setAlignment(Qt::AlignTop);
2243 saveFaceColor_ =
new QCheckBox(
"Save Face Colors");
2244 layout->addWidget(saveFaceColor_);
2246 saveAlpha_ =
new QCheckBox(
"Save Color Alpha");
2247 layout->addWidget(saveAlpha_);
2249 saveNormals_ =
new QCheckBox(
"Save Normals");
2250 layout->addWidget(saveNormals_);
2252 saveTexCoords_ =
new QCheckBox(
"Save Texture Coordinates");
2253 layout->addWidget(saveTexCoords_);
2255 saveTextures_ =
new QCheckBox(
"Save Textures");
2256 layout->addWidget(saveTextures_);
2258 saveCopyTextures_ =
new QCheckBox(
"Copy Texture Files");
2259 layout->addWidget(saveCopyTextures_);
2261 saveCreateTexFolder_ =
new QCheckBox(
"Create Textures Folder");
2262 layout->addWidget(saveCreateTexFolder_);
2264 savePrecisionLabel_ =
new QLabel(
"Writer Precision");
2265 layout->addWidget(savePrecisionLabel_);
2267 savePrecision_ =
new QSpinBox();
2268 savePrecision_->setMinimum(1);
2269 savePrecision_->setMaximum(12);
2270 savePrecision_->setValue(6);
2271 layout->addWidget(savePrecision_);
2273 saveDefaultButton_ =
new QPushButton(
"Make Default");
2274 layout->addWidget(saveDefaultButton_);
2276 saveOptions_->setLayout(layout);
2278 connect(saveDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotSaveDefault()));
2279 connect(saveCopyTextures_, SIGNAL(toggled(
bool)),
this, SLOT(slotHandleCheckBoxes(
bool)));
2281 saveFaceColor_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/FaceColor",
true).toBool() );
2282 saveAlpha_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Alpha",
true).toBool() );
2283 saveNormals_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Normals",
true).toBool() );
2284 saveTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/TexCoords",
true).toBool() );
2285 saveTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/Textures",
true).toBool() );
2286 saveCopyTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/CopyTextures",
true).toBool() );
2287 saveCreateTexFolder_->setChecked(
OpenFlipperSettings().value(
"FileObj/Save/CreateTexFolder",
true).toBool() );
2289 slotHandleCheckBoxes(saveCopyTextures_->isChecked());
2292 return saveOptions_;
2299 if (loadOptions_ == 0){
2301 loadOptions_ =
new QWidget();
2302 QVBoxLayout* layout =
new QVBoxLayout();
2303 layout->setAlignment(Qt::AlignTop);
2305 QLabel* label =
new QLabel(tr(
"If file contains meshes:"));
2307 layout->addWidget(label);
2309 triMeshHandling_ =
new QComboBox();
2310 triMeshHandling_->addItem( tr(
"Detect correct type") );
2311 triMeshHandling_->addItem( tr(
"Ask") );
2312 triMeshHandling_->addItem( tr(
"Open as PolyMesh") );
2313 triMeshHandling_->addItem( tr(
"Open as TriangleMesh") );
2315 layout->addWidget(triMeshHandling_);
2317 loadFaceColor_ =
new QCheckBox(
"Load Face Colors");
2318 layout->addWidget(loadFaceColor_);
2320 loadNormals_ =
new QCheckBox(
"Load Normals");
2321 layout->addWidget(loadNormals_);
2323 loadTexCoords_ =
new QCheckBox(
"Load Texture Coordinates");
2324 layout->addWidget(loadTexCoords_);
2326 loadTextures_ =
new QCheckBox(
"Load Textures");
2327 layout->addWidget(loadTextures_);
2329 loadDefaultButton_ =
new QPushButton(
"Make Default");
2330 layout->addWidget(loadDefaultButton_);
2332 loadOptions_->setLayout(layout);
2334 connect(loadDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotLoadDefault()));
2337 triMeshHandling_->setCurrentIndex(
OpenFlipperSettings().value(
"FileObj/Load/TriMeshHandling",TYPEAUTODETECT).toInt() );
2339 loadFaceColor_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/FaceColor",
true).toBool() );
2340 loadNormals_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/Normals",
true).toBool() );
2341 loadTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/TexCoords",
true).toBool() );
2342 loadTextures_->setChecked(
OpenFlipperSettings().value(
"FileObj/Load/Textures",
true).toBool() );
2345 return loadOptions_;
void forceMeshType(ObjectOptions _meshType)
force all meshes to be opened with specific type
QString name()
Return a name for the plugin.
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
FileOBJPlugin()
Constructor.
QString path()
Path of the OBJ file.
BaseObject * object(int _groupId)
return object for the given group
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void slotLoadDefault()
Slot called when user wants to save the given Load options as default.
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
void setVertexTexCoord(VertexHandle _vh, int _texCoordID)
set vertex texture coordinate
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
int addTexCoord(const Vec2f &_coord)
add texture coordinates
void setDegreeU(int _degree)
set degree
Vec3f vertex(unsigned int _index)
get vertex with given index
bool noOptions()
Return true if the importer has no options stored.
void setObject(BaseObject *_object, int _groupId)
add an object
void setFromFileName(const QString &_filename)
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
int degreeV()
get current degree
bool dataType(DataType _type) const
MeshT * mesh()
return a pointer to the mesh
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
void checkTypes(QByteArray &_bufferedFile, QString _filename, OBJImporter &_importer, QStringList &_includes)
Reader functions.
int currentGroup()
Get the id of the current group.
void backupTextureCoordinates(MeshT &_mesh)
creates a backup of the original per vertex/face texture coordinates
void addFace(const VHandles &_indices)
add a face with indices _indices refering to vertices
void setDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, int _viewer)
Set the draw Mode of a Viewer. .
unsigned int groupCount()
Number of groups currently stored in the importer.
void addMaterial(std::string _materialName)
Add a material.
MaterialList & materials()
return all loaded materials
const std::vector< std::string > usedMaterials(unsigned int _objectID)
used materials
void useVertex(int _vertex_index)
used vertices
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Type for a MeshObject containing a triangle mesh.
int degreeU()
get current degree
QString filename() const
return the filename of the object
std::vector< int > IdList
Standard Type for id Lists used for scripting.
void setDegreeV(int _degree)
set degree V direction
unsigned int n_vertices()
Global Properties.
void setObjectOptions(ObjectOptions _options)
QString path() const
return the path to the object ( defaults to "." if unset )
#define DATA_BSPLINE_SURFACE
ACG::SceneGraph::BSplineCurveNodeT< BSplineCurve > * splineCurveNode()
Get the scenegraph Node.
const DataType DATA_GROUP(1)
Items used for Grouping.
void convertToOBJName(QString &_name)
Convert non-valid filenames (e.g. of groups that end with .jpg) to valid .objs.
BSplineSurface * splineSurface()
return a pointer to the spline curve
void update_face_normals()
Update normal vectors for all faces.
void initializePlugin()
Initialize Plugin.
int addNormal(const Vec3f &_normal)
add a normal
DrawMode SOLID_2DTEXTURED_FACE_SHADED
draw per halfedge textured faces
void setNormal(int _index, int _normalID)
set vertex normal
QWidget * saveOptionsWidget(QString)
BSplineCurve * splineCurve()
return a pointer to the spline curve
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
#define DATA_TRIANGLE_MESH
#define DATA_BSPLINE_CURVE
Type for a Meshobject containing a poly mesh.
void update_normals()
Compute normals for all primitives.
QWidget * loadOptionsWidget(QString)
bool hasNormals(int _objectID)
Query Object Options.