Skip to content

Commit

Permalink
Merge pull request #4895 from assimp/kimkulling/make_remove_empty_bon…
Browse files Browse the repository at this point in the history
…es_optional_issue-4840

Update LimitBoneWeightsProcess.cpp
  • Loading branch information
kimkulling committed Jan 20, 2023
2 parents 67eae8e + 81cf136 commit 288d49b
Showing 1 changed file with 38 additions and 50 deletions.
88 changes: 38 additions & 50 deletions code/PostProcessing/LimitBoneWeightsProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2023, assimp team
All rights reserved.
Expand Down Expand Up @@ -36,13 +35,7 @@ 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.
----------------------------------------------------------------------
*/

/** Implementation of the LimitBoneWeightsProcess post processing step */


---------------------------------------------------------------------- */
#include "LimitBoneWeightsProcess.h"
#include <assimp/SmallVector.h>
#include <assimp/StringUtils.h>
Expand All @@ -51,30 +44,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <stdio.h>

using namespace Assimp;
namespace Assimp {

// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
LimitBoneWeightsProcess::LimitBoneWeightsProcess()
{
mMaxWeights = AI_LMW_MAX_WEIGHTS;
}
LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {}

// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LimitBoneWeightsProcess::~LimitBoneWeightsProcess() = default;

// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const
{
bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_LimitBoneWeights) != 0;
}

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void LimitBoneWeightsProcess::Execute( aiScene* pScene)
{
void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
ai_assert(pScene != nullptr);

ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");

for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
Expand All @@ -86,16 +76,30 @@ void LimitBoneWeightsProcess::Execute( aiScene* pScene)

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp)
{
// get the current value of the property
void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) {
this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
}

// ------------------------------------------------------------------------------------------------
static unsigned int removeEmptyBones(aiMesh *pMesh) {
ai_assert(pMesh != nullptr);

unsigned int writeBone = 0;
for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone) {
aiBone* bone = pMesh->mBones[readBone];
if (bone->mNumWeights > 0) {
pMesh->mBones[writeBone++] = bone;
} else {
delete bone;
}
}

return writeBone;
}

// ------------------------------------------------------------------------------------------------
// Unites identical vertices in the given mesh
void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
{
void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) {
if (!pMesh->HasBones())
return;

Expand All @@ -105,11 +109,9 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
WeightsPerVertex vertexWeights(pMesh->mNumVertices);
size_t maxVertexWeights = 0;

for (unsigned int b = 0; b < pMesh->mNumBones; ++b)
{
for (unsigned int b = 0; b < pMesh->mNumBones; ++b) {
const aiBone* bone = pMesh->mBones[b];
for (unsigned int w = 0; w < bone->mNumWeights; ++w)
{
for (unsigned int w = 0; w < bone->mNumWeights; ++w) {
const aiVertexWeight& vw = bone->mWeights[w];

if (vertexWeights.size() <= vw.mVertexId)
Expand All @@ -126,8 +128,7 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
unsigned int removed = 0, old_bones = pMesh->mNumBones;

// now cut the weight count if it exceeds the maximum
for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
{
for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit) {
if (vit->size() <= mMaxWeights)
continue;

Expand All @@ -154,40 +155,27 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
}

// clear weight count for all bone
for (unsigned int a = 0; a < pMesh->mNumBones; ++a)
{
for (unsigned int a = 0; a < pMesh->mNumBones; ++a) {
pMesh->mBones[a]->mNumWeights = 0;
}

// rebuild the vertex weight array for all bones
for (unsigned int a = 0; a < vertexWeights.size(); ++a)
{
for (unsigned int a = 0; a < vertexWeights.size(); ++a) {
const VertexWeightArray& vw = vertexWeights[a];
for (const Weight* it = vw.begin(); it != vw.end(); ++it)
{
for (const Weight* it = vw.begin(); it != vw.end(); ++it) {
aiBone* bone = pMesh->mBones[it->mBone];
bone->mWeights[bone->mNumWeights++] = aiVertexWeight(a, it->mWeight);
}
}

// remove empty bones
unsigned int writeBone = 0;

for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone)
{
aiBone* bone = pMesh->mBones[readBone];
if (bone->mNumWeights > 0)
{
pMesh->mBones[writeBone++] = bone;
}
else
{
delete bone;
}
}
pMesh->mNumBones = writeBone;
#ifdef AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES
pMesh->mNumBones = removeEmptyBones(pMesh);
#endif // AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES

if (!DefaultLogger::isNullLogger()) {
ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
}
}

} // namespace Assimp

0 comments on commit 288d49b

Please sign in to comment.