Skip to content
Snippets Groups Projects
Commit 19a52e11 authored by Sam Jenkins's avatar Sam Jenkins
Browse files

Re #23574 Added function to check if stl if binary

parent 83b7c567
No related branches found
No related tags found
No related merge requests found
#ifndef MANTID_DATAHANDLING_LOADBINSTL_H_
#define MANTID_DATAHANDLING_LOADBINSTL_H_
#include "MantidAPI/IFileLoader.h"
#include "MantidGeometry/Objects/MeshObject.h"
#include "MantidKernel/BinaryStreamReader.h"
#include <MantidKernel/V3D.h>
namespace Mantid {
namespace DataHandling {
class DLLExport LoadBinStl : public API::IFileLoader<Kernel::FileDescriptor> {
class DLLExport LoadBinStl {
public:
/// Algorithm's name
const std::string name() const override;
/// Algorithm's version
int version() const override;
/// Algorithm's category for identification
const std::string category() const override;
const std::string summary() const override;
/// Returns a confidence value that this algorithm can load a file
int confidence(Kernel::FileDescriptor &descriptor) const {return 0;};
/// Returns a value indicating whether or not loader wants to load multiple
/// files into a single workspace
bool loadMutipleAsOne() { return false; }
LoadBinStl(std::string filename):m_filename(filename){}
std::unique_ptr<Geometry::MeshObject> readStl();
bool isBinarySTL();
private:
void init() override;
void exec() override;
void readStl(std::string filename);
uint32_t getNumberTriangles(Kernel::BinaryStreamReader);
void readTriangle(Kernel::BinaryStreamReader);
std::string m_filename;
std::vector<uint16_t> m_triangle;
std::vector<Kernel::V3D> m_verticies;
};
......
......@@ -4,60 +4,54 @@
#include "MantidGeometry/Objects/MeshObject.h"
#include <fstream>
#include <iostream>
#include <Poco/File.h>
namespace Mantid {
namespace DataHandling {
using Mantid::API::WorkspaceProperty;
using Mantid::Kernel::Direction;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(LoadBinStl)
//----------------------------------------------------------------------------------------------
/// Algorithms name for identification. @see Algorithm::name
const std::string LoadBinStl::name() const { return "LoadBinStl"; }
/// Algorithm's version for identification. @see Algorithm::version
int LoadBinStl::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string LoadBinStl::category() const {
return "DataHandling\\LoadBinStl";
}
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string LoadBinStl::summary() const {
return "Load mesh from binary stl file for diffraction";
}
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void LoadBinStl::init() {
const std::vector<std::string> exts{".stl"};
declareProperty(Kernel::make_unique<Mantid::API::FileProperty>(
"Filename", "", Mantid::API::FileProperty::Load, exts),
"The path name of the file containing the shape");
bool LoadBinStl::isBinarySTL(){
//each triangle is 50 bytes
const uint32_t SIZE_OF_TRIANGLE = 50;
Poco::File stlFile = Poco::File(m_filename);
uint32_t fileSize = stlFile.getSize();
if (fileSize<84) {
//File is smaller than header plus number of triangles, cannot be binary format stl
return false;
}
uint32_t numberTrianglesLong;
std::ifstream myFile(m_filename.c_str(), std::ios::in | std::ios::binary);
Kernel::BinaryStreamReader streamReader = Kernel::BinaryStreamReader(myFile);
numberTrianglesLong = getNumberTriangles(streamReader);
myFile.close();
if (!fileSize == (84 + (numberTrianglesLong * SIZE_OF_TRIANGLE))){
//File is not the Header plus the number of triangles it claims to be long, invalid binary Stl
return false;
}
//if both conditions pass, file is likely binary stl
return true;
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void LoadBinStl::exec() {
auto filename = getProperty("Filename");
readStl(filename);
}
void LoadBinStl::readStl(std::string filename) {
std::ifstream myFile(filename.c_str(), std::ios::in | std::ios::binary);
uint32_t getNumberTriangles(Kernel::BinaryStreamReader streamReader){
uint32_t numberTrianglesLong;
Kernel::BinaryStreamReader streamReader = Kernel::BinaryStreamReader(myFile);
// skip header
streamReader.moveStreamToPosition(80);
// Read the number of triangles
streamReader >> numberTrianglesLong;
return numberTrianglesLong;
}
std::unique_ptr<Geometry::MeshObject> LoadBinStl::readStl() {
std::ifstream myFile(m_filename.c_str(), std::ios::in | std::ios::binary);
uint32_t numberTrianglesLong;
Kernel::BinaryStreamReader streamReader = Kernel::BinaryStreamReader(myFile);
numberTrianglesLong = getNumberTriangles(streamReader);
uint32_t next = 96;
const uint32_t STEPSIZE = 50;
// now read in all the triangles
......@@ -71,7 +65,7 @@ void LoadBinStl::readStl(std::string filename) {
std::unique_ptr<Geometry::MeshObject> retVal = std::unique_ptr<Geometry::MeshObject>(
new Geometry::MeshObject(std::move(m_triangle), std::move(m_verticies),
Mantid::Kernel::Material()));
return;
return retVal;
}
void LoadBinStl::readTriangle(Kernel::BinaryStreamReader streamReader) {
......
#include "MantidDataHandling/LoadSampleShape.h"
#include "MantidDataHandling/LoadBinStl.h"
#include "MantidGeometry/Objects/MeshObject.h"
#include "MantidAPI/FileProperty.h"
......@@ -123,14 +124,16 @@ std::unique_ptr<MeshObject> readSTLMeshObject(std::ifstream &file) {
}
std::unique_ptr<Geometry::MeshObject> readSTLSolid(std::ifstream &file,
std::string &name) {
std::string &name,std::string filename) {
// Read Solid name
// We expect line after trimming to be "solid "+name.
std::string line;
if (getline(file, line)) {
boost::trim(line);
if (line.size() < 5 || line.substr(0, 5) != "solid") {
throw std::runtime_error("Expected start of solid");
//attempt to load stl binary instead
std::unique_ptr<LoadBinStl> binaryStlReader = Kernel::make_unique<LoadBinStl>();
return binaryStlReader->LoadBinStl::readStl(filename);
} else {
name = line.substr(6, std::string::npos);
}
......@@ -308,7 +311,7 @@ void LoadSampleShape::exec() {
shape = readOFFshape(file);
} else /* stl */ {
std::string solidName = "";
shape = readSTLSolid(file, solidName);
shape = readSTLSolid(file, solidName, filename);
}
// Put shape into sample.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment