Step: check step-files for import.

pull/2175/head
Kim Kulling 2018-09-02 13:04:52 +02:00
parent c75bc99902
commit 499f66f3cc
9 changed files with 179 additions and 71 deletions

View File

@ -134,7 +134,7 @@ IFCImporter::~IFCImporter()
bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
const std::string& extension = GetExtension(pFile);
if (extension == "ifc" || extension == "ifczip" || extension == "stp" ) {
if (extension == "ifc" || extension == "ifczip" /*|| extension == "stp" */) {
return true;
} else if ((!extension.length() || checkSig) && pIOHandler) {
// note: this is the common identification for STEP-encoded files, so

View File

@ -549,4 +549,3 @@ void STEP::LazyObject::LazyInit() const
// store the original id in the object instance
obj->SetID(id);
}

View File

@ -48,18 +48,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
namespace STEP {
// ### Parsing a STEP file is a twofold procedure ###
// --------------------------------------------------------------------------
// 1) read file header and return to caller, who checks if the
// file is of a supported schema ..
DB* ReadFileHeader(std::shared_ptr<IOStream> stream);
// --------------------------------------------------------------------------
// 2) read the actual file contents using a user-supplied set of
// conversion functions to interpret the data.
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, const char* const* inverse_indices_to_track, size_t len2);
template <size_t N, size_t N2> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
// --------------------------------------------------------------------------
/// @brief Parsing a STEP file is a twofold procedure.
/// 1) read file header and return to caller, who checks if the
/// file is of a supported schema ..
DB* ReadFileHeader(std::shared_ptr<IOStream> stream);
/// 2) read the actual file contents using a user-supplied set of
/// conversion functions to interpret the data.
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, const char* const* inverse_indices_to_track, size_t len2);
/// @brief Helper to read a file.
template <size_t N, size_t N2>
inline
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N,arr2,N2);
}
}
} // ! STEP
} // ! Assimp

View File

@ -1,4 +1,52 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* 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.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
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
OWNER 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.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_STEPFILE_IMPORTER
#include "StepFileImporter.h"
#include "../../Importer/IFC/STEPFileReader.h"
#include <assimp/importerdesc.h>
#include <assimp/DefaultIOSystem.h>
namespace Assimp {
namespace STEP {
@ -25,7 +73,7 @@ StepFileImporter::~StepFileImporter() {
bool StepFileImporter::CanRead(const std::string& file, IOSystem* pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(file);
if ( extension == "stp" ) {
if ( extension == "stp" || extension == "step" ) {
return true;
} else if ((!extension.length() || checkSig) && pIOHandler) {
const char* tokens[] = { "ISO-10303-21" };
@ -40,9 +88,25 @@ const aiImporterDesc *StepFileImporter::GetInfo() const {
return &desc;
}
void StepFileImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
static const std::string mode = "rb";
static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN";
void StepFileImporter::InternReadFile(const std::string &file, aiScene* pScene, IOSystem* pIOHandler) {
// Read file into memory
std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
}
std::unique_ptr<STEP::DB> db(STEP::ReadFileHeader(fileStream));
const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader();
if (!head.fileSchema.size() || head.fileSchema != StepFileSchema) {
DeadlyImportError("Unrecognized file schema: " + head.fileSchema);
}
}
}
}
} // Namespace STEP
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEPFILE_IMPORTER

View File

@ -1,5 +1,50 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* 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.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
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
OWNER 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.
---------------------------------------------------------------------------
*/
#pragma once
#ifndef ASSIMP_BUILD_NO_STEPFILE_IMPORTER
#include <assimp/BaseImporter.h>
namespace Assimp {
@ -18,5 +63,7 @@ protected:
private:
};
}
}
} // Namespace STEP
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEPFILE_IMPORTER

View File

