mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 23:01:17 +00:00
Fix small binary STLs failing to load as ASCII (#16130)
This commit is contained in:
@@ -75,6 +75,19 @@ static FILE *stl_open_count_facets(stl_file *stl, const char *file, unsigned int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Zero normals and coordinates like 10 or 15 have no byte above 127, so the test above can miss a binary file.
|
||||||
|
// Its size still matches its facet count; text read as that count would need a file of gigabytes.
|
||||||
|
if (stl->stats.type == ascii) {
|
||||||
|
uint32_t header_num_facets;
|
||||||
|
fseek(fp, custom_header_length, SEEK_SET);
|
||||||
|
if (fread(&header_num_facets, sizeof(uint32_t), 1, fp) == 1) {
|
||||||
|
#if BOOST_ENDIAN_BIG_BYTE
|
||||||
|
stl_internal_reverse_quads((char*)&header_num_facets, 4);
|
||||||
|
#endif /* BOOST_ENDIAN_BIG_BYTE */
|
||||||
|
if (header_size + uint64_t(header_num_facets) * SIZEOF_STL_FACET == file_size)
|
||||||
|
stl->stats.type = binary;
|
||||||
|
}
|
||||||
|
}
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
|
|
||||||
uint32_t num_facets = 0;
|
uint32_t num_facets = 0;
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
#include <catch2/catch_all.hpp>
|
#include <catch2/catch_all.hpp>
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/Format/STL.hpp"
|
#include "libslic3r/Format/STL.hpp"
|
||||||
|
#include "test_utils.hpp"
|
||||||
|
#include <boost/nowide/fstream.hpp>
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
|
|
||||||
@@ -58,3 +61,25 @@ SCENARIO("Reading an STL file", "[stl]") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("A binary STL whose facet bytes never exceed 127 is read as binary", "[stl]")
|
||||||
|
{
|
||||||
|
const indexed_triangle_set cube = its_make_cube(10., 10., 10.);
|
||||||
|
std::string stl(80, '\0');
|
||||||
|
const auto append = [&stl](const auto &value) { stl.append(reinterpret_cast<const char *>(&value), sizeof(value)); };
|
||||||
|
append(uint32_t(cube.indices.size()));
|
||||||
|
const stl_normal zero_normal = stl_normal::Zero();
|
||||||
|
for (const stl_triangle_vertex_indices &facet : cube.indices) {
|
||||||
|
append(zero_normal);
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
append(cube.vertices[facet[i]]);
|
||||||
|
append(uint16_t(0));
|
||||||
|
}
|
||||||
|
REQUIRE(std::none_of(stl.begin() + 84, stl.begin() + 84 + 128, [](unsigned char c) { return c > 127; }));
|
||||||
|
|
||||||
|
ScopedTemporaryFile file(".stl");
|
||||||
|
boost::nowide::ofstream(file.string(), std::ios::binary) << stl;
|
||||||
|
Model model;
|
||||||
|
REQUIRE(load_stl(file.string().c_str(), &model));
|
||||||
|
REQUIRE(is_approx(model.objects.front()->volumes.front()->mesh().size(), Vec3d(10, 10, 10)));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user