closes https://github.com/assimp/assimp/issues/2054: make empty bone validation optional.

pull/2446/head
Kim Kulling 2019-05-05 13:39:10 +02:00
parent 0b9c72fa94
commit fcff12b219
8 changed files with 52 additions and 50 deletions

View File

@ -1299,7 +1299,7 @@ void ASEImporter::BuildMaterialIndices()
} }
} }
// Dekete our temporary array // Delete our temporary array
delete[] pcIntMaterials; delete[] pcIntMaterials;
} }

View File

@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the ASE parser class * @brief Implementation of the ASE parser class
*/ */
#pragma once
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -190,8 +190,9 @@ struct Animation {
Animation() AI_NO_EXCEPT Animation() AI_NO_EXCEPT
: mRotationType (TRACK) : mRotationType (TRACK)
, mScalingType (TRACK) , mScalingType (TRACK)
, mPositionType (TRACK) , mPositionType (TRACK) {
{} // empty
}
//! List of track rotation keyframes //! List of track rotation keyframes
std::vector< aiQuatKey > akeyRotations; std::vector< aiQuatKey > akeyRotations;
@ -243,7 +244,6 @@ struct BaseNode {
mTargetPosition.x = qnan; mTargetPosition.x = qnan;
} }
//! Name of the mesh //! Name of the mesh
std::string mName; std::string mName;

View File

@ -76,7 +76,7 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
FBXConverter::FBXConverter(aiScene* out, const Document& doc) FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones)
: defaultMaterialIndex() : defaultMaterialIndex()
, lights() , lights()
, cameras() , cameras()
@ -89,7 +89,8 @@ namespace Assimp {
, mNodeNames() , mNodeNames()
, anim_fps() , anim_fps()
, out(out) , out(out)
, doc(doc) { , doc(doc)
, mRemoveEmptyBones( removeEmptyBones ) {
// animations need to be converted first since this will // animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed // populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated. // to determine which nodes need to be generated.
@ -1407,9 +1408,9 @@ namespace Assimp {
const WeightIndexArray& indices = cluster->GetIndices(); const WeightIndexArray& indices = cluster->GetIndices();
if (indices.empty()) { /*if (indices.empty()) {
continue; continue;
} }*/
const MatIndexArray& mats = geo.GetMaterialIndices(); const MatIndexArray& mats = geo.GetMaterialIndices();
@ -1439,13 +1440,11 @@ namespace Assimp {
if (index_out_indices.back() == no_index_sentinel) { if (index_out_indices.back() == no_index_sentinel) {
index_out_indices.back() = out_indices.size(); index_out_indices.back() = out_indices.size();
} }
if (no_mat_check) { if (no_mat_check) {
out_indices.push_back(out_idx[i]); out_indices.push_back(out_idx[i]);
} } else {
else {
// this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn) // this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn)
const std::vector<unsigned int>::iterator it = std::lower_bound( const std::vector<unsigned int>::iterator it = std::lower_bound(
outputVertStartIndices->begin(), outputVertStartIndices->begin(),
@ -1465,10 +1464,10 @@ namespace Assimp {
// if we found at least one, generate the output bones // if we found at least one, generate the output bones
// XXX this could be heavily simplified by collecting the bone // XXX this could be heavily simplified by collecting the bone
// data in a single step. // data in a single step.
if (ok) { //if (ok) {
ConvertCluster(bones, model, *cluster, out_indices, index_out_indices, ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
count_out_indices, node_global_transform); count_out_indices, node_global_transform);
} //}
} }
} }
catch (std::exception&) { catch (std::exception&) {
@ -3525,9 +3524,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc) void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{ {
FBXConverter converter(out, doc); FBXConverter converter(out, doc, removeEmptyBones);
} }
} // !FBX } // !FBX

View File

@ -112,7 +112,7 @@ public:
}; };
public: public:
FBXConverter(aiScene* out, const Document& doc); FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones );
~FBXConverter(); ~FBXConverter();
private: private:
@ -453,6 +453,8 @@ private:
aiScene* const out; aiScene* const out;
const FBX::Document& doc; const FBX::Document& doc;
bool mRemoveEmptyBones;
}; };
} }

View File

@ -65,7 +65,9 @@ struct ImportSettings
, preservePivots(true) , preservePivots(true)
, optimizeEmptyAnimationCurves(true) , optimizeEmptyAnimationCurves(true)
, useLegacyEmbeddedTextureNaming(false) , useLegacyEmbeddedTextureNaming(false)
{} , removeEmptyBones( true ) {
// empty
}
/** enable strict mode: /** enable strict mode:
@ -141,8 +143,12 @@ struct ImportSettings
bool optimizeEmptyAnimationCurves; bool optimizeEmptyAnimationCurves;
/** use legacy naming for embedded textures eg: (*0, *1, *2) /** use legacy naming for embedded textures eg: (*0, *1, *2)
**/ */
bool useLegacyEmbeddedTextureNaming; bool useLegacyEmbeddedTextureNaming;
/** Empty bones shall be removed
*/
bool removeEmptyBones;
}; };

View File

@ -140,6 +140,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false); settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -184,7 +185,7 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
Document doc(parser,settings); Document doc(parser,settings);
// convert the FBX DOM to aiScene // convert the FBX DOM to aiScene
ConvertToAssimpScene(pScene,doc); ConvertToAssimpScene(pScene,doc, settings.removeEmptyBones);
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>()); std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
} }

View File

@ -46,8 +46,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* the data structure returned by Assimp. * the data structure returned by Assimp.
*/ */
// internal headers // internal headers
#include "ValidateDataStructure.h" #include "ValidateDataStructure.h"
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
@ -110,8 +108,8 @@ void ValidateDSProcess::ReportWarning(const char* msg,...)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline int HasNameMatch(const aiString& in, aiNode* node) inline
{ int HasNameMatch(const aiString& in, aiNode* node) {
int result = (node->mName == in ? 1 : 0 ); int result = (node->mName == in ? 1 : 0 );
for (unsigned int i = 0; i < node->mNumChildren;++i) { for (unsigned int i = 0; i < node->mNumChildren;++i) {
result += HasNameMatch(in,node->mChildren[i]); result += HasNameMatch(in,node->mChildren[i]);
@ -121,9 +119,8 @@ inline int HasNameMatch(const aiString& in, aiNode* node)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size, inline
const char* firstName, const char* secondName) void ValidateDSProcess::DoValidation(T** parray, unsigned int size, const char* firstName, const char* secondName) {
{
// validate all entries // validate all entries
if (size) if (size)
{ {
@ -516,13 +513,12 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiMesh* pMesh, void ValidateDSProcess::Validate( const aiMesh* pMesh, const aiBone* pBone,float* afSum) {
const aiBone* pBone,float* afSum)
{
this->Validate(&pBone->mName); this->Validate(&pBone->mName);
if (!pBone->mNumWeights) { if (!pBone->mNumWeights) {
ReportError("aiBone::mNumWeights is zero"); // ReportError("aiBone::mNumWeights is zero");
} }
// check whether all vertices affected by this bone are valid // check whether all vertices affected by this bone are valid
@ -563,9 +559,6 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
else { else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there."); ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
} }
// Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
// if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -746,8 +739,9 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
"AI_MATKEY_SHININESS_STRENGTH key is 0.0"); "AI_MATKEY_SHININESS_STRENGTH key is 0.0");
} }
break; break;
default: ; default:
}; break;
}
} }
if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) { if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) {