@ -197,6 +197,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
# include "MMDImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_STEPFILE_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
#endif
namespace Assimp {
@ -352,6 +355,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
out.push_back( new MMDImporter() );
#endif
#ifndef ASSIMP_BUILD_NO_STEPFILE_IMPORTER
out.push_back(new STEP::StepFileImporter());
#endif
}
/** will delete all registered importers. */

View File

@ -105,7 +105,7 @@ bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler ,
}
// ------------------------------------------------------------------------------------------------
const aiImporterDesc* ObjFileImporter::GetInfo () const {
const aiImporterDesc* ObjFileImporter::GetInfo() const {
return &desc;
}

View File

@ -363,8 +363,7 @@ namespace STEP {
* to extract valid C++ objects out of a STEP file. Those conversion functions
* may, however, perform further schema validations. */
// -------------------------------------------------------------------------------
class ConversionSchema
{
class ConversionSchema {
public:
struct SchemaEntry {
SchemaEntry( const char *name, ConvertObjectProc func )
@ -379,30 +378,27 @@ namespace STEP {
typedef std::map<std::string,ConvertObjectProc> ConverterMap;
public:
template <size_t N>
explicit ConversionSchema( const SchemaEntry (& schemas)[N]) {
*this = schemas;
}
ConversionSchema() {}
ConversionSchema() {
public:
}
ConvertObjectProc GetConverterProc(const std::string& name) const {
ConverterMap::const_iterator it = converters.find(name);
return it == converters.end() ? NULL : (*it).second;
return it == converters.end() ? nullptr : (*it).second;
}
bool IsKnownToken(const std::string& name) const {
return converters.find(name) != converters.end();
}
const char* GetStaticStringForToken(const std::string& token) const {
ConverterMap::const_iterator it = converters.find(token);
return it == converters.end() ? NULL : (*it).first.c_str();
return it == converters.end() ? nullptr : (*it).first.c_str();
}
@ -450,8 +446,6 @@ namespace STEP {
// empty
}
public:
// utilities to simplify casting to concrete types
template <typename T>
const T& To() const {
@ -473,7 +467,6 @@ namespace STEP {
return dynamic_cast<T*>(this);
}
public:
uint64_t GetID() const {
return id;
}
@ -500,9 +493,11 @@ namespace STEP {
/** CRTP shared base class for use by concrete entity implementation classes */
// ------------------------------------------------------------------------------
template <typename TDerived, size_t arg_count>
struct ObjectHelper : virtual Object
{
ObjectHelper() : aux_is_derived(0) {}
struct ObjectHelper : virtual Object {
ObjectHelper()
: aux_is_derived(0) {
// empty
}
static Object* Construct(const STEP::DB& db, const EXPRESS::LIST& params) {
// make sure we don't leak if Fill() throws an exception
@ -531,10 +526,16 @@ namespace STEP {
/** Class template used to represent OPTIONAL data members in the converted schema */
// ------------------------------------------------------------------------------
template <typename T>
struct Maybe
{
Maybe() : have() {}
explicit Maybe(const T& ptr) : ptr(ptr), have(true) {
struct Maybe {
Maybe()
: have() {
// empty
}
explicit Maybe(const T& ptr)
: ptr(ptr)
, have(true) {
// empty
}
@ -571,7 +572,6 @@ namespace STEP {
}
private:
template <typename T2> friend struct InternGenericConvert;
operator T&() {
@ -586,16 +586,13 @@ namespace STEP {
/** A LazyObject is created when needed. Before this happens, we just keep
the text line that contains the object definition. */
// -------------------------------------------------------------------------------
class LazyObject
{
class LazyObject {
friend class DB;
public:
public:
LazyObject(DB& db, uint64_t id, uint64_t line, const char* type,const char* args);
~LazyObject();
public:
Object& operator * () {
if (!obj) {
LazyInit();
@ -653,38 +650,37 @@ namespace STEP {
}
private:
void LazyInit() const;
private:
mutable uint64_t id;
const char* const type;
DB& db;
mutable const char* args;
mutable Object* obj;
};
template <typename T>
inline bool operator==( std::shared_ptr<LazyObject> lo, T whatever ) {
inline
bool operator==( std::shared_ptr<LazyObject> lo, T whatever ) {
return *lo == whatever; // XXX use std::forward if we have 0x
}
template <typename T>
inline bool operator==( const std::pair<uint64_t, std::shared_ptr<LazyObject> >& lo, T whatever ) {
inline
bool operator==( const std::pair<uint64_t, std::shared_ptr<LazyObject> >& lo, T whatever ) {
return *(lo.second) == whatever; // XXX use std::forward if we have 0x
}
// ------------------------------------------------------------------------------
/** Class template used to represent lazily evaluated object references in the converted schema */
// ------------------------------------------------------------------------------
template <typename T>
struct Lazy
{
struct Lazy {
typedef Lazy Out;
Lazy(const LazyObject* obj = NULL) : obj(obj) {
Lazy(const LazyObject* obj = nullptr)
: obj(obj) {
// empty
}
operator const T*() const {
@ -710,19 +706,15 @@ namespace STEP {
/** Class template used to represent LIST and SET data members in the converted schema */
// ------------------------------------------------------------------------------
template <typename T, uint64_t min_cnt, uint64_t max_cnt=0uL>
struct ListOf : public std::vector<typename T::Out>
{
struct ListOf : public std::vector<typename T::Out> {
typedef typename T::Out OutScalar;
typedef ListOf Out;
ListOf() {
static_assert(min_cnt <= max_cnt || !max_cnt, "min_cnt <= max_cnt || !max_cnt");
}
};
// ------------------------------------------------------------------------------
template <typename TOut>
struct PickBaseType {
@ -734,7 +726,8 @@ namespace STEP {
typedef EXPRESS::ENTITY Type;
};
template <> struct PickBaseType< std::shared_ptr< const EXPRESS::DataType > >;
template<>
struct PickBaseType< std::shared_ptr< const EXPRESS::DataType > >;
// ------------------------------------------------------------------------------
template <typename T>
@ -742,8 +735,7 @@ namespace STEP {
void operator()(T& out, const std::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& /*db*/) {
try{
out = dynamic_cast< const typename PickBaseType<T>::Type& > ( *in );
}
catch(std::bad_cast&) {
} catch(std::bad_cast&) {
throw TypeError("type error reading literal field");
}
}
@ -816,7 +808,6 @@ namespace STEP {
return InternGenericConvertList<T1,N1,N2>()(a,b,db);
}
// ------------------------------------------------------------------------------
/** Lightweight manager class that holds the map of all objects in a
* STEP file. DB's are exclusively maintained by the functions in
@ -833,7 +824,6 @@ namespace STEP {
friend class LazyObject;
public:
// objects indexed by ID - this can grow pretty large (i.e some hundred million
// entries), so use raw pointers to avoid *any* overhead.
typedef std::map<uint64_t,const LazyObject* > ObjectMap;
@ -858,19 +848,16 @@ namespace STEP {
: reader(reader)
, splitter(*reader,true,true)
, evaluated_count()
, schema( NULL )
, schema( nullptr )
{}
public:
~DB() {
for(ObjectMap::value_type& o : objects) {
delete o.second;
}
}
public:
uint64_t GetObjectCount() const {
return objects.size();
}
@ -899,7 +886,6 @@ namespace STEP {
return refs;
}
bool KeepInverseIndicesForType(const char* const type) const {
return inv_whitelist.find(type) != inv_whitelist.end();
}
@ -911,7 +897,7 @@ namespace STEP {
if (it != objects.end()) {
return (*it).second;
}
return NULL;
return nullptr;
}

View File

@ -241,4 +241,5 @@ private:
};
}
#endif // INCLUDED_LINE_SPLITTER_H