diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 687cf9fc3..6c7827734 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -42,6 +42,7 @@ #include #include #include +#include using namespace MeshCore; @@ -330,6 +331,9 @@ bool MeshInput::LoadAny(const char* FileName) else if (fi.hasExtension("obj")) { ok = LoadOBJ( str ); } + else if (fi.hasExtension("off")) { + ok = LoadOFF( str ); + } else if (fi.hasExtension("ply")) { ok = LoadPLY( str ); } @@ -512,6 +516,124 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) return true; } +/** Loads an OFF file. */ +bool MeshInput::LoadOFF (std::istream &rstrIn) +{ + boost::regex rx_n("^\\s*([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s*$"); + boost::regex rx_p("^\\s*([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); + boost::regex rx_f3("^\\s*([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s*$"); + boost::regex rx_f4("^\\s*([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s*$"); + + boost::cmatch what; + + MeshPointArray meshPoints; + MeshFacetArray meshFacets; + + std::string line; + float fX, fY, fZ; + unsigned int i1=1,i2=1,i3=1,i4=1; + MeshGeomFacet clFacet; + MeshFacet item; + + if (!rstrIn || rstrIn.bad() == true) + return false; + + std::streambuf* buf = rstrIn.rdbuf(); + if (!buf) + return false; + + bool readvertices=false; + std::getline(rstrIn, line); + boost::algorithm::to_lower(line); + if (line.find("off") == std::string::npos) + return false; // not an OFF file + + // get number of vertices and faces + int numPoints=0, numFaces=0; + std::getline(rstrIn, line); + boost::algorithm::to_lower(line); + if (boost::regex_match(line.c_str(), what, rx_n)) { + numPoints = std::atoi(what[1].first); + numFaces = std::atoi(what[2].first); + } + else { + // Cannot read number of elements + return false; + } + + meshPoints.reserve(numPoints); + meshFacets.reserve(numFaces); + + for (int i=0; i_rclMesh.Clear(); // remove all data before + // Don't use Assign() because Merge() checks which points are really needed. + // This method sets already the correct neighbourhood + unsigned long ct = meshPoints.size(); + std::list removeFaces; + for (MeshFacetArray::_TConstIterator it = meshFacets.begin(); it != meshFacets.end(); ++it) { + bool ok = true; + for (int i=0;i<3;i++) { + if (it->_aulPoints[i] >= ct) { + Base::Console().Warning("Face index %ld out of range\n", it->_aulPoints[i]); + ok = false; + } + } + + if (!ok) + removeFaces.push_front(it-meshFacets.begin()); + } + + for (std::list::iterator it = removeFaces.begin(); it != removeFaces.end(); ++it) + meshFacets.erase(meshFacets.begin() + *it); + + MeshKernel tmp; + tmp.Adopt(meshPoints,meshFacets); + this->_rclMesh.Merge(tmp); + + return true; +} + bool MeshInput::LoadPLY (std::istream &inp) { // http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/ diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index a056b17a4..e45d9f64e 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -89,6 +89,8 @@ public: bool LoadBinarySTL (std::istream &rstrIn); /** Loads an OBJ Mesh file. */ bool LoadOBJ (std::istream &rstrIn); + /** Loads an OFF Mesh file. */ + bool LoadOFF (std::istream &rstrIn); /** Loads a PLY Mesh file. */ bool LoadPLY (std::istream &rstrIn); /** Loads the mesh object from an XML file. */ diff --git a/src/Mod/Mesh/Gui/Command.cpp b/src/Mod/Mesh/Gui/Command.cpp index 35228e778..03d971474 100644 --- a/src/Mod/Mesh/Gui/Command.cpp +++ b/src/Mod/Mesh/Gui/Command.cpp @@ -289,11 +289,12 @@ void CmdMeshImport::activated(int iMsg) { // use current path as default QStringList filter; - filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj *.ply)"); + filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj *.off *.ply)"); filter << QObject::tr("Binary STL (*.stl)"); filter << QObject::tr("ASCII STL (*.ast)"); filter << QObject::tr("Binary Mesh (*.bms)"); filter << QObject::tr("Alias Mesh (*.obj)"); + filter << QObject::tr("Object File Format (*.off)"); filter << QObject::tr("Inventor V2.1 ascii (*.iv)"); filter << QObject::tr("Stanford Polygon (*.ply)"); //filter << "Nastran (*.nas *.bdf)";