Mantid
Loading...
Searching...
No Matches
LoadAsciiStl.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 +
9#include <boost/algorithm/string.hpp>
10#include <fstream>
11namespace Mantid::DataHandling {
12
13bool LoadAsciiStl::isAsciiSTL(const std::string &filename) {
14 std::ifstream file(filename.c_str());
15 if (!file) {
16 // if the file cannot be read then it is not a valid asciiStl File
17 return false;
18 }
19 std::string line;
20 getline(file, line);
21 boost::trim(line);
22 return (line.size() >= 5 && line.substr(0, 5) == "solid");
23}
24
25std::unique_ptr<Geometry::MeshObject> LoadAsciiStl::readShape() {
26 std::string line;
27 getline(m_file, line);
29 Kernel::V3D t1, t2, t3;
30 uint32_t vertexCount = 0;
31 while (readSTLTriangle(m_file, t1, t2, t3)) {
32 // Add triangle if all 3 vertices are distinct
33 if (!areEqualVertices(t1, t2) && !areEqualVertices(t1, t3) && !areEqualVertices(t2, t3)) {
34 auto vertexPair = std::pair<Kernel::V3D, uint32_t>(t1, vertexCount);
35 auto emplacementResult = vertexSet.insert(vertexPair);
36 if (emplacementResult.second) {
37 vertexCount++;
38 }
39 m_triangle.emplace_back(emplacementResult.first->second);
40 vertexPair = std::pair<Kernel::V3D, uint32_t>(t2, vertexCount);
41 emplacementResult = vertexSet.insert(vertexPair);
42 if (emplacementResult.second) {
43 vertexCount++;
44 }
45 m_triangle.emplace_back(emplacementResult.first->second);
46 vertexPair = std::pair<Kernel::V3D, uint32_t>(t3, vertexCount);
47 emplacementResult = vertexSet.insert(vertexPair);
48 if (emplacementResult.second) {
49 vertexCount++;
50 }
51 m_triangle.emplace_back(emplacementResult.first->second);
52 }
53 }
56 if (m_setMaterial) {
57 g_logstl.information("Setting Material");
58 ReadMaterial reader;
60 material = *(reader.buildMaterial());
61 } else {
62 material = Mantid::Kernel::Material();
63 }
64 auto retVal = std::make_unique<Geometry::MeshObject>(std::move(m_triangle), std::move(m_vertices), material);
65 return retVal;
66}
67
68bool LoadAsciiStl::readSTLTriangle(std::ifstream &file, Kernel::V3D &v1, Kernel::V3D &v2, Kernel::V3D &v3) {
69 if (readSTLLine(file, "facet") && readSTLLine(file, "outer loop")) {
70 readSTLVertex(file, v1);
71 readSTLVertex(file, v2);
72 readSTLVertex(file, v3);
73 } else {
74 return false; // End of file
75 }
76 return readSTLLine(file, "endloop") && readSTLLine(file, "endfacet");
77}
78
79bool LoadAsciiStl::readSTLVertex(std::ifstream &file, Kernel::V3D &vertex) {
80 std::string line;
82 if (getline(file, line)) {
83 boost::trim(line);
84 std::vector<std::string> tokens;
85 boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on);
86 if (tokens.size() == 4 && tokens[0] == "vertex") {
87 double xVal = std::stod(tokens[1]);
88 double yVal = std::stod(tokens[2]);
89 double zVal = std::stod(tokens[3]);
90 vertex = createScaledV3D(xVal, yVal, zVal);
91 return true;
92 } else {
93 throw Kernel::Exception::ParseError("Error on reading STL vertex", m_filename, m_lineNumber);
94 }
95 }
96 throw Kernel::Exception::ParseError("Error on reading STL triangle", m_filename, m_lineNumber);
97}
98
99// Read, check and ignore line in STL file. Return true if line is read
100bool LoadAsciiStl::readSTLLine(std::ifstream &file, std::string const &type) {
101 std::string line;
102 m_lineNumber++;
103 if (getline(file, line)) {
104 boost::trim(line);
105 if (line.size() < type.size() || line.substr(0, type.size()) != type) {
106 // Before throwing, check for endsolid statment
107 const std::string type2 = "endsolid";
108 if (line.size() < type2.size() || line.substr(0, type2.size()) != type2) {
109 throw Kernel::Exception::ParseError("Expected STL line begining with " + type + " or " + type2, m_filename,
111 } else {
112 return false; // ends reading at endsolid
113 }
114 }
115 return true; // expected line read, then ignored
116 } else {
117 return false; // end of file
118 }
119}
120
121} // namespace Mantid::DataHandling
std::unique_ptr< Geometry::MeshObject > readShape() override
bool readSTLVertex(std::ifstream &file, Kernel::V3D &vertex)
static bool isAsciiSTL(const std::string &filename)
bool readSTLLine(std::ifstream &file, std::string const &type)
bool readSTLTriangle(std::ifstream &file, Kernel::V3D &v1, Kernel::V3D &v2, Kernel::V3D &v3)
bool areEqualVertices(Kernel::V3D const &v1, Kernel::V3D const &v2) const
Definition: LoadStl.cpp:15
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...
Records the filename, the description of failure and the line on which it happened.
Definition: Exception.h:115
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition: Material.h:50
Class for 3D vectors.
Definition: V3D.h:34