From 499f66f3ccd7613076988534b3940645cb08a5fd Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 2 Sep 2018 13:04:52 +0200 Subject: [PATCH] Step: check step-files for import. --- code/Importer/IFC/IFCLoader.cpp | 2 +- code/Importer/IFC/STEPFileReader.cpp | 1 - code/Importer/IFC/STEPFileReader.h | 29 ++++--- code/Importer/StepFile/StepFileImporter.cpp | 72 ++++++++++++++++- code/Importer/StepFile/StepFileImporter.h | 51 +++++++++++- code/ImporterRegistry.cpp | 6 ++ code/ObjFileImporter.cpp | 2 +- code/STEPFile.h | 86 +++++++++------------ include/assimp/LineSplitter.h | 1 + 9 files changed, 179 insertions(+), 71 deletions(-) diff --git a/code/Importer/IFC/IFCLoader.cpp b/code/Importer/IFC/IFCLoader.cpp index a40eedc1d..0f4046a80 100644 --- a/code/Importer/IFC/IFCLoader.cpp +++ b/code/Importer/IFC/IFCLoader.cpp @@ -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 diff --git a/code/Importer/IFC/STEPFileReader.cpp b/code/Importer/IFC/STEPFileReader.cpp index b1390b9de..bd56f71fe 100644 --- a/code/Importer/IFC/STEPFileReader.cpp +++ b/code/Importer/IFC/STEPFileReader.cpp @@ -549,4 +549,3 @@ void STEP::LazyObject::LazyInit() const // store the original id in the object instance obj->SetID(id); } - diff --git a/code/Importer/IFC/STEPFileReader.h b/code/Importer/IFC/STEPFileReader.h index b9dcf8948..667d28bfd 100644 --- a/code/Importer/IFC/STEPFileReader.h +++ b/code/Importer/IFC/STEPFileReader.h @@ -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 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 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); - } +// -------------------------------------------------------------------------- +/// @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 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 +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 diff --git a/code/Importer/StepFile/StepFileImporter.cpp b/code/Importer/StepFile/StepFileImporter.cpp index 35d70384c..1113fcbbc 100644 --- a/code/Importer/StepFile/StepFileImporter.cpp +++ b/code/Importer/StepFile/StepFileImporter.cpp @@ -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 +#include 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 fileStream(pIOHandler->Open(file, mode)); + if (!fileStream.get()) { + throw DeadlyImportError("Failed to open file " + file + "."); + } + + std::unique_ptr db(STEP::ReadFileHeader(fileStream)); + const STEP::HeaderInfo& head = static_cast(*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 + diff --git a/code/Importer/StepFile/StepFileImporter.h b/code/Importer/StepFile/StepFileImporter.h index 08ca3d508..a353c554e 100644 --- a/code/Importer/StepFile/StepFileImporter.h +++ b/code/Importer/StepFile/StepFileImporter.h @@ -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 namespace Assimp { @@ -18,5 +63,7 @@ protected: private: }; -} -} +} // Namespace STEP +} // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_STEPFILE_IMPORTER diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index 4a8428d25..1caa5b9f2 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -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. */ diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 2b6730e4e..60cd18816 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -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; } diff --git a/code/STEPFile.h b/code/STEPFile.h index 1f24dbc6b..418847f7f 100644 --- a/code/STEPFile.h +++ b/code/STEPFile.h @@ -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 ConverterMap; - public: - template 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 const T& To() const { @@ -473,7 +467,6 @@ namespace STEP { return dynamic_cast(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 - 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 - 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 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 - inline bool operator==( std::shared_ptr lo, T whatever ) { + inline + bool operator==( std::shared_ptr lo, T whatever ) { return *lo == whatever; // XXX use std::forward if we have 0x } template - inline bool operator==( const std::pair >& lo, T whatever ) { + inline + bool operator==( const std::pair >& 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 - 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 - struct ListOf : public std::vector - { + struct ListOf : public std::vector { typedef typename T::Out OutScalar; typedef ListOf Out; - ListOf() { static_assert(min_cnt <= max_cnt || !max_cnt, "min_cnt <= max_cnt || !max_cnt"); } - }; - // ------------------------------------------------------------------------------ template 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 @@ -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::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()(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 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; } diff --git a/include/assimp/LineSplitter.h b/include/assimp/LineSplitter.h index e5ac98d85..2914923b5 100644 --- a/include/assimp/LineSplitter.h +++ b/include/assimp/LineSplitter.h @@ -241,4 +241,5 @@ private: }; } + #endif // INCLUDED_LINE_SPLITTER_H