Merge branch 'master' into coverity_scan

pull/2286/head
Kim Kulling 2016-11-22 22:04:08 +01:00
commit b2ec1c27c9
20 changed files with 409 additions and 183 deletions

View File

@ -336,25 +336,21 @@ auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap* pTexMap1, const
} while(pInputList.size() > 0); } while(pInputList.size() > 0);
} }
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
{ {
if(pMetadataList.size() > 0) if ( !metadataList.empty() )
{ {
if(pSceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); if(sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
// copy collected metadata to output node. // copy collected metadata to output node.
pSceneNode.mMetaData = new aiMetadata(); sceneNode.mMetaData = aiMetadata::Alloc( metadataList.size() );
pSceneNode.mMetaData->mNumProperties = pMetadataList.size(); size_t meta_idx( 0 );
pSceneNode.mMetaData->mKeys = new aiString[pSceneNode.mMetaData->mNumProperties];
pSceneNode.mMetaData->mValues = new aiMetadataEntry[pSceneNode.mMetaData->mNumProperties];
size_t meta_idx = 0; for(const CAMFImporter_NodeElement_Metadata& metadata: metadataList)
for(const CAMFImporter_NodeElement_Metadata& metadata: pMetadataList)
{ {
pSceneNode.mMetaData->Set(meta_idx++, metadata.Type, aiString(metadata.Value)); sceneNode.mMetaData->Set(meta_idx++, metadata.Type, aiString(metadata.Value));
} }
}// if(pMetadataList.size() > 0) }// if(!metadataList.empty())
} }
void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode) void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)

View File

@ -56,7 +56,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream> #include <sstream>
#include <cctype> #include <cctype>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -461,29 +460,32 @@ void BaseImporter::TextFileToBuffer(IOStream* stream,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace Assimp namespace Assimp {
{
// Represents an import request // Represents an import request
struct LoadRequest struct LoadRequest {
{
LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id) LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
: file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id) : file(_file)
{ , flags(_flags)
if (_map) , refCnt(1)
, scene(NULL)
, loaded(false)
, id(_id) {
if ( _map ) {
map = *_map; map = *_map;
} }
}
bool operator== ( const std::string& f ) const {
return file == f;
}
const std::string file; const std::string file;
unsigned int flags; unsigned int flags;
unsigned int refCnt; unsigned int refCnt;
aiScene* scene; aiScene *scene;
bool loaded; bool loaded;
BatchLoader::PropertyMap map; BatchLoader::PropertyMap map;
unsigned int id; unsigned int id;
bool operator== (const std::string& f) const {
return file == f;
}
}; };
} }

View File

@ -1075,10 +1075,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
// create metadata on node // create metadata on node
std::size_t numStaticMetaData = 2; std::size_t numStaticMetaData = 2;
aiMetadata* data = new aiMetadata(); aiMetadata* data = aiMetadata::Alloc( unparsedProperties.size() + numStaticMetaData );
data->mNumProperties = unparsedProperties.size() + numStaticMetaData;
data->mKeys = new aiString[ data->mNumProperties ]();
data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
nd.mMetaData = data; nd.mMetaData = data;
int index = 0; int index = 0;
@ -1089,22 +1086,22 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
// add unparsed properties to the node's metadata // add unparsed properties to the node's metadata
for( const DirectPropertyMap::value_type& prop : unparsedProperties ) { for( const DirectPropertyMap::value_type& prop : unparsedProperties ) {
// Interpret the property as a concrete type // Interpret the property as a concrete type
if ( const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >() ) if ( const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >() ) {
data->Set( index++, prop.first, interpreted->Value() ); data->Set( index++, prop.first, interpreted->Value() );
else if ( const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >() ) } else if ( const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >() ) {
data->Set( index++, prop.first, interpreted->Value() ); data->Set( index++, prop.first, interpreted->Value() );
else if ( const TypedProperty<uint64_t>* interpreted = prop.second->As<TypedProperty<uint64_t> >() ) } else if ( const TypedProperty<uint64_t>* interpreted = prop.second->As<TypedProperty<uint64_t> >() ) {
data->Set( index++, prop.first, interpreted->Value() ); data->Set( index++, prop.first, interpreted->Value() );
else if ( const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >() ) } else if ( const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >() ) {
data->Set( index++, prop.first, interpreted->Value() ); data->Set( index++, prop.first, interpreted->Value() );
else if ( const TypedProperty<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >() ) } else if ( const TypedProperty<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >() ) {
data->Set( index++, prop.first, aiString( interpreted->Value() ) ); data->Set( index++, prop.first, aiString( interpreted->Value() ) );
else if ( const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >() ) } else if ( const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >() ) {
data->Set( index++, prop.first, interpreted->Value() ); data->Set( index++, prop.first, interpreted->Value() );
else } else {
assert( false ); ai_assert( false );
}
} }
} }

