125 #ifndef __H__STL_READER
126 #define __H__STL_READER
134 #ifdef STL_READER_NO_EXCEPTIONS
135 #define STL_READER_THROW(msg) return false;
136 #define STL_READER_COND_THROW(cond, msg) if(cond) return false;
139 #define STL_READER_THROW(msg) {std::stringstream ss; ss << msg; throw(std::runtime_error(ss.str()));}
142 #define STL_READER_COND_THROW(cond, msg) if(cond){std::stringstream ss; ss << msg; throw(std::runtime_error(ss.str()));}
189 template <
class TNumberContainer,
class TIndexContainer>
191 TNumberContainer& coordsOut,
192 TNumberContainer& normalsOut,
193 TIndexContainer& trisOut,
194 TIndexContainer& solidRangesOut);
201 template <
class TNumberContainer,
class TIndexContainer>
203 TNumberContainer& coordsOut,
204 TNumberContainer& normalsOut,
205 TIndexContainer& trisOut,
206 TIndexContainer& solidRangesOut);
213 template <
class TNumberContainer,
class TIndexContainer>
215 TNumberContainer& coordsOut,
216 TNumberContainer& normalsOut,
217 TIndexContainer& trisOut,
218 TIndexContainer& solidRangesOut);
229 template <
class TNumber =
float,
class TIndex =
unsigned int>
249 #ifndef STL_READER_NO_EXCEPTIONS
255 #ifndef STL_READER_NO_EXCEPTIONS
256 }
catch (std::exception& e) {
286 return tris.size() / 3;
292 return &
tris [ti * 3];
298 return tris [ti * 3 + ci];
329 return solids.size () - 1;
397 namespace stl_reader_impl {
401 template <
typename number_t,
typename index_t>
408 return (c[0] == data[0]) && (c[1] == data[1]) && (c[2] == data[2]);
413 return (c[0] != data[0]) || (c[1] != data[1]) || (c[2] != data[2]);
418 return (data[0] < c[0])
419 || (data[0] == c[0] && data[1] < c[1])
420 || (data[0] == c[0] && data[1] == c[1] && data[2] < c[2]);
423 inline number_t& operator [] (
const size_t i) {
return data[i];}
424 inline number_t operator [] (
const size_t i)
const {
return data[i];}
429 template <
class TNumberContainer,
class TIndexContainer>
431 TIndexContainer& trisInOut,
435 &coordsWithIndexInOut)
442 sort (coordsWithIndexInOut.begin(), coordsWithIndexInOut.end());
445 size_t numUnique = 1;
446 for(
size_t i = 1; i < coordsWithIndexInOut.size(); ++i){
447 if(coordsWithIndexInOut[i] != coordsWithIndexInOut[i - 1])
451 uniqueCoordsOut.resize (numUnique * 3);
452 vector<index_t> newIndex (coordsWithIndexInOut.size());
458 for(
size_t i = 0; i < 3; ++i)
459 uniqueCoordsOut[i] = coordsWithIndexInOut[0][i];
461 for(
size_t i = 1; i < coordsWithIndexInOut.size(); ++i){
463 if(c != coordsWithIndexInOut[i - 1]){
465 for(
size_t j = 0; j < 3; ++j)
466 uniqueCoordsOut[curInd * 3 + j] = coordsWithIndexInOut[i][j];
469 newIndex[c.
index] = curInd;
474 size_t numUniqueTriInds = 0;
475 for(
size_t i = 0; i < trisInOut.size(); i+=3){
477 for(
int j = 0; j < 3; ++j)
478 ni[j] = newIndex[trisInOut[i+j]];
480 if((ni[0] != ni[1]) && (ni[0] != ni[2]) && (ni[1] != ni[2])){
481 for(
int j = 0; j < 3; ++j)
482 trisInOut[numUniqueTriInds + j] = ni[j];
483 numUniqueTriInds += 3;
487 if(numUniqueTriInds < trisInOut.size())
488 trisInOut.resize (numUniqueTriInds);
493 template <
class TNumberContainer,
class TIndexContainer>
495 TNumberContainer& coordsOut,
496 TNumberContainer& normalsOut,
497 TIndexContainer& trisOut,
498 TIndexContainer& solidRangesOut)
501 return ReadStlFile_ASCII(filename, coordsOut, normalsOut, trisOut, solidRangesOut);
507 template <
class TNumberContainer,
class TIndexContainer>
509 TNumberContainer& coordsOut,
510 TNumberContainer& normalsOut,
511 TIndexContainer& trisOut,
512 TIndexContainer& solidRangesOut)
515 using namespace stl_reader_impl;
523 solidRangesOut.clear();
525 ifstream in(filename);
528 vector<CoordWithIndex <number_t, index_t> > coordsWithIndex;
531 vector<string> tokens;
533 int maxNumTokens = 0;
534 size_t numFaceVrts = 0;
536 while(!(in.eof() || in.fail()))
543 istringstream line(buffer);
545 while(!(line.eof() || line.fail())){
546 if(tokenCount >= maxNumTokens){
547 maxNumTokens = tokenCount + 1;
548 tokens.resize(maxNumTokens);
550 line >> tokens[tokenCount];
556 string& tok = tokens[0];
557 if(tok.compare(
"vertex") == 0){
560 ": vertex not specified correctly in line " << lineCount);
564 CoordWithIndex <number_t, index_t> c;
565 for(
size_t i = 0; i < 3; ++i)
566 c[i] = atof(tokens[i+1].c_str());
567 c.index =
static_cast<index_t
>(coordsWithIndex.size());
568 coordsWithIndex.push_back(c);
571 else if(tok.compare(
"facet") == 0)
574 "ERROR while reading from " << filename <<
575 ": triangle not specified correctly in line " << lineCount);
578 "ERROR while reading from " << filename <<
579 ": Missing normal specifier in line " << lineCount);
582 for(
size_t i = 0; i < 3; ++i)
583 normalsOut.push_back (atof(tokens[i+2].c_str()));
587 else if(tok.compare(
"outer") == 0){
589 "ERROR while reading from " << filename <<
590 ": expecting outer loop in line " << lineCount);
592 else if(tok.compare(
"endfacet") == 0){
594 "ERROR while reading from " << filename <<
595 ": bad number of vertices specified for face in line " << lineCount);
597 trisOut.push_back(coordsWithIndex.size() - 3);
598 trisOut.push_back(coordsWithIndex.size() - 2);
599 trisOut.push_back(coordsWithIndex.size() - 1);
601 else if(tok.compare(
"solid") == 0){
602 solidRangesOut.push_back(trisOut.size() / 3);
608 solidRangesOut.push_back(trisOut.size() / 3);
616 template <
class TNumberContainer,
class TIndexContainer>
618 TNumberContainer& coordsOut,
619 TNumberContainer& normalsOut,
620 TIndexContainer& trisOut,
621 TIndexContainer& solidRangesOut)
624 using namespace stl_reader_impl;
632 solidRangesOut.clear();
634 ifstream in(filename, ios::binary);
638 in.read(stl_header, 80);
641 unsigned int numTris = 0;
642 in.read((
char*)&numTris, 4);
645 vector<CoordWithIndex <number_t, index_t> > coordsWithIndex;
647 for(
unsigned int tri = 0; tri < numTris; ++tri){
649 in.read((
char*)d, 12 * 4);
652 for(
int i = 0; i < 3; ++i)
653 normalsOut.push_back (d[i]);
655 for(
size_t ivrt = 1; ivrt < 4; ++ivrt){
656 CoordWithIndex <number_t, index_t> c;
657 for(
size_t i = 0; i < 3; ++i)
658 c[i] = d[ivrt * 3 + i];
659 c.index =
static_cast<index_t
>(coordsWithIndex.size());
660 coordsWithIndex.push_back(c);
663 trisOut.push_back(coordsWithIndex.size() - 3);
664 trisOut.push_back(coordsWithIndex.size() - 2);
665 trisOut.push_back(coordsWithIndex.size() - 1);
669 STL_READER_COND_THROW(!in,
"Error while parsing additional triangle data in binary stl file " << filename);
672 solidRangesOut.push_back(0);
673 solidRangesOut.push_back(trisOut.size() / 3);
684 ifstream in(filename);
689 transform(firstWord.begin(), firstWord.end(), firstWord.begin(), ::tolower);
691 return firstWord.compare(
"solid") == 0;
convenience mesh class which makes accessing the stl data more easy
Definition: stl_reader.h:230
const TIndex * tri_corner_inds(const size_t ti) const
returns an array of 3 indices, one for each corner vertex of the triangle
Definition: stl_reader.h:290
const TIndex * raw_tris() const
returns a pointer to the triangle array, containing num_tris()*3 entries.
Definition: stl_reader.h:367
const TIndex * raw_solids() const
returns a pointer to the solids array, containing num_solids()+1 entries.
Definition: stl_reader.h:377
std::vector< TIndex > solids
Definition: stl_reader.h:388
const TNumber * tri_corner_coords(const size_t ti, const size_t ci) const
returns an array of 3 floating point values, one for each coordinate of the specified corner of the s...
Definition: stl_reader.h:308
const TNumber * raw_normals() const
returns a pointer to the normal array, containing num_tris()*3 entries.
Definition: stl_reader.h:357
size_t num_solids() const
returns the number of solids of the mesh
Definition: stl_reader.h:325
std::vector< TNumber > coords
Definition: stl_reader.h:385
size_t num_tris() const
returns the number of triangles in the mesh
Definition: stl_reader.h:284
std::vector< TNumber > normals
Definition: stl_reader.h:386
const TNumber * vrt_coords(const size_t vi) const
returns an array of 3 floating point values, one for each coordinate of the vertex
Definition: stl_reader.h:278
StlMesh(const char *filename)
initializes the mesh from the stl-file specified through filename
Definition: stl_reader.h:239
TIndex solid_tris_begin(const size_t si) const
returns the index of the first triangle in the given solid
Definition: stl_reader.h:333
const TIndex tri_corner_ind(const size_t ti, const size_t ci) const
returns the index of the corner with index 0<=ci<3 of triangle ti
Definition: stl_reader.h:296
const TNumber * raw_coords() const
returns a pointer to the coordinate array, containing num_vrts()*3 entries.
Definition: stl_reader.h:347
const TNumber * tri_normal(const size_t ti) const
returns an array of 3 floating point values defining the normal of a tri
Definition: stl_reader.h:314
bool read_file(const char *filename)
fills the mesh with the contents of the specified stl-file
Definition: stl_reader.h:245
StlMesh()
initializes an empty mesh
Definition: stl_reader.h:233
TIndex solid_tris_end(const size_t si) const
returns the index of the triangle behind the last triangle in the given solid
Definition: stl_reader.h:339
size_t num_vrts() const
returns the number of vertices in the mesh
Definition: stl_reader.h:272
std::vector< TIndex > tris
Definition: stl_reader.h:387
bool operator==(const MathVector< N, T > &v, const MathVector< N, T > &w)
Definition: math_vector.h:523
bool operator<(const MathVector< N, T > &v, const MathVector< N, T > &w)
Definition: math_vector.h:541
bool operator!=(const MathVector< N, T > &v, const MathVector< N, T > &w)
Definition: math_vector.h:552
Definition: smart_pointer.h:814
void RemoveDoubles(TNumberContainer &uniqueCoordsOut, TIndexContainer &trisInOut, std::vector< CoordWithIndex< typename TNumberContainer::value_type, typename TIndexContainer::value_type > > &coordsWithIndexInOut)
Definition: stl_reader.h:430
Definition: stl_reader.h:146
bool ReadStlFile_BINARY(const char *filename, TNumberContainer &coordsOut, TNumberContainer &normalsOut, TIndexContainer &trisOut, TIndexContainer &solidRangesOut)
Reads a binary stl file into several arrays.
Definition: stl_reader.h:617
bool ReadStlFile(const char *filename, TNumberContainer &coordsOut, TNumberContainer &normalsOut, TIndexContainer &trisOut, TIndexContainer &solidRangesOut)
Reads an ASCII or binary stl file into several arrays.
Definition: stl_reader.h:494
bool ReadStlFile_ASCII(const char *filename, TNumberContainer &coordsOut, TNumberContainer &normalsOut, TIndexContainer &trisOut, TIndexContainer &solidRangesOut)
Reads an ASCII stl file into several arrays.
Definition: stl_reader.h:508
bool StlFileHasASCIIFormat(const char *filename)
Determines whether a stl file has ASCII format.
Definition: stl_reader.h:681
T value_type
Definition: sparsematrix_interface.h:2
#define STL_READER_COND_THROW(cond, msg)
Throws an std::runtime_error with the given message, if the given condition evaluates to true.
Definition: stl_reader.h:142
#define STL_READER_THROW(msg)
Throws an std::runtime_error with the given message.
Definition: stl_reader.h:139
Definition: stl_reader.h:402
index_t index
Definition: stl_reader.h:404