vrshoot

diff libs/assimp/FindDegenerates.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/assimp/FindDegenerates.cpp	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,216 @@
     1.4 +/*
     1.5 +---------------------------------------------------------------------------
     1.6 +Open Asset Import Library (assimp)
     1.7 +---------------------------------------------------------------------------
     1.8 +
     1.9 +Copyright (c) 2006-2012, assimp team
    1.10 +
    1.11 +All rights reserved.
    1.12 +
    1.13 +Redistribution and use of this software in source and binary forms, 
    1.14 +with or without modification, are permitted provided that the following 
    1.15 +conditions are met:
    1.16 +
    1.17 +* Redistributions of source code must retain the above
    1.18 +  copyright notice, this list of conditions and the
    1.19 +  following disclaimer.
    1.20 +
    1.21 +* Redistributions in binary form must reproduce the above
    1.22 +  copyright notice, this list of conditions and the
    1.23 +  following disclaimer in the documentation and/or other
    1.24 +  materials provided with the distribution.
    1.25 +
    1.26 +* Neither the name of the assimp team, nor the names of its
    1.27 +  contributors may be used to endorse or promote products
    1.28 +  derived from this software without specific prior
    1.29 +  written permission of the assimp team.
    1.30 +
    1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
    1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.42 +---------------------------------------------------------------------------
    1.43 +*/
    1.44 +
    1.45 +/** @file  FindDegenerates.cpp
    1.46 + *  @brief Implementation of the FindDegenerates post-process step.
    1.47 +*/
    1.48 +
    1.49 +#include "AssimpPCH.h"
    1.50 +
    1.51 +// internal headers
    1.52 +#include "ProcessHelper.h"
    1.53 +#include "FindDegenerates.h"
    1.54 +
    1.55 +using namespace Assimp;
    1.56 +
    1.57 +// ------------------------------------------------------------------------------------------------
    1.58 +// Constructor to be privately used by Importer
    1.59 +FindDegeneratesProcess::FindDegeneratesProcess()
    1.60 +: configRemoveDegenerates (false)
    1.61 +{}
    1.62 +
    1.63 +// ------------------------------------------------------------------------------------------------
    1.64 +// Destructor, private as well
    1.65 +FindDegeneratesProcess::~FindDegeneratesProcess()
    1.66 +{
    1.67 +	// nothing to do here
    1.68 +}
    1.69 +
    1.70 +// ------------------------------------------------------------------------------------------------
    1.71 +// Returns whether the processing step is present in the given flag field.
    1.72 +bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
    1.73 +{
    1.74 +	return 0 != (pFlags & aiProcess_FindDegenerates);
    1.75 +}
    1.76 +
    1.77 +// ------------------------------------------------------------------------------------------------
    1.78 +// Setup import configuration
    1.79 +void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
    1.80 +{
    1.81 +	// Get the current value of AI_CONFIG_PP_FD_REMOVE
    1.82 +	configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
    1.83 +}
    1.84 +
    1.85 +// ------------------------------------------------------------------------------------------------
    1.86 +// Executes the post processing step on the given imported data.
    1.87 +void FindDegeneratesProcess::Execute( aiScene* pScene)
    1.88 +{
    1.89 +	DefaultLogger::get()->debug("FindDegeneratesProcess begin");
    1.90 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
    1.91 +		ExecuteOnMesh( pScene->mMeshes[i]);
    1.92 +	}
    1.93 +	DefaultLogger::get()->debug("FindDegeneratesProcess finished");
    1.94 +}
    1.95 +
    1.96 +// ------------------------------------------------------------------------------------------------
    1.97 +// Executes the post processing step on the given imported mesh
    1.98 +void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
    1.99 +{
   1.100 +	mesh->mPrimitiveTypes = 0;
   1.101 +
   1.102 +	std::vector<bool> remove_me; 
   1.103 +	if (configRemoveDegenerates)
   1.104 +		remove_me.resize(mesh->mNumFaces,false);
   1.105 +
   1.106 +	unsigned int deg = 0, limit;
   1.107 +	for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
   1.108 +	{
   1.109 +		aiFace& face = mesh->mFaces[a];
   1.110 +		bool first = true;
   1.111 +
   1.112 +		// check whether the face contains degenerated entries
   1.113 +		for (register unsigned int i = 0; i < face.mNumIndices; ++i)
   1.114 +		{
   1.115 +			// Polygons with more than 4 points are allowed to have double points, that is
   1.116 +			// simulating polygons with holes just with concave polygons. However,
   1.117 +			// double points may not come directly after another.
   1.118 +			limit = face.mNumIndices;
   1.119 +			if (face.mNumIndices > 4)
   1.120 +				limit = std::min(limit,i+2);
   1.121 +
   1.122 +			for (register unsigned int t = i+1; t < limit; ++t)
   1.123 +			{
   1.124 +				if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
   1.125 +				{
   1.126 +					// we have found a matching vertex position
   1.127 +					// remove the corresponding index from the array
   1.128 +					--face.mNumIndices;--limit;
   1.129 +					for (unsigned int m = t; m < face.mNumIndices; ++m)
   1.130 +					{
   1.131 +						face.mIndices[m] = face.mIndices[m+1];
   1.132 +					}
   1.133 +					--t; 
   1.134 +
   1.135 +					// NOTE: we set the removed vertex index to an unique value
   1.136 +					// to make sure the developer gets notified when his
   1.137 +					// application attemps to access this data.
   1.138 +					face.mIndices[face.mNumIndices] = 0xdeadbeef;
   1.139 +
   1.140 +					if(first)
   1.141 +					{
   1.142 +						++deg;
   1.143 +						first = false;
   1.144 +					}
   1.145 +
   1.146 +					if (configRemoveDegenerates) {
   1.147 +						remove_me[a] = true;
   1.148 +						goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
   1.149 +					}
   1.150 +				}
   1.151 +			}
   1.152 +		}
   1.153 +
   1.154 +		// We need to update the primitive flags array of the mesh.
   1.155 +		switch (face.mNumIndices)
   1.156 +		{
   1.157 +		case 1u:
   1.158 +			mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
   1.159 +			break;
   1.160 +		case 2u:
   1.161 +			mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
   1.162 +			break;
   1.163 +		case 3u:
   1.164 +			mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
   1.165 +			break;
   1.166 +		default:
   1.167 +			mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
   1.168 +			break;
   1.169 +		};
   1.170 +evil_jump_outside:
   1.171 +		continue;
   1.172 +	}
   1.173 +
   1.174 +	// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
   1.175 +	if (configRemoveDegenerates && deg) {
   1.176 +		unsigned int n = 0;
   1.177 +		for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
   1.178 +		{
   1.179 +			aiFace& face_src = mesh->mFaces[a];
   1.180 +			if (!remove_me[a]) {
   1.181 +				aiFace& face_dest = mesh->mFaces[n++];
   1.182 +
   1.183 +				// Do a manual copy, keep the index array
   1.184 +				face_dest.mNumIndices = face_src.mNumIndices;
   1.185 +				face_dest.mIndices    = face_src.mIndices;
   1.186 +
   1.187 +				if (&face_src != &face_dest) {
   1.188 +					// clear source
   1.189 +					face_src.mNumIndices = 0;
   1.190 +					face_src.mIndices = NULL;
   1.191 +				}
   1.192 +			}
   1.193 +			else {
   1.194 +				// Otherwise delete it if we don't need this face
   1.195 +				delete[] face_src.mIndices;
   1.196 +				face_src.mIndices = NULL;
   1.197 +				face_src.mNumIndices = 0;
   1.198 +			}
   1.199 +		}
   1.200 +		// Just leave the rest of the array unreferenced, we don't care for now
   1.201 +		mesh->mNumFaces = n;
   1.202 +		if (!mesh->mNumFaces) {
   1.203 +			// WTF!? 
   1.204 +			// OK ... for completeness and because I'm not yet tired,
   1.205 +			// let's write code that willl hopefully never be called
   1.206 +			// (famous last words)
   1.207 +
   1.208 +			// OK ... bad idea.
   1.209 +			throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
   1.210 +		}
   1.211 +	}
   1.212 +
   1.213 +	if (deg && !DefaultLogger::isNullLogger())
   1.214 +	{
   1.215 +		char s[64];
   1.216 +		ASSIMP_itoa10(s,deg); 
   1.217 +		DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
   1.218 +	}
   1.219 +}