View File

@ -707,15 +707,11 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
} }
if (!properties.empty()) { if (!properties.empty()) {
aiMetadata* data = new aiMetadata(); aiMetadata* data = aiMetadata::Alloc( properties.size() );
data->mNumProperties = properties.size(); unsigned int index( 0 );
data->mKeys = new aiString[data->mNumProperties](); for ( const Metadata::value_type& kv : properties ) {
data->mValues = new aiMetadataEntry[data->mNumProperties](); data->Set( index++, kv.first, aiString( kv.second ) );
}
unsigned int index = 0;
for(const Metadata::value_type& kv : properties)
data->Set(index++, kv.first, aiString(kv.second));
nd->mMetaData = data; nd->mMetaData = data;
} }
} }

View File

@ -451,6 +451,7 @@ void ObjFileParser::getFace( aiPrimitiveType type ) {
DefaultLogger::get()->error("Obj: Ignoring empty face"); DefaultLogger::get()->error("Obj: Ignoring empty face");
// skip line and clean up // skip line and clean up
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
delete face;
return; return;
} }

View File

@ -901,11 +901,8 @@ void SIBImporter::InternReadFile(const std::string& pFile,
// Mark instanced objects as being so. // Mark instanced objects as being so.
if (n >= firstInst) if (n >= firstInst)
{ {
node->mMetaData = new aiMetadata; node->mMetaData = aiMetadata::Alloc( 1 );
node->mMetaData->mNumProperties = 1; node->mMetaData->Set( 0, "IsInstance", true );
node->mMetaData->mKeys = new aiString[1];
node->mMetaData->mValues = new aiMetadataEntry[1];
node->mMetaData->Set(0, "IsInstance", true);
} }
} }

View File

