2015-04-28 11:54:17 +00:00
|
|
|
/* ========================================================================= *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
|
|
|
|
* OpenMesh *
|
2015-04-28 11:33:32 +00:00
|
|
|
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
2015-04-28 13:07:46 +00:00
|
|
|
* Department of Computer Graphics and Multimedia *
|
2015-04-28 11:33:32 +00:00
|
|
|
* All rights reserved. *
|
|
|
|
|
* www.openmesh.org *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2009-11-17 13:54:16 +00:00
|
|
|
*---------------------------------------------------------------------------*
|
2015-04-28 11:33:32 +00:00
|
|
|
* This file is part of OpenMesh. *
|
|
|
|
|
*---------------------------------------------------------------------------*
|
2009-06-04 08:46:29 +00:00
|
|
|
* *
|
2015-04-28 11:33:32 +00:00
|
|
|
* Redistribution and use in source and binary forms, with or without *
|
|
|
|
|
* modification, are permitted provided that the following conditions *
|
|
|
|
|
* are met: *
|
|
|
|
|
* *
|
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice, *
|
|
|
|
|
* this list of conditions and the following disclaimer. *
|
|
|
|
|
* *
|
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright *
|
|
|
|
|
* notice, this list of conditions and the following disclaimer in the *
|
|
|
|
|
* documentation and/or other materials provided with the distribution. *
|
|
|
|
|
* *
|
|
|
|
|
* 3. Neither the name of the copyright holder nor the names of its *
|
|
|
|
|
* contributors may be used to endorse or promote products derived from *
|
|
|
|
|
* this software without specific prior written permission. *
|
|
|
|
|
* *
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
|
|
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
|
|
|
|
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
2015-04-28 11:54:17 +00:00
|
|
|
* *
|
|
|
|
|
* ========================================================================= */
|
2009-06-04 08:46:29 +00:00
|
|
|
|
|
|
|
|
/*===========================================================================*\
|
2009-11-17 13:54:16 +00:00
|
|
|
* *
|
2009-06-04 08:46:29 +00:00
|
|
|
* $Revision$ *
|
|
|
|
|
* $Date$ *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
|
|
|
|
\*===========================================================================*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//== INCLUDES =================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// STL
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
#include <float.h>
|
2012-05-08 15:05:10 +00:00
|
|
|
#include <fstream>
|
2016-08-15 17:27:55 +02:00
|
|
|
#include <cstring>
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
// OpenMesh
|
|
|
|
|
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
|
|
|
|
#include <OpenMesh/Core/IO/reader/STLReader.hh>
|
|
|
|
|
#include <OpenMesh/Core/IO/IOManager.hh>
|
|
|
|
|
|
2016-08-15 17:14:25 +02:00
|
|
|
//comppare strings crossplatform ignorign case
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#define strnicmp _strnicmp
|
|
|
|
|
#else
|
|
|
|
|
#define strnicmp strncasecmp
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
//=== NAMESPACES ==============================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace OpenMesh {
|
|
|
|
|
namespace IO {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=== INSTANCIATE =============================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// register the STLReader singleton with MeshReader
|
|
|
|
|
_STLReader_ __STLReaderInstance;
|
|
|
|
|
_STLReader_& STLReader() { return __STLReaderInstance; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=== IMPLEMENTATION ==========================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_STLReader_::
|
2009-11-17 13:54:16 +00:00
|
|
|
_STLReader_()
|
2009-02-06 13:37:46 +00:00
|
|
|
: eps_(FLT_MIN)
|
|
|
|
|
{
|
2009-11-17 13:54:16 +00:00
|
|
|
IOManager().register_module(this);
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
2009-11-17 13:54:16 +00:00
|
|
|
bool
|
2009-02-06 13:37:46 +00:00
|
|
|
_STLReader_::
|
|
|
|
|
read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
|
|
STL_Type file_type = NONE;
|
|
|
|
|
|
|
|
|
|
if ( check_extension( _filename, "stla" ) )
|
|
|
|
|
{
|
|
|
|
|
file_type = STLA;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if ( check_extension( _filename, "stlb" ) )
|
|
|
|
|
{
|
|
|
|
|
file_type = STLB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if ( check_extension( _filename, "stl" ) )
|
|
|
|
|
{
|
|
|
|
|
file_type = check_stl_type(_filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (file_type)
|
|
|
|
|
{
|
|
|
|
|
case STLA:
|
|
|
|
|
{
|
2013-09-26 10:35:13 +00:00
|
|
|
result = read_stla(_filename, _bi, _opt);
|
2009-02-06 13:37:46 +00:00
|
|
|
_opt -= Options::Binary;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-11-17 13:54:16 +00:00
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
case STLB:
|
|
|
|
|
{
|
2013-09-26 10:35:13 +00:00
|
|
|
result = read_stlb(_filename, _bi, _opt);
|
2009-02-06 13:37:46 +00:00
|
|
|
_opt += Options::Binary;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-11-17 13:54:16 +00:00
|
|
|
|
|
|
|
|
default:
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
result = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-17 13:54:16 +00:00
|
|
|
bool
|
|
|
|
|
_STLReader_::read(std::istream& _is,
|
|
|
|
|
BaseImporter& _bi,
|
|
|
|
|
Options& _opt)
|
|
|
|
|
{
|
|
|
|
|
|
2012-09-26 15:02:18 +00:00
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
|
|
if (_opt & Options::Binary)
|
2013-09-26 10:35:13 +00:00
|
|
|
result = read_stlb(_is, _bi, _opt);
|
2012-09-26 15:02:18 +00:00
|
|
|
else
|
2013-09-26 10:35:13 +00:00
|
|
|
result = read_stla(_is, _bi, _opt);
|
2009-11-17 13:54:16 +00:00
|
|
|
|
2012-09-26 15:02:18 +00:00
|
|
|
return result;
|
2009-11-17 13:54:16 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef DOXY_IGNORE_THIS
|
|
|
|
|
|
|
|
|
|
class CmpVec
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
2018-04-05 09:08:44 +02:00
|
|
|
explicit CmpVec(float _eps=FLT_MIN) : eps_(_eps) {}
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
bool operator()( const Vec3f& _v0, const Vec3f& _v1 ) const
|
|
|
|
|
{
|
2009-11-17 13:54:16 +00:00
|
|
|
if (fabs(_v0[0] - _v1[0]) <= eps_)
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
2009-11-17 13:54:16 +00:00
|
|
|
if (fabs(_v0[1] - _v1[1]) <= eps_)
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
return (_v0[2] < _v1[2] - eps_);
|
|
|
|
|
}
|
|
|
|
|
else return (_v0[1] < _v1[1] - eps_);
|
|
|
|
|
}
|
|
|
|
|
else return (_v0[0] < _v1[0] - eps_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
float eps_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2012-05-08 15:05:10 +00:00
|
|
|
void trimStdString( std::string& _string) {
|
|
|
|
|
// Trim Both leading and trailing spaces
|
|
|
|
|
|
|
|
|
|
size_t start = _string.find_first_not_of(" \t\r\n");
|
|
|
|
|
size_t end = _string.find_last_not_of(" \t\r\n");
|
|
|
|
|
|
|
|
|
|
if(( std::string::npos == start ) || ( std::string::npos == end))
|
|
|
|
|
_string = "";
|
|
|
|
|
else
|
|
|
|
|
_string = _string.substr( start, end-start+1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2009-11-17 13:54:16 +00:00
|
|
|
bool
|
2009-02-06 13:37:46 +00:00
|
|
|
_STLReader_::
|
2013-09-26 10:35:13 +00:00
|
|
|
read_stla(const std::string& _filename, BaseImporter& _bi, Options& _opt) const
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
2012-05-08 15:05:10 +00:00
|
|
|
std::fstream in( _filename.c_str(), std::ios_base::in );
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
if (!in)
|
|
|
|
|
{
|
2009-11-17 13:54:16 +00:00
|
|
|
omerr() << "[STLReader] : cannot not open file "
|
2009-02-06 13:37:46 +00:00
|
|
|
<< _filename
|
|
|
|
|
<< std::endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
bool res = read_stla(in, _bi, _opt);
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2012-04-05 15:10:37 +00:00
|
|
|
if (in)
|
2012-05-08 15:05:10 +00:00
|
|
|
in.close();
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
return res;
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2012-09-26 15:02:18 +00:00
|
|
|
bool
|
|
|
|
|
_STLReader_::
|
2013-09-26 10:35:13 +00:00
|
|
|
read_stla(std::istream& _in, BaseImporter& _bi, Options& _opt) const
|
2012-09-26 15:02:18 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
unsigned int i;
|
|
|
|
|
OpenMesh::Vec3f v;
|
|
|
|
|
OpenMesh::Vec3f n;
|
|
|
|
|
BaseImporter::VHandles vhandles;
|
|
|
|
|
|
|
|
|
|
CmpVec comp(eps_);
|
|
|
|
|
std::map<Vec3f, VertexHandle, CmpVec> vMap(comp);
|
|
|
|
|
std::map<Vec3f, VertexHandle, CmpVec>::iterator vMapIt;
|
|
|
|
|
|
|
|
|
|
std::string line;
|
|
|
|
|
|
2015-09-14 13:26:19 +02:00
|
|
|
std::string garbage;
|
|
|
|
|
std::stringstream strstream;
|
2015-09-11 15:41:16 +02:00
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
bool facet_normal(false);
|
2012-09-26 15:02:18 +00:00
|
|
|
|
|
|
|
|
while( _in && !_in.eof() ) {
|
|
|
|
|
|
|
|
|
|
// Get one line
|
|
|
|
|
std::getline(_in, line);
|
|
|
|
|
if ( _in.bad() ){
|
|
|
|
|
omerr() << " Warning! Could not read stream properly!\n";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Trim Both leading and trailing spaces
|
|
|
|
|
trimStdString(line);
|
|
|
|
|
|
|
|
|
|
// Normal found?
|
|
|
|
|
if (line.find("facet normal") != std::string::npos) {
|
2015-09-11 15:41:16 +02:00
|
|
|
strstream.str(line);
|
|
|
|
|
strstream.clear();
|
2012-09-26 15:02:18 +00:00
|
|
|
|
|
|
|
|
// facet
|
|
|
|
|
strstream >> garbage;
|
|
|
|
|
|
|
|
|
|
// normal
|
|
|
|
|
strstream >> garbage;
|
|
|
|
|
|
|
|
|
|
strstream >> n[0];
|
|
|
|
|
strstream >> n[1];
|
|
|
|
|
strstream >> n[2];
|
|
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
facet_normal = true;
|
2012-09-26 15:02:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Detected a triangle
|
|
|
|
|
if ( (line.find("outer") != std::string::npos) || (line.find("OUTER") != std::string::npos ) ) {
|
|
|
|
|
|
|
|
|
|
vhandles.clear();
|
|
|
|
|
|
|
|
|
|
for (i=0; i<3; ++i) {
|
|
|
|
|
// Get one vertex
|
|
|
|
|
std::getline(_in, line);
|
|
|
|
|
trimStdString(line);
|
|
|
|
|
|
2015-09-11 15:41:16 +02:00
|
|
|
strstream.str(line);
|
|
|
|
|
strstream.clear();
|
2012-09-26 15:02:18 +00:00
|
|
|
|
|
|
|
|
strstream >> garbage;
|
|
|
|
|
|
|
|
|
|
strstream >> v[0];
|
|
|
|
|
strstream >> v[1];
|
|
|
|
|
strstream >> v[2];
|
|
|
|
|
|
|
|
|
|
// has vector been referenced before?
|
|
|
|
|
if ((vMapIt=vMap.find(v)) == vMap.end())
|
|
|
|
|
{
|
|
|
|
|
// No : add vertex and remember idx/vector mapping
|
2013-01-08 07:24:43 +00:00
|
|
|
VertexHandle handle = _bi.add_vertex(v);
|
|
|
|
|
vhandles.push_back(handle);
|
|
|
|
|
vMap[v] = handle;
|
2012-09-26 15:02:18 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
// Yes : get index from map
|
|
|
|
|
vhandles.push_back(vMapIt->second);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add face only if it is not degenerated
|
|
|
|
|
if ((vhandles[0] != vhandles[1]) &&
|
|
|
|
|
(vhandles[0] != vhandles[2]) &&
|
|
|
|
|
(vhandles[1] != vhandles[2])) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FaceHandle fh = _bi.add_face(vhandles);
|
|
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
// set the normal if requested
|
|
|
|
|
// if a normal was requested but could not be found we unset the option
|
|
|
|
|
if (facet_normal) {
|
2013-09-26 13:02:09 +00:00
|
|
|
if (fh.is_valid() && _opt.face_has_normal())
|
2013-09-26 10:35:13 +00:00
|
|
|
_bi.set_normal(fh, n);
|
|
|
|
|
} else
|
|
|
|
|
_opt -= Options::FaceNormal;
|
2012-09-26 15:02:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
facet_normal = false;
|
2012-09-26 15:02:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2009-11-17 13:54:16 +00:00
|
|
|
bool
|
2009-02-06 13:37:46 +00:00
|
|
|
_STLReader_::
|
2013-09-26 10:35:13 +00:00
|
|
|
read_stlb(const std::string& _filename, BaseImporter& _bi, Options& _opt) const
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
2013-09-26 10:35:13 +00:00
|
|
|
std::fstream in( _filename.c_str(), std::ios_base::in | std::ios_base::binary);
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
if (!in)
|
|
|
|
|
{
|
2009-11-17 13:54:16 +00:00
|
|
|
omerr() << "[STLReader] : cannot not open file "
|
2009-02-06 13:37:46 +00:00
|
|
|
<< _filename
|
|
|
|
|
<< std::endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
bool res = read_stlb(in, _bi, _opt);
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
if (in)
|
|
|
|
|
in.close();
|
2012-03-30 09:47:37 +00:00
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
return res;
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2012-09-26 15:02:18 +00:00
|
|
|
bool
|
|
|
|
|
_STLReader_::
|
2013-09-26 10:35:13 +00:00
|
|
|
read_stlb(std::istream& _in, BaseImporter& _bi, Options& _opt) const
|
2012-09-26 15:02:18 +00:00
|
|
|
{
|
|
|
|
|
char dummy[100];
|
|
|
|
|
bool swapFlag;
|
|
|
|
|
unsigned int i, nT;
|
2013-09-26 10:35:13 +00:00
|
|
|
OpenMesh::Vec3f v, n;
|
2012-09-26 15:02:18 +00:00
|
|
|
BaseImporter::VHandles vhandles;
|
|
|
|
|
|
|
|
|
|
std::map<Vec3f, VertexHandle, CmpVec> vMap;
|
|
|
|
|
std::map<Vec3f, VertexHandle, CmpVec>::iterator vMapIt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check size of types
|
|
|
|
|
if ((sizeof(float) != 4) || (sizeof(int) != 4)) {
|
|
|
|
|
omerr() << "[STLReader] : wrong type size\n";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// determine endian mode
|
|
|
|
|
union { unsigned int i; unsigned char c[4]; } endian_test;
|
|
|
|
|
endian_test.i = 1;
|
|
|
|
|
swapFlag = (endian_test.c[3] == 1);
|
|
|
|
|
|
|
|
|
|
// read number of triangles
|
|
|
|
|
_in.read(dummy, 80);
|
|
|
|
|
nT = read_int(_in, swapFlag);
|
|
|
|
|
|
|
|
|
|
// read triangles
|
|
|
|
|
while (nT)
|
|
|
|
|
{
|
|
|
|
|
vhandles.clear();
|
|
|
|
|
|
2013-09-26 10:35:13 +00:00
|
|
|
// read triangle normal
|
|
|
|
|
n[0] = read_float(_in, swapFlag);
|
|
|
|
|
n[1] = read_float(_in, swapFlag);
|
|
|
|
|
n[2] = read_float(_in, swapFlag);
|
2012-09-26 15:02:18 +00:00
|
|
|
|
|
|
|
|
// triangle's vertices
|
|
|
|
|
for (i=0; i<3; ++i)
|
|
|
|
|
{
|
|
|
|
|
v[0] = read_float(_in, swapFlag);
|
|
|
|
|
v[1] = read_float(_in, swapFlag);
|
|
|
|
|
v[2] = read_float(_in, swapFlag);
|
|
|
|
|
|
|
|
|
|
// has vector been referenced before?
|
|
|
|
|
if ((vMapIt=vMap.find(v)) == vMap.end())
|
|
|
|
|
{
|
2013-01-08 07:24:43 +00:00
|
|
|
// No : add vertex and remember idx/vector mapping
|
|
|
|
|
VertexHandle handle = _bi.add_vertex(v);
|
|
|
|
|
vhandles.push_back(handle);
|
|
|
|
|
vMap[v] = handle;
|
2012-09-26 15:02:18 +00:00
|
|
|
}
|
|
|
|
|
else
|
2013-01-08 07:24:43 +00:00
|
|
|
// Yes : get index from map
|
|
|
|
|
vhandles.push_back(vMapIt->second);
|
2012-09-26 15:02:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add face only if it is not degenerated
|
|
|
|
|
if ((vhandles[0] != vhandles[1]) &&
|
|
|
|
|
(vhandles[0] != vhandles[2]) &&
|
2013-09-26 10:35:13 +00:00
|
|
|
(vhandles[1] != vhandles[2])) {
|
|
|
|
|
FaceHandle fh = _bi.add_face(vhandles);
|
|
|
|
|
|
2013-09-26 13:02:09 +00:00
|
|
|
if (fh.is_valid() && _opt.face_has_normal())
|
2013-09-26 10:35:13 +00:00
|
|
|
_bi.set_normal(fh, n);
|
|
|
|
|
}
|
2012-09-26 15:02:18 +00:00
|
|
|
|
|
|
|
|
_in.read(dummy, 2);
|
|
|
|
|
--nT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
_STLReader_::STL_Type
|
|
|
|
|
_STLReader_::
|
|
|
|
|
check_stl_type(const std::string& _filename) const
|
|
|
|
|
{
|
|
|
|
|
|
2016-08-16 15:06:19 +02:00
|
|
|
// open file
|
|
|
|
|
std::ifstream ifs (_filename.c_str(), std::ifstream::binary);
|
|
|
|
|
if(!ifs.good())
|
|
|
|
|
{
|
|
|
|
|
omerr() << "could not open file" << _filename << std::endl;
|
|
|
|
|
return NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//find first non whitespace character
|
|
|
|
|
std::string line = "";
|
|
|
|
|
std::size_t firstChar;
|
|
|
|
|
while(line.empty() && ifs.good())
|
|
|
|
|
{
|
|
|
|
|
std::getline(ifs,line);
|
|
|
|
|
firstChar = line.find_first_not_of("\t ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//check for ascii keyword solid
|
|
|
|
|
if(strnicmp("solid",&line[firstChar],5) == 0)
|
|
|
|
|
{
|
|
|
|
|
return STLA;
|
|
|
|
|
}
|
|
|
|
|
ifs.close();
|
|
|
|
|
|
|
|
|
|
//if the file does not start with solid it is probably STLB
|
|
|
|
|
//check the file size to verify it.
|
|
|
|
|
|
|
|
|
|
//open the file
|
|
|
|
|
FILE* in = fopen(_filename.c_str(), "rb");
|
|
|
|
|
if (!in) return NONE;
|
|
|
|
|
|
|
|
|
|
// determine endian mode
|
|
|
|
|
union { unsigned int i; unsigned char c[4]; } endian_test;
|
|
|
|
|
endian_test.i = 1;
|
|
|
|
|
bool swapFlag = (endian_test.c[3] == 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// read number of triangles
|
|
|
|
|
char dummy[100];
|
|
|
|
|
fread(dummy, 1, 80, in);
|
|
|
|
|
size_t nT = read_int(in, swapFlag);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// compute file size from nT
|
|
|
|
|
size_t binary_size = 84 + nT*50;
|
|
|
|
|
|
|
|
|
|
// get actual file size
|
|
|
|
|
size_t file_size(0);
|
|
|
|
|
rewind(in);
|
|
|
|
|
while (!feof(in))
|
|
|
|
|
file_size += fread(dummy, 1, 100, in);
|
|
|
|
|
fclose(in);
|
|
|
|
|
|
|
|
|
|
// if sizes match -> it's STLB
|
|
|
|
|
return (binary_size == file_size ? STLB : NONE);
|
2009-02-06 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
|
} // namespace IO
|
|
|
|
|
} // namespace OpenMesh
|
|
|
|
|
//=============================================================================
|