Mantid
Loading...
Searching...
No Matches
LoadBinaryStl.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include <Poco/File.h>
11#include <fstream>
12namespace Mantid::DataHandling {
13
14namespace {
15uint32_t getNumberTriangles(Kernel::BinaryStreamReader streamReader, const int header) {
16 uint32_t numberTrianglesLong;
17 // skip header
18 streamReader.moveStreamToPosition(header);
19 // Read the number of triangles
20 streamReader >> numberTrianglesLong;
21 return numberTrianglesLong;
22}
23} // namespace
24
25bool LoadBinaryStl::isBinarySTL(const std::string &filename) {
26 Poco::File stlFile = Poco::File(filename);
27 if (!stlFile.exists()) {
28 // if the file cannot be read then it is not a valid binary Stl File
29 return false;
30 }
31 auto fileSize = stlFile.getSize();
32 if (fileSize < HEADER_SIZE + TRIANGLE_COUNT_DATA_SIZE) {
33 // File is smaller than header plus number of triangles, cannot be binary
34 // format stl
35 return false;
36 }
37 uint32_t numberTrianglesLong;
38 std::ifstream myFile(filename.c_str(), openMode);
40 numberTrianglesLong = getNumberTriangles(streamReader, HEADER_SIZE);
41 myFile.close();
42 if (!(fileSize == (HEADER_SIZE + TRIANGLE_COUNT_DATA_SIZE + (numberTrianglesLong * TRIANGLE_DATA_SIZE)))) {
43 // File is not the Header plus the number of triangles it claims to be long,
44 // invalid binary Stl
45 return false;
46 }
47 // if both conditions pass, file is likely binary stl
48 return true;
49}
50
51std::unique_ptr<Geometry::MeshObject> LoadBinaryStl::readShape() {
52
54 const auto numberTrianglesLong = getNumberTriangles(streamReader, HEADER_SIZE);
56 // now read in all the triangles
57 m_triangle.reserve(3 * numberTrianglesLong);
58 m_vertices.reserve(3 * numberTrianglesLong);
59 g_logstl.debug("Began reading " + std::to_string(numberTrianglesLong) + " triangles.");
60 uint32_t vertexCount = 0;
61 for (uint32_t i = 0; i < numberTrianglesLong; i++) {
62
63 // find next triangle, skipping the normal and attribute
64 streamReader.moveStreamToPosition(nextToRead);
65 readTriangle(streamReader, vertexCount);
66 nextToRead += TRIANGLE_DATA_SIZE;
67 }
69 m_vertices.shrink_to_fit();
70 m_triangle.shrink_to_fit();
71 g_logstl.debug("Read All");
72
74 if (m_setMaterial) {
75 g_logstl.information("Setting Material");
76 ReadMaterial reader;
78 material = *(reader.buildMaterial());
79 } else {
80 material = Mantid::Kernel::Material();
81 }
82 auto retVal = std::make_unique<Geometry::MeshObject>(std::move(m_triangle), std::move(m_vertices), material);
83 return retVal;
84}
85
86void LoadBinaryStl::readTriangle(Kernel::BinaryStreamReader streamReader, uint32_t &vertexCount) {
87 // read in the verticies
88 for (int i = 0; i < 3; i++) {
89 float xVal;
90 float yVal;
91 float zVal;
92 streamReader >> xVal;
93 streamReader >> yVal;
94 streamReader >> zVal;
95 // mesh objects are stored in metres, so convert to that
96 auto vec = createScaledV3D(xVal, yVal, zVal);
97 auto vertexPair = std::pair<Kernel::V3D, uint32_t>(vec, vertexCount);
98 auto emplacementResult = vertexSet.insert(vertexPair);
99 // check if the value was new to the map and increase the value to assign to
100 // the next if so
101 if (emplacementResult.second) {
102 vertexCount++;
103 }
104 m_triangle.emplace_back(emplacementResult.first->second);
105 }
106}
107
108} // namespace Mantid::DataHandling
std::unique_ptr< Geometry::MeshObject > readShape() override
static constexpr int HEADER_SIZE
Definition: LoadBinaryStl.h:26
static constexpr uint32_t VECTOR_DATA_SIZE
Definition: LoadBinaryStl.h:29
static bool isBinarySTL(const std::string &filename)
static constexpr uint32_t TRIANGLE_COUNT_DATA_SIZE
Definition: LoadBinaryStl.h:28
static constexpr uint32_t TRIANGLE_DATA_SIZE
Definition: LoadBinaryStl.h:27
void readTriangle(Kernel::BinaryStreamReader, uint32_t &vertexCount)
static constexpr std::ios_base::openmode openMode
Definition: LoadBinaryStl.h:30
ReadMaterial::MaterialParameters m_params
Definition: LoadStl.h:61
std::unordered_set< std::pair< Kernel::V3D, uint32_t >, HashV3DPair, V3DTrueComparator > vertexSet
Definition: LoadStl.h:62
std::vector< uint32_t > m_triangle
Definition: MeshFileIO.h:64
Kernel::V3D createScaledV3D(double xVal, double yVal, double zVal)
scales a 3D point according the units defined in the MeshFileIO class
Definition: MeshFileIO.cpp:53
std::vector< Kernel::V3D > m_vertices
Definition: MeshFileIO.h:65
This class contains code for interpreting a material input for SetSampleMaterial, validating the para...
Definition: ReadMaterial.h:26
std::unique_ptr< Kernel::Material > buildMaterial()
Construct the material,.
void setMaterialParameters(const MaterialParameters &params)
Set the parameters to build the material to the builder, taking into account which values were and we...
Assists with reading a binary file by providing standard overloads for the istream operators (>>) to ...
void moveStreamToPosition(size_t nbytes)
Move the stream to nbytes past the beginning of the file.
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition: Material.h:50
std::string to_string(const wide_integer< Bits, Signed > &n)