@ -43,7 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// possible as new fields are added to assimp structures. // possible as new fields are added to assimp structures.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** @file Implements Assimp::SceneCombiner. This is a smart utility /**
* @file Implements Assimp::SceneCombiner. This is a smart utility
* class that combines multiple scenes, meshes, ... into one. Currently * class that combines multiple scenes, meshes, ... into one. Currently
* these utilities are used by the IRR and LWS loaders and the * these utilities are used by the IRR and LWS loaders and the
* OptimizeGraph step. * OptimizeGraph step.
@ -198,8 +199,9 @@ void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList) void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList)
{ {
unsigned int cnt; unsigned int cnt;
for (cnt = 0; cnt < attach->mNumChildren;++cnt) for ( cnt = 0; cnt < attach->mNumChildren; ++cnt ) {
AttachToGraph(attach->mChildren[cnt],srcList); AttachToGraph( attach->mChildren[ cnt ], srcList );
}
cnt = 0; cnt = 0;
for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin(); for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin();
@ -1219,13 +1221,12 @@ void SceneCombiner::Copy (aiNode** _dest, const aiNode* src)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiMetadata** _dest, const aiMetadata* src) void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src)
{ {
ai_assert(NULL != _dest && NULL != src); ai_assert( NULL != _dest );
ai_assert( NULL != src);
aiMetadata* dest = *_dest = new aiMetadata(); aiMetadata* dest = *_dest = aiMetadata::Alloc( src->mNumProperties );
dest->mNumProperties = src->mNumProperties;
dest->mKeys = new aiString[src->mNumProperties];
std::copy(src->mKeys, src->mKeys + src->mNumProperties, dest->mKeys); std::copy(src->mKeys, src->mKeys + src->mNumProperties, dest->mKeys);
dest->mValues = new aiMetadataEntry[src->mNumProperties]; dest->mValues = new aiMetadataEntry[src->mNumProperties];

View File

@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SpatialSort.h" #include "SpatialSort.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "Vertex.h" #include "Vertex.h"
#include <assimp/ai_assert.h>
#include <stdio.h> #include <stdio.h>
using namespace Assimp; using namespace Assimp;
@ -55,9 +56,7 @@ void mydummy() {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class CatmullClarkSubdivider : public Subdivider class CatmullClarkSubdivider : public Subdivider
{ {
public: public:
void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input); void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
void Subdivide (aiMesh** smesh, size_t nmesh, void Subdivide (aiMesh** smesh, size_t nmesh,
aiMesh** out, unsigned int num, bool discard_input); aiMesh** out, unsigned int num, bool discard_input);
@ -74,8 +73,6 @@ public:
unsigned int ref; unsigned int ref;
}; };
typedef std::vector<unsigned int> UIntVector; typedef std::vector<unsigned int> UIntVector;
typedef std::map<uint64_t,Edge> EdgeMap; typedef std::map<uint64_t,Edge> EdgeMap;
@ -99,7 +96,6 @@ public:
unsigned int eh_tmp0__, eh_tmp1__; unsigned int eh_tmp0__, eh_tmp1__;
private: private:
void InternSubdivide (const aiMesh* const * smesh, void InternSubdivide (const aiMesh* const * smesh,
size_t nmesh,aiMesh** out, unsigned int num); size_t nmesh,aiMesh** out, unsigned int num);
}; };
@ -128,7 +124,8 @@ void CatmullClarkSubdivider::Subdivide (
bool discard_input bool discard_input
) )
{ {
assert(mesh != out); ai_assert(mesh != out);
Subdivide(&mesh,1,&out,num,discard_input); Subdivide(&mesh,1,&out,num,discard_input);
} }
@ -142,12 +139,12 @@ void CatmullClarkSubdivider::Subdivide (
bool discard_input bool discard_input
) )
{ {
ai_assert(NULL != smesh && NULL != out); ai_assert( NULL != smesh );
ai_assert( NULL != out );
// course, both regions may not overlap // course, both regions may not overlap
assert(smesh<out || smesh+nmesh>out+nmesh); ai_assert(smesh<out || smesh+nmesh>out+nmesh);
if (!num) { if (!num) {
// No subdivision at all. Need to copy all the meshes .. argh. // No subdivision at all. Need to copy all the meshes .. argh.
if (discard_input) { if (discard_input) {
for (size_t s = 0; s < nmesh; ++s) { for (size_t s = 0; s < nmesh; ++s) {

View File

@ -1480,10 +1480,11 @@ void X3DImporter::ParseNode_Head()
XML_CheckNode_MustBeEmpty(); XML_CheckNode_MustBeEmpty();
// adding metadata from <head> as MetaString from <Scene> // adding metadata from <head> as MetaString from <Scene>
bool added( false );
CX3DImporter_NodeElement_MetaString* ms = new CX3DImporter_NodeElement_MetaString(NodeElement_Cur); CX3DImporter_NodeElement_MetaString* ms = new CX3DImporter_NodeElement_MetaString(NodeElement_Cur);
ms->Name = mReader->getAttributeValueSafe("name"); ms->Name = mReader->getAttributeValueSafe("name");
// name can not be empty // name must not be empty
if(!ms->Name.empty()) if(!ms->Name.empty())
{ {
ms->Value.push_back(mReader->getAttributeValueSafe("content")); ms->Value.push_back(mReader->getAttributeValueSafe("content"));
@ -1491,8 +1492,13 @@ void X3DImporter::ParseNode_Head()
if ( NodeElement_Cur != nullptr ) if ( NodeElement_Cur != nullptr )
{ {
NodeElement_Cur->Child.push_back( ms ); NodeElement_Cur->Child.push_back( ms );
added = true;
} }
} }
// if an error has occurred, release instance
if ( !added ) {
delete ms;
}
}// if(XML_CheckNode_NameEqual("meta")) }// if(XML_CheckNode_NameEqual("meta"))
}// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END)

View File

@ -130,37 +130,35 @@ public:
public: public:
std::string ID;///< ID of the element. Can be empty. In X3D synonym for "ID" attribute. std::string ID;///< ID of the element. Can be empty. In X3D synonym for "ID" attribute.
CX3DImporter_NodeElement* Parent;///< Parrent element. If nullptr then this node is root. CX3DImporter_NodeElement* Parent;///< Parent element. If nullptr then this node is root.
std::list<CX3DImporter_NodeElement*> Child;///< Child elements. std::list<CX3DImporter_NodeElement*> Child;///< Child elements.
/***********************************************/ /***********************************************/
/****************** Functions ******************/ /****************** Functions ******************/
/***********************************************/ /***********************************************/
private: /// @brief The destructor, virtual.
virtual ~CX3DImporter_NodeElement() {
// empty
}
/// \fn CX3DImporter_NodeElement(const CX3DImporter_NodeElement& pNodeElement) private:
/// Disabled copy constructor. /// Disabled copy constructor.
CX3DImporter_NodeElement(const CX3DImporter_NodeElement& pNodeElement); CX3DImporter_NodeElement(const CX3DImporter_NodeElement& pNodeElement);
/// \fn CX3DImporter_NodeElement& operator=(const CX3DImporter_NodeElement& pNodeElement)
/// Disabled assign operator. /// Disabled assign operator.
CX3DImporter_NodeElement& operator=(const CX3DImporter_NodeElement& pNodeElement); CX3DImporter_NodeElement& operator=(const CX3DImporter_NodeElement& pNodeElement);
/// \fn CX3DImporter_NodeElement()
/// Disabled default constructor. /// Disabled default constructor.
CX3DImporter_NodeElement(); CX3DImporter_NodeElement();
protected: protected:
/// \fn CX3DImporter_NodeElement(const EType pType, CX3DImporter_NodeElement* pParent)
/// In constructor inheritor must set element type. /// In constructor inheritor must set element type.
/// \param [in] pType - element type. /// \param [in] pType - element type.
/// \param [in] pParent - parent element. /// \param [in] pParent - parent element.
CX3DImporter_NodeElement(const EType pType, CX3DImporter_NodeElement* pParent) CX3DImporter_NodeElement(const EType pType, CX3DImporter_NodeElement* pParent)
: Type(pType), Parent(pParent) : Type(pType), Parent(pParent)
{} {}
};// class IX3DImporter_NodeElement };// class IX3DImporter_NodeElement
/// \class CX3DImporter_NodeElement_Group /// \class CX3DImporter_NodeElement_Group

View File

@ -758,15 +758,14 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN
size_t meta_idx; size_t meta_idx;
PostprocessHelper_CollectMetadata(pNodeElement, meta_list);// find metadata in current node element. PostprocessHelper_CollectMetadata(pNodeElement, meta_list);// find metadata in current node element.
if(meta_list.size() > 0) if ( !meta_list.empty() )
{ {
if(pSceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); if ( pSceneNode.mMetaData != nullptr ) {
throw DeadlyImportError( "Postprocess. MetaData member in node are not nullptr. Something went wrong." );
}
// copy collected metadata to output node. // copy collected metadata to output node.
pSceneNode.mMetaData = new aiMetadata(); pSceneNode.mMetaData = aiMetadata::Alloc( meta_list.size() );
pSceneNode.mMetaData->mNumProperties = meta_list.size();
pSceneNode.mMetaData->mKeys = new aiString[pSceneNode.mMetaData->mNumProperties];
pSceneNode.mMetaData->mValues = new aiMetadataEntry[pSceneNode.mMetaData->mNumProperties];
meta_idx = 0; meta_idx = 0;
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++) for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++)
{ {
@ -808,7 +807,7 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN
throw DeadlyImportError("Postprocess. Unknown metadata type."); throw DeadlyImportError("Postprocess. Unknown metadata type.");
}// if((*it)->Type == CX3DImporter_NodeElement::ENET_Meta*) else }// if((*it)->Type == CX3DImporter_NodeElement::ENET_Meta*) else
}// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++) }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++)
}// if(meta_list.size() > 0) }// if( !meta_list.empty() )
} }
}// namespace Assimp }// namespace Assimp

View File

@ -744,6 +744,10 @@ namespace glTF
SExtension(const EType pType) SExtension(const EType pType)
: Type(pType) : Type(pType)
{} {}
virtual ~SExtension() {
// empty
}
}; };
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
@ -765,8 +769,13 @@ namespace glTF
/// \fn SCompression_Open3DGC /// \fn SCompression_Open3DGC
/// Constructor. /// Constructor.
SCompression_Open3DGC() SCompression_Open3DGC()
: SExtension(Compression_Open3DGC) : SExtension(Compression_Open3DGC) {
{} // empty
}
virtual ~SCompression_Open3DGC() {
// empty
}
}; };
#endif #endif

