Warning, /include/assimp/SmoothingGroups.inl is written in an unsupported language. File is not indexed.
0001 /*
0002 ---------------------------------------------------------------------------
0003 Open Asset Import Library (assimp)
0004 ---------------------------------------------------------------------------
0005
0006 Copyright (c) 2006-2024, assimp team
0007
0008 All rights reserved.
0009
0010 Redistribution and use of this software in source and binary forms,
0011 with or without modification, are permitted provided that the following
0012 conditions are met:
0013
0014 * Redistributions of source code must retain the above
0015 copyright notice, this list of conditions and the
0016 following disclaimer.
0017
0018 * Redistributions in binary form must reproduce the above
0019 copyright notice, this list of conditions and the
0020 following disclaimer in the documentation and/or other
0021 materials provided with the distribution.
0022
0023 * Neither the name of the assimp team, nor the names of its
0024 contributors may be used to endorse or promote products
0025 derived from this software without specific prior
0026 written permission of the assimp team.
0027
0028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0029 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0030 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0031 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0032 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0033 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0034 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0035 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0036 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0038 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0039 ---------------------------------------------------------------------------
0040 */
0041
0042 /** @file Generation of normal vectors basing on smoothing groups */
0043
0044 #pragma once
0045 #ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
0046 #define AI_SMOOTHINGGROUPS_INL_INCLUDED
0047
0048 #ifdef __GNUC__
0049 # pragma GCC system_header
0050 #endif
0051
0052 #include <assimp/SGSpatialSort.h>
0053
0054 #include <algorithm>
0055
0056 using namespace Assimp;
0057
0058 // ------------------------------------------------------------------------------------------------
0059 template <class T>
0060 void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
0061 {
0062 // First generate face normals
0063 sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D());
0064 for( unsigned int a = 0; a < sMesh.mFaces.size(); a++)
0065 {
0066 T& face = sMesh.mFaces[a];
0067
0068 aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]];
0069 aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]];
0070 aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]];
0071
0072 aiVector3D pDelta1 = *pV2 - *pV1;
0073 aiVector3D pDelta2 = *pV3 - *pV1;
0074 aiVector3D vNor = pDelta1 ^ pDelta2;
0075
0076 for (unsigned int c = 0; c < 3;++c)
0077 sMesh.mNormals[face.mIndices[c]] = vNor;
0078 }
0079
0080 // calculate the position bounds so we have a reliable epsilon to check position differences against
0081 aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
0082 for( unsigned int a = 0; a < sMesh.mPositions.size(); a++)
0083 {
0084 minVec.x = std::min( minVec.x, sMesh.mPositions[a].x);
0085 minVec.y = std::min( minVec.y, sMesh.mPositions[a].y);
0086 minVec.z = std::min( minVec.z, sMesh.mPositions[a].z);
0087 maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x);
0088 maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y);
0089 maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z);
0090 }
0091 const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
0092 std::vector<aiVector3D> avNormals;
0093 avNormals.resize(sMesh.mNormals.size());
0094
0095 // now generate the spatial sort tree
0096 SGSpatialSort sSort;
0097 for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
0098 i != sMesh.mFaces.end();++i)
0099 {
0100 for (unsigned int c = 0; c < 3;++c)
0101 sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup);
0102 }
0103 sSort.Prepare();
0104
0105 std::vector<bool> vertexDone(sMesh.mPositions.size(),false);
0106 for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
0107 i != sMesh.mFaces.end();++i)
0108 {
0109 std::vector<unsigned int> poResult;
0110 for (unsigned int c = 0; c < 3;++c)
0111 {
0112 unsigned int idx = (*i).mIndices[c];
0113 if (vertexDone[idx])continue;
0114
0115 sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup,
0116 posEpsilon,poResult);
0117
0118 aiVector3D vNormals;
0119 for (std::vector<unsigned int>::const_iterator
0120 a = poResult.begin();
0121 a != poResult.end();++a)
0122 {
0123 vNormals += sMesh.mNormals[(*a)];
0124 }
0125 vNormals.NormalizeSafe();
0126
0127 // write back into all affected normals
0128 for (std::vector<unsigned int>::const_iterator
0129 a = poResult.begin();
0130 a != poResult.end();++a)
0131 {
0132 idx = *a;
0133 avNormals [idx] = vNormals;
0134 vertexDone[idx] = true;
0135 }
0136 }
0137 }
0138 sMesh.mNormals = avNormals;
0139 }
0140
0141 #endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED