C++ (Qt)#ifndef PARSER_H#define PARSER_H #include <QList>#include <QVector3D> class Parser {public: void parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes );}; #endif // PARSER_H
C++ (Qt)#include "Parser.h" void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) { }
C++ (Qt)#include <QString>#include <QtTest>#include "Parser.h"#include <QVector3D> class CubeFromBlenderTests : public QObject { Q_OBJECT public: CubeFromBlenderTests( ); static inline bool qFuzzyCompare( double p1, double p2, double delta ) { return ( qAbs( p1 - p2 ) <= delta * qMin( qAbs( p1 ), qAbs( p2 ) )); } privateQ_SLOTS: void testCase1_data( ); void testCase1( );}; CubeFromBlenderTests::CubeFromBlenderTests( ) {} void CubeFromBlenderTests::testCase1_data( ) { QTest::addColumn<QString>("input"); QTest::addColumn<QList<QVector3D> >("expected_points"); QTest::addColumn<QList<QVector3D> >("expected_indexes"); QString input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n" "# www.blender.org\n" "o Cube\n" "v 1.000000 1.000001 -0.999999\n" "v 1.000000 -0.999999 -1.000001\n" "v -1.000000 -0.999999 -1.000001\n" "v -1.000000 1.000001 -0.999999\n" "v 1.000000 0.999999 1.000001\n" "v 0.999999 -1.000001 0.999999\n" "v -1.000000 -1.000000 0.999999\n" "v -1.000000 0.999999 1.000001\n" "s off\n" "f 1 2 4\n" "f 5 8 6\n" "f 1 5 2\n" "f 2 6 3\n" "f 3 7 4\n" "f 5 1 8\n" "f 2 3 4\n" "f 8 7 6\n" "f 5 6 2\n" "f 6 7 3\n" "f 7 8 4\n" "f 1 4 8\n" ); QList<QVector3D> expected_points; QVector3D point; // 1 point.setX( 1.000000 ); point.setY( 1.000001 ); point.setZ( -0.999999 ); expected_points.append( point ); // 2 point.setX( 1.000000 ); point.setY( -0.999999 ); point.setZ( -1.000001 ); expected_points.append( point ); // 3 point.setX( -1.000000 ); point.setY( -0.999999 ); point.setZ( -1.000001 ); expected_points.append( point ); // 4 point.setX( -1.000000 ); point.setY( 1.000001 ); point.setZ( -0.999999 ); expected_points.append( point ); // 5 point.setX( 1.000000 ); point.setY( 0.999999 ); point.setZ( 1.000001 ); expected_points.append( point ); // 6 point.setX( 0.999999 ); point.setY( -1.000001 ); point.setZ( 0.999999 ); expected_points.append( point ); // 7 point.setX( -1.000000 ); point.setY( -1.000000 ); point.setZ( 0.999999 ); expected_points.append( point ); // 8 point.setX( -1.000000 ); point.setY( 0.999999 ); point.setZ( 1.000001 ); expected_points.append( point ); QList<QVector3D> expected_indexes; QVector3D indexes; // 1 indexes.setX( 1.0 ); indexes.setY( 2.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 2 indexes.setX( 5.0 ); indexes.setY( 8.0 ); indexes.setZ( 6.0 ); expected_indexes.append( indexes ); // 3 indexes.setX( 1.0 ); indexes.setY( 5.0 ); indexes.setZ( 2.0 ); expected_indexes.append( indexes ); // 4 indexes.setX( 2.0 ); indexes.setY( 6.0 ); indexes.setZ( 3.0 ); expected_indexes.append( indexes ); // 5 indexes.setX( 3.0 ); indexes.setY( 7.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 6 indexes.setX( 5.0 ); indexes.setY( 1.0 ); indexes.setZ( 8.0 ); expected_indexes.append( indexes ); // 7 indexes.setX( 2.0 ); indexes.setY( 3.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 8 indexes.setX( 8.0 ); indexes.setY( 7.0 ); indexes.setZ( 6.0 ); expected_indexes.append( indexes ); // 9 indexes.setX( 5.0 ); indexes.setY( 6.0 ); indexes.setZ( 2.0 ); expected_indexes.append( indexes ); // 10 indexes.setX( 6.0 ); indexes.setY( 7.0 ); indexes.setZ( 3.0 ); expected_indexes.append( indexes ); // 11 indexes.setX( 7.0 ); indexes.setY( 8.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 12 indexes.setX( 1.0 ); indexes.setY( 4.0 ); indexes.setZ( 8.0 ); expected_indexes.append( indexes ); QTest::newRow( "parseData_01" ) << input << expected_points << expected_indexes;} void CubeFromBlenderTests::testCase1( ) { QFETCH( QString, input ); QFETCH( QList<QVector3D>, expected_points ); QFETCH( QList<QVector3D>, expected_indexes ); Parser parser; QList<QVector3D> points; QList<QVector3D> indexes; parser.parseData( input, points, indexes ); double delta = 0.0001; bool result = false; QString msg; // Check size of points and indexes QCOMPARE( points.size( ), expected_points.size( ) ); QCOMPARE( indexes.size( ), expected_indexes.size( ) ); // Check points for ( std::size_t i = 0; i < points.size( ); ++i ) { // Check x result = qFuzzyCompare( points[i].x( ), expected_points[i].x( ), delta ); msg = QString( "\nActual: %1" "\nExpected: %2" "\nDelta: %3" ).arg( points[i].x( ) ).arg( expected_points[i].x( ) ).arg( delta ); QVERIFY2( result, msg.toStdString( ).c_str( ) ); // Check y result = qFuzzyCompare( points[i].y( ), expected_points[i].y( ), delta ); msg = QString( "\nActual: %1" "\nExpected: %2" "\nDelta: %3" ).arg( points[i].y( ) ).arg( expected_points[i].y( ) ).arg( delta ); QVERIFY2( result, msg.toStdString( ).c_str( ) ); // Check z result = qFuzzyCompare( points[i].z( ), expected_points[i].z( ), delta ); msg = QString( "\nActual: %1" "\nExpected: %2" "\nDelta: %3" ).arg( points[i].z( ) ).arg( expected_points[i].z( ) ).arg( delta ); QVERIFY2( result, msg.toStdString( ).c_str( ) ); } // Check indexes int actualIndex = 0; int expectedIndex = 0; for ( std::size_t i = 0; i < indexes.size( ); ++i ) { // 1 actualIndex = (int) indexes[i].x( ); expectedIndex = (int) indexes[i].x( ); QCOMPARE( actualIndex, expectedIndex ); // 2 actualIndex = (int) indexes[i].y( ); expectedIndex = (int) indexes[i].y( ); QCOMPARE( actualIndex, expectedIndex ); // 3 actualIndex = (int) indexes[i].z( ); expectedIndex = (int) indexes[i].z( ); QCOMPARE( actualIndex, expectedIndex ); }} QTEST_APPLESS_MAIN( CubeFromBlenderTests ) #include "tst_CubeFromBlenderTests.moc"
C++ (Qt)#include "Parser.h"#include <QStringList> void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) { QStringList list = input.split( "\n" ); for ( std::size_t i = 0; i < list.size( ); ++i ) { // Poitns if ( list[i][0] == QChar( 'v' ) ) { QStringList listForPoints = list[i].split( " " ); if ( listForPoints.size( ) == 4 ) { bool ok; float x = listForPoints[1].toFloat( &ok ); if ( !ok ) { break; } float y = listForPoints[2].toFloat( &ok ); if ( !ok ) { break; } float z = listForPoints[3].toFloat( &ok ); if ( !ok ) { break; } points.append( QVector3D( x, y, z ) ); } } // Indexes if ( list[i][0] == QChar( 'f' ) ) { QStringList listForIndexes = list[i].split( " " ); if ( listForIndexes.size( ) == 4 ) { bool ok; float x = listForIndexes[1].toFloat( &ok ); if ( !ok ) { break; } float y = listForIndexes[2].toFloat( &ok ); if ( !ok ) { break; } float z = listForIndexes[3].toFloat( &ok ); if ( !ok ) { break; } indexes.append( QVector3D( x, y, z ) ); } } }}
C++ (Qt)#ifndef OBJFORMAT_H#define OBJFORMAT_H #include <QObject>#include <QString>#include <QVector>#include <QFile>#include <QStringList>#include <QTextStream>#include <QMessageBox>#include <QInputDialog>#include <QDir> #include "simdynamic.h"#include "./dialogs/importprogressdialog.h" class ObjFormat : public QObject{ Q_OBJECT public: explicit ObjFormat(QObject *parent = 0); void importModel(QString str, int digit); SimulationDynamicMesh* getModel(void){return simDynamicMesh;} private: SimulationDynamicMesh* simDynamicMesh; QMessageBox msgBox; QFile file; ImportProgressDialog* importProgressDlg; void parseLine(QString str); bool appVertex, appTexture, appFaces, appNormals; signals: public slots: };
C++ (Qt)#include "objformat.h"#include "common.h" ObjFormat::ObjFormat(QObject *parent) : QObject(parent) , simDynamicMesh(new SimulationDynamicMesh()) , appVertex(false) , appTexture(false) , appFaces(false) , appNormals(false){} void ObjFormat::importModel(QString str, int digit){ importProgressDlg = new ImportProgressDialog(); importProgressDlg->show(); file.setFileName(str); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { msgBox.setWindowTitle(SimError::critical); msgBox.setText(QString::fromLocal8Bit("File '") + str + QString::fromLocal8Bit("' wurde nicht gefunden!")); msgBox.setIcon(QMessageBox::Critical); msgBox.exec(); return; } QTextStream stream(&file); importProgressDlg->printToLog("Parsing *obj File"); QVector<QString> lines; while(!stream.atEnd()) { lines.append(stream.readLine()); } file.close(); importProgressDlg->setProgressBarMaxValue(lines.size()); for(int i = 0; i < lines.size(); i++) { parseLine(lines.at(i)); importProgressDlg->setProgressBarValue(i); } if(!simDynamicMesh->haveIdenticalVertixes(importProgressDlg) && !simDynamicMesh->haveIdenticalFaces(importProgressDlg)) { simDynamicMesh->sortEdges(importProgressDlg); } QString meshName = QString("Object_%1").arg(QString::number(digit)); bool ok; QString text = QInputDialog::getText(NULL,tr("Simulation Object Name:"),tr("Simulation Object Name:"),QLineEdit::Normal,meshName,&ok); if (ok && !text.isEmpty()) simDynamicMesh->setMeshName(text); importProgressDlg->close(); delete importProgressDlg;} void ObjFormat::parseLine(QString str){ str.remove("\t"); str.remove("\n"); str = str.trimmed(); QStringList list = str.split(" "); if(list.at(0) == "v") // parser vertex { simDynamicMesh->appendVertex(list.at(1).toFloat(), list.at(2).toFloat(), list.at(3).toFloat()); simDynamicMesh->setLastVertexColor(0.75F, 0.75F, 0.75F); if(!appVertex) { importProgressDlg->printToLog("\tAppend Vertex Data"); appVertex = true; } } else if(list.at(0) == "vn") { simDynamicMesh->appendNormals(list.at(1).toFloat(), list.at(2).toFloat(), list.at(3).toFloat()); if(!appNormals) { importProgressDlg->printToLog("\tAppend Normal Data"); appNormals = true; } } else if(list.at(0) == "vt") { simDynamicMesh->appendTexture(list.at(1).toFloat(), list.at(2).toFloat()); if(!appTexture) { importProgressDlg->printToLog("\tAppend Texture Data"); appTexture = true; } } else if(list.at(0) == "f") { QStringList vert1 = list.at(1).split("/"); QStringList vert2 = list.at(2).split("/"); QStringList vert3 = list.at(3).split("/"); if(vert1.size() > 1) { simDynamicMesh->appendFace(vert1.at(0).toInt(), vert2.at(0).toInt(), vert3.at(0).toInt(), vert1.at(1).toInt(), vert2.at(1).toInt(), vert3.at(1).toInt(), vert1.at(2).toInt(), vert2.at(2).toInt(), vert3.at(2).toInt()); } else { simDynamicMesh->appendFace(vert1.at(0).toInt(), vert2.at(0).toInt(), vert3.at(0).toInt()); } if(!appFaces) { importProgressDlg->printToLog("\tAppend Face Data"); appFaces = true; } }}