View File

@ -1005,6 +1005,12 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
size_t tval = ifs.GetNIntAttribute(idx); size_t tval = ifs.GetNIntAttribute(idx);
switch( ifs.GetIntAttributeType( idx ) ) switch( ifs.GetIntAttributeType( idx ) )
{ {
case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN:
case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX:
case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID:
case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID:
break;
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx)));
} }
@ -1049,10 +1055,14 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
} }
} }
for(size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) for(size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) {
{ switch(ifs.GetIntAttributeType(idx)) {
switch(ifs.GetIntAttributeType(idx)) case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN:
{ case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX:
case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID:
case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID:
break;
// ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint))); // ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx)));
@ -1062,7 +1072,9 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
// //
// Decode data // Decode data
// //
if(decoder.DecodePayload(ifs, bstream) != o3dgc::O3DGC_OK) throw DeadlyImportError("GLTF: can not decode Open3DGC data."); if ( decoder.DecodePayload( ifs, bstream ) != o3dgc::O3DGC_OK ) {
throw DeadlyImportError( "GLTF: can not decode Open3DGC data." );
}
// Set encoded region for "buffer". // Set encoded region for "buffer".
buf->EncodedRegion_Mark(pCompression_Open3DGC.Offset, pCompression_Open3DGC.Count, decoded_data, decoded_data_size, id); buf->EncodedRegion_Mark(pCompression_Open3DGC.Offset, pCompression_Open3DGC.Count, decoded_data, decoded_data_size, id);

View File

@ -37,9 +37,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER #ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
@ -94,8 +91,6 @@ namespace Assimp {
} // end of namespace Assimp } // end of namespace Assimp
glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene, glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
const ExportProperties* pProperties, bool isBinary) const ExportProperties* pProperties, bool isBinary)
: mFilename(filename) : mFilename(filename)
@ -419,17 +414,18 @@ Ref<Node> FindSkeletonRootJoint(Ref<Skin>& skinRef)
return parentNodeRef; return parentNodeRef;
} }
void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData) void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData)
{ {
if (aim->mNumBones < 1) { if (aimesh->mNumBones < 1) {
return; return;
} }
// Store the vertex joint and weight data. // Store the vertex joint and weight data.
vec4* vertexJointData = new vec4[aim->mNumVertices]; const size_t NumVerts( aimesh->mNumVertices );
vec4* vertexWeightData = new vec4[aim->mNumVertices]; vec4* vertexJointData = new vec4[ NumVerts ];
int* jointsPerVertex = new int[aim->mNumVertices]; vec4* vertexWeightData = new vec4[ NumVerts ];
for (size_t i = 0; i < aim->mNumVertices; ++i) { int* jointsPerVertex = new int[ NumVerts ];
for (size_t i = 0; i < NumVerts; ++i) {
jointsPerVertex[i] = 0; jointsPerVertex[i] = 0;
for (size_t j = 0; j < 4; ++j) { for (size_t j = 0; j < 4; ++j) {
vertexJointData[i][j] = 0; vertexJointData[i][j] = 0;
@ -437,8 +433,8 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
} }
} }
for (unsigned int idx_bone = 0; idx_bone < aim->mNumBones; ++idx_bone) { for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) {
const aiBone* aib = aim->mBones[idx_bone]; const aiBone* aib = aimesh->mBones[idx_bone];
// aib->mName =====> skinRef->jointNames // aib->mName =====> skinRef->jointNames
// Find the node with id = mName. // Find the node with id = mName.
@ -470,7 +466,9 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
float vertWeight = aib->mWeights[idx_weights].mWeight; float vertWeight = aib->mWeights[idx_weights].mWeight;
// A vertex can only have at most four joint weights. Ignore all others. // A vertex can only have at most four joint weights. Ignore all others.
if (jointsPerVertex[vertexId] > 3) { continue; } if (jointsPerVertex[vertexId] > 3) {
continue;
}
vertexJointData[vertexId][jointsPerVertex[vertexId]] = jointNamesIndex; vertexJointData[vertexId][jointsPerVertex[vertexId]] = jointNamesIndex;
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight; vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
@ -481,11 +479,18 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
} // End: for-loop mNumMeshes } // End: for-loop mNumMeshes
Mesh::Primitive& p = meshRef->primitives.back(); Mesh::Primitive& p = meshRef->primitives.back();
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aim->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
if (vertexJointAccessor) p.attributes.joint.push_back(vertexJointAccessor); if ( vertexJointAccessor ) {
p.attributes.joint.push_back( vertexJointAccessor );
}
Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aim->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
if (vertexWeightAccessor) p.attributes.weight.push_back(vertexWeightAccessor); if ( vertexWeightAccessor ) {
p.attributes.weight.push_back( vertexWeightAccessor );
}
delete[] jointsPerVertex;
delete[] vertexWeightData;
delete[] vertexJointData;
} }
void glTFExporter::ExportMeshes() void glTFExporter::ExportMeshes()
@ -865,7 +870,10 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
} }
Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
if (tranAccessor) animRef->Parameters.translation = tranAccessor; if ( tranAccessor ) {
animRef->Parameters.translation = tranAccessor;
}
delete[] translationData;
} }
//------------------------------------------------------- //-------------------------------------------------------
@ -877,7 +885,10 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
} }
Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
if (scaleAccessor) animRef->Parameters.scale = scaleAccessor; if ( scaleAccessor ) {
animRef->Parameters.scale = scaleAccessor;
}
delete[] scaleData;
} }
//------------------------------------------------------- //-------------------------------------------------------
@ -892,7 +903,10 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
} }
Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
if (rotAccessor) animRef->Parameters.rotation = rotAccessor; if ( rotAccessor ) {
animRef->Parameters.rotation = rotAccessor;
}
delete[] rotationData;
} }
} }

View File

@ -46,24 +46,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_METADATA_H_INC #ifndef AI_METADATA_H_INC
#define AI_METADATA_H_INC #define AI_METADATA_H_INC
#include <assert.h>
#if defined(_MSC_VER) && (_MSC_VER <= 1500) #if defined(_MSC_VER) && (_MSC_VER <= 1500)
#include "Compiler/pstdint.h" # include "Compiler/pstdint.h"
#else #else
#include <limits.h> # include <stdint.h>
#include <stdint.h>
#endif #endif
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** /**
* Enum used to distinguish data types * Enum used to distinguish data types
*/ */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
typedef enum aiMetadataType typedef enum aiMetadataType {
{
AI_BOOL = 0, AI_BOOL = 0,
AI_INT32 = 1, AI_INT32 = 1,
AI_UINT64 = 2, AI_UINT64 = 2,
@ -77,8 +71,6 @@ typedef enum aiMetadataType
#endif #endif
} aiMetadataType; } aiMetadataType;
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** /**
* Metadata entry * Metadata entry
@ -86,8 +78,7 @@ typedef enum aiMetadataType
* The type field uniquely identifies the underlying type of the data field * The type field uniquely identifies the underlying type of the data field
*/ */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct aiMetadataEntry struct aiMetadataEntry {
{
aiMetadataType mType; aiMetadataType mType;
void* mData; void* mData;
}; };
@ -119,8 +110,7 @@ inline aiMetadataType GetAiType( aiVector3D ) { return AI_AIVECTOR3D; }
* Metadata is a key-value store using string keys and values. * Metadata is a key-value store using string keys and values.
*/ */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct aiMetadata struct aiMetadata {
{
/** Length of the mKeys and mValues arrays, respectively */ /** Length of the mKeys and mValues arrays, respectively */
unsigned int mNumProperties; unsigned int mNumProperties;
@ -133,28 +123,28 @@ struct aiMetadata
#ifdef __cplusplus #ifdef __cplusplus
/** Constructor */ /**
* @brief The default constructor, set all members to zero by default.
*/
aiMetadata() aiMetadata()
// set all members to zero by default
: mNumProperties(0) : mNumProperties(0)
, mKeys(NULL) , mKeys(NULL)
, mValues(NULL) , mValues(NULL) {
{} // empty
}
/** Destructor */ /**
~aiMetadata() * @brief The destructor.
{ */
delete[] mKeys; ~aiMetadata() {
delete [] mKeys;
mKeys = NULL; mKeys = NULL;
if (mValues) if (mValues) {
{
// Delete each metadata entry // Delete each metadata entry
for (unsigned i=0; i<mNumProperties; ++i) for (unsigned i=0; i<mNumProperties; ++i) {
{
void* data = mValues[i].mData; void* data = mValues[i].mData;
switch (mValues[i].mType) switch (mValues[i].mType) {
{
case AI_BOOL: case AI_BOOL:
delete static_cast<bool*>(data); delete static_cast<bool*>(data);
break; break;
@ -180,7 +170,6 @@ struct aiMetadata
case FORCE_32BIT: case FORCE_32BIT:
#endif #endif
default: default:
assert(false);
break; break;
} }
} }
@ -191,13 +180,36 @@ struct aiMetadata
} }
} }
/**
* @brief Allocates property fields + keys.
* @param numProperties Number of requested properties.
*/
static inline
aiMetadata *Alloc( unsigned int numProperties ) {
if ( 0 == numProperties ) {
return nullptr;
}
aiMetadata *data = new aiMetadata;
data->mNumProperties = numProperties;
data->mKeys = new aiString[ data->mNumProperties ]();
data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
return data;
}
template<typename T> template<typename T>
inline void Set( unsigned index, const std::string& key, const T& value ) inline
{ bool Set( unsigned index, const std::string& key, const T& value ) {
// In range assertion // In range assertion
assert(index < mNumProperties); if ( index >= mNumProperties ) {
return false;
}
// Ensure that we have a valid key.
if ( key.empty() ) {
return false;
}
// Set metadata key // Set metadata key
mKeys[index] = key; mKeys[index] = key;
@ -206,13 +218,17 @@ struct aiMetadata
mValues[index].mType = GetAiType(value); mValues[index].mType = GetAiType(value);
// Copy the given value to the dynamic storage // Copy the given value to the dynamic storage
mValues[index].mData = new T(value); mValues[index].mData = new T(value);
return true;
} }
template<typename T> template<typename T>
inline bool Get( unsigned index, T& value ) inline
{ bool Get( unsigned index, T& value ) {
// In range assertion // In range assertion
assert(index < mNumProperties); if ( index >= mNumProperties ) {
return false;
}
// Return false if the output data type does // Return false if the output data type does
// not match the found value's data type // not match the found value's data type
@ -223,16 +239,19 @@ struct aiMetadata
// Otherwise, output the found value and // Otherwise, output the found value and
// return true // return true
value = *static_cast<T*>(mValues[index].mData); value = *static_cast<T*>(mValues[index].mData);
return true; return true;
} }
template<typename T> template<typename T>
inline bool Get( const aiString& key, T& value ) inline
{ bool Get( const aiString& key, T& value ) {
// Search for the given key // Search for the given key
for (unsigned i=0; i<mNumProperties; ++i) for ( unsigned int i = 0; i < mNumProperties; ++i ) {
if (mKeys[i]==key) if ( mKeys[ i ] == key ) {
return Get(i, value); return Get( i, value );
}
}
return false; return false;
} }
@ -241,18 +260,18 @@ struct aiMetadata
return Get(aiString(key), value); return Get(aiString(key), value);
} }
/// \fn inline bool Get(size_t pIndex, const aiString*& pKey, const aiMetadataEntry*& pEntry)
/// Return metadata entry for analyzing it by user. /// Return metadata entry for analyzing it by user.
/// \param [in] pIndex - index of the entry. /// \param [in] pIndex - index of the entry.
/// \param [out] pKey - pointer to the key value. /// \param [out] pKey - pointer to the key value.
/// \param [out] pEntry - pointer to the entry: type and value. /// \param [out] pEntry - pointer to the entry: type and value.
/// \return false - if pIndex is out of range, else - true. /// \return false - if pIndex is out of range, else - true.
inline bool Get(size_t pIndex, const aiString*& pKey, const aiMetadataEntry*& pEntry) inline bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) {
{ if ( index >= mNumProperties ) {
if(pIndex >= mNumProperties) return false; return false;
}
pKey = &mKeys[pIndex]; key = &mKeys[index];
pEntry = &mValues[pIndex]; entry = &mValues[index];
return true; return true;
} }

View File

@ -109,7 +109,7 @@ extern "C" {
/** Maximum dimension for strings, ASSIMP strings are zero terminated. */ /** Maximum dimension for strings, ASSIMP strings are zero terminated. */
#ifdef __cplusplus #ifdef __cplusplus
const size_t MAXLEN = 1024; static const size_t MAXLEN = 1024;
#else #else
# define MAXLEN 1024 # define MAXLEN 1024
#endif #endif

View File

@ -79,6 +79,7 @@ SET( TEST_SRCS
unit/utMaterialSystem.cpp unit/utMaterialSystem.cpp
unit/utMatrix3x3.cpp unit/utMatrix3x3.cpp
unit/utMatrix4x4.cpp unit/utMatrix4x4.cpp
unit/utMetadata.cpp
unit/SceneDiffer.h unit/SceneDiffer.h
unit/SceneDiffer.cpp unit/SceneDiffer.cpp
unit/utObjImportExport.cpp unit/utObjImportExport.cpp

View File

@ -43,17 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
class utMatrix4x4Test : public ::testing::Test { class utMatrix4x4 : public ::testing::Test {
}; };
TEST_F( utMatrix4x4Test, badIndexOperatorTest ) { TEST_F( utMatrix4x4, badIndexOperatorTest ) {
aiMatrix4x4 m; aiMatrix4x4 m;
ai_real *a0 = m[ 4 ]; ai_real *a0 = m[ 4 ];
EXPECT_EQ( NULL, a0 ); EXPECT_EQ( NULL, a0 );
} }
TEST_F( utMatrix4x4Test, indexOperatorTest ) { TEST_F( utMatrix4x4, indexOperatorTest ) {
aiMatrix4x4 m; aiMatrix4x4 m;
ai_real *a0 = m[ 0 ]; ai_real *a0 = m[ 0 ];
EXPECT_FLOAT_EQ( 1.0, *a0 ); EXPECT_FLOAT_EQ( 1.0, *a0 );

View File

@ -0,0 +1,179 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2016, 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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include <assimp/metadata.h>
using namespace ::Assimp;
class utMetadata: public ::testing::Test {
protected:
aiMetadata *m_data;
virtual void SetUp() {
m_data = nullptr;
}
virtual void TearDown() {
delete m_data;
}
};
TEST_F( utMetadata, creationTest ) {
bool ok( true );
try {
aiMetadata data;
} catch ( ... ) {
ok = false;
}
EXPECT_TRUE( ok );
}
TEST_F( utMetadata, allocTest ) {
aiMetadata *data = aiMetadata::Alloc( 0 );
EXPECT_EQ( nullptr, data );
data = aiMetadata::Alloc( 1 );
EXPECT_NE( nullptr, data );
EXPECT_EQ( 1, data->mNumProperties );
EXPECT_NE( nullptr, data->mKeys );
EXPECT_NE( nullptr, data->mValues );
}
TEST_F( utMetadata, get_set_pod_Test ) {
m_data = aiMetadata::Alloc( 5 );
// int, 32 bit
unsigned int index( 0 );
bool success( false );
const std::string key_int = "test_int";
success = m_data->Set( index, key_int, 1 );
EXPECT_TRUE( success );
success = m_data->Set( index + 10, key_int, 1 );
EXPECT_FALSE( success );
// unsigned int, 64 bit
index++;
const std::string key_uint = "test_uint";
success = m_data->Set<uint64_t>( index, key_uint, 1UL );
EXPECT_TRUE( success );
uint64_t result_uint( 0 );
success = m_data->Get( key_uint, result_uint );
EXPECT_TRUE( success );
EXPECT_EQ( 1UL, result_uint );
// bool
index++;
const std::string key_bool = "test_bool";
success = m_data->Set( index, key_bool, true );
EXPECT_TRUE( success );
bool result_bool( false );
success = m_data->Get( key_bool, result_bool );
EXPECT_TRUE( success );
EXPECT_EQ( true, result_bool );
// float
index++;
const std::string key_float = "test_float";
float fVal = 2.0f;
success = m_data->Set( index, key_float, fVal );
EXPECT_TRUE( success );
float result_float( 0.0f );
success = m_data->Get( key_float, result_float );
EXPECT_TRUE( success );
EXPECT_FLOAT_EQ( 2.0f, result_float );
// double
index++;
const std::string key_double = "test_double";
double dVal = 3.0;
success = m_data->Set( index, key_double, dVal );
EXPECT_TRUE( success );
double result_double( 0.0 );
success = m_data->Get( key_double, result_double );
EXPECT_TRUE( success );
EXPECT_DOUBLE_EQ( 3.0, result_double );
// error
int result;
success = m_data->Get( "bla", result );
EXPECT_FALSE( success );
}
TEST_F( utMetadata, get_set_string_Test ) {
m_data = aiMetadata::Alloc( 1 );
unsigned int index( 0 );
bool success( false );
const std::string key = "test";
success = m_data->Set( index, key, aiString( std::string( "test" ) ) );
EXPECT_TRUE( success );
success = m_data->Set( index+10, key, aiString( std::string( "test" ) ) );
EXPECT_FALSE( success );
aiString result;
success = m_data->Get( key, result );
EXPECT_EQ( aiString( std::string( "test" ) ), result );
EXPECT_TRUE( success );
success = m_data->Get( "bla", result );
EXPECT_FALSE( success );
}
TEST_F( utMetadata, get_set_aiVector3D_Test ) {
m_data = aiMetadata::Alloc( 1 );
unsigned int index( 0 );
bool success( false );
const std::string key = "test";
aiVector3D vec( 1, 2, 3 );
success = m_data->Set( index, key, vec );
EXPECT_TRUE( success );
aiVector3D result( 0, 0, 0 );
success = m_data->Get( key, result );
EXPECT_EQ( vec, result );
EXPECT_TRUE( success );
}

View File

@ -186,4 +186,6 @@ TEST_F( utObjImportExport, obj_import_test ) {
SceneDiffer differ; SceneDiffer differ;
EXPECT_TRUE( differ.isEqual( expected, scene ) ); EXPECT_TRUE( differ.isEqual( expected, scene ) );
differ.showReport(); differ.showReport();
m_im->FreeScene();
} }