diff --git a/src/io_off/io_off_reader.cpp b/src/io_off/io_off_reader.cpp index 2c87f7ee..e3572b84 100644 --- a/src/io_off/io_off_reader.cpp +++ b/src/io_off/io_off_reader.cpp @@ -200,16 +200,25 @@ bool OffReader::readFile(const FilePath& filepath, TaskProgress* progress) int vertexCount = 0; int facetCount = 0; { - if (!ifs.good()) - return fnError(OffReaderI18N::textIdTr("Unexpected end of file")); + // Normally vertex/face/edge counts are specified on a dedicated line coming after OFF + // But for some files they are wrongly specified on the line containing OFF token, eg "OFF 24 12 0" + const auto arrayStrFirstLine = getWords<3>(strLine); + if (!arrayStrFirstLine[1].empty() && !arrayStrFirstLine[2].empty()) { + vertexCount = strToNum(arrayStrFirstLine[1]); + facetCount = strToNum(arrayStrFirstLine[2]); + } + else { + if (!ifs.good()) + return fnError(OffReaderI18N::textIdTr("Unexpected end of file")); - getNonCommentLine(ifs, strLine); - const auto arrayStrCount = getWords<2>(strLine); - if (hasEmptyString(arrayStrCount)) - return fnError(OffReaderI18N::textIdTr("No vertex or face count")); + getNonCommentLine(ifs, strLine); + const auto arrayStrCount = getWords<2>(strLine); + if (hasEmptyString(arrayStrCount)) + return fnError(OffReaderI18N::textIdTr("No vertex or face count")); - vertexCount = strToNum(arrayStrCount[0]); - facetCount = strToNum(arrayStrCount[1]); + vertexCount = strToNum(arrayStrCount[0]); + facetCount = strToNum(arrayStrCount[1]); + } } // Helper function for progress report diff --git a/tests/inputs/#258_cube.off b/tests/inputs/#258_cube.off new file mode 100644 index 00000000..c71df4a9 --- /dev/null +++ b/tests/inputs/#258_cube.off @@ -0,0 +1,37 @@ +OFF 24 12 0 +0 0 0 0.603827 0.603827 0.603827 +0 0 10 0.603827 0.603827 0.603827 +0 10 0 0.603827 0.603827 0.603827 +0 10 10 0.603827 0.603827 0.603827 +10 0 0 0.603827 0.603827 0.603827 +10 0 10 0.603827 0.603827 0.603827 +10 10 0 0.603827 0.603827 0.603827 +10 10 10 0.603827 0.603827 0.603827 +0 0 0 0.603827 0.603827 0.603827 +10 0 0 0.603827 0.603827 0.603827 +0 0 10 0.603827 0.603827 0.603827 +10 0 10 0.603827 0.603827 0.603827 +0 10 0 0.603827 0.603827 0.603827 +10 10 0 0.603827 0.603827 0.603827 +0 10 10 0.603827 0.603827 0.603827 +10 10 10 0.603827 0.603827 0.603827 +0 0 0 0.603827 0.603827 0.603827 +0 10 0 0.603827 0.603827 0.603827 +10 0 0 0.603827 0.603827 0.603827 +10 10 0 0.603827 0.603827 0.603827 +0 0 10 0.603827 0.603827 0.603827 +0 10 10 0.603827 0.603827 0.603827 +10 0 10 0.603827 0.603827 0.603827 +10 10 10 0.603827 0.603827 0.603827 +3 1 0 2 +3 1 2 3 +3 5 4 6 +3 5 6 7 +3 11 9 8 +3 11 8 10 +3 15 13 12 +3 15 12 14 +3 19 17 16 +3 19 16 18 +3 23 21 20 +3 23 20 22 diff --git a/tests/test_base.cpp b/tests/test_base.cpp index 2be649ad..74cfdef7 100644 --- a/tests/test_base.cpp +++ b/tests/test_base.cpp @@ -35,6 +35,8 @@ #include "../src/base/unit_system.h" #include "../src/io_dxf/io_dxf.h" #include "../src/io_occ/io_occ.h" +#include "../src/io_off/io_off_reader.h" +#include "../src/io_off/io_off_writer.h" #include "../src/io_ply/io_ply_reader.h" #include "../src/io_ply/io_ply_writer.h" @@ -622,6 +624,28 @@ void TestBase::IO_bugGitHub166_test_data() #endif } +void TestBase::IO_bugGitHub258_test() +{ + auto app = Application::instance(); + DocumentPtr doc = app->newDocument(); + const bool okImport = m_ioSystem->importInDocument() + .targetDocument(doc) + .withFilepath("tests/inputs/#258_cube.off") + .execute(); + QVERIFY(okImport); + QVERIFY(doc->entityCount() == 1); + + const TopoDS_Shape shape = doc->xcaf().shape(doc->entityLabel(0)); + const TopoDS_Face& face = TopoDS::Face(shape); + TopLoc_Location locFace; + auto triangulation = BRep_Tool::Triangulation(face, locFace); + QVERIFY(!triangulation.IsNull()); + QCOMPARE(triangulation->NbNodes(), 24); + QCOMPARE(triangulation->NbTriangles(), 12); + + app->closeDocument(doc); +} + void TestBase::DoubleToString_test() { const std::locale frLocale = getFrLocale(); @@ -1102,11 +1126,16 @@ void TestBase::Span_test() void TestBase::initTestCase() { m_ioSystem = new IO::System; + m_ioSystem->addFactoryReader(std::make_unique()); - m_ioSystem->addFactoryReader(std::make_unique()); - m_ioSystem->addFactoryWriter(std::make_unique()); m_ioSystem->addFactoryReader(std::make_unique()); + m_ioSystem->addFactoryReader(std::make_unique()); + m_ioSystem->addFactoryReader(std::make_unique()); + m_ioSystem->addFactoryWriter(std::make_unique()); + m_ioSystem->addFactoryWriter(std::make_unique()); + m_ioSystem->addFactoryWriter(std::make_unique()); + IO::addPredefinedFormatProbes(m_ioSystem); } diff --git a/tests/test_base.h b/tests/test_base.h index b5a73817..5723fe7e 100644 --- a/tests/test_base.h +++ b/tests/test_base.h @@ -43,6 +43,7 @@ private slots: void IO_OccStaticVariablesRollback_test_data(); void IO_bugGitHub166_test(); void IO_bugGitHub166_test_data(); + void IO_bugGitHub258_test(); void DoubleToString_test(); void StringConv_test();