123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- Open Asset Import Library (assimp)
- ----------------------------------------------------------------------
- Copyright (c) 2006-2025, 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.
- ----------------------------------------------------------------------
- */
- /** @file BlenderBMesh.cpp
- * @brief Conversion of Blender's new BMesh stuff
- */
- #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
- #include "BlenderBMesh.h"
- #include "BlenderDNA.h"
- #include "BlenderScene.h"
- #include "BlenderTessellator.h"
- namespace Assimp {
- template <>
- const char *LogFunctions<BlenderBMeshConverter>::Prefix() {
- return "BLEND_BMESH: ";
- }
- } // namespace Assimp
- using namespace Assimp;
- using namespace Assimp::Blender;
- using namespace Assimp::Formatter;
- // ------------------------------------------------------------------------------------------------
- BlenderBMeshConverter::BlenderBMeshConverter(const Mesh *mesh) :
- BMesh(mesh),
- triMesh(nullptr) {
- ai_assert(nullptr != mesh);
- }
- // ------------------------------------------------------------------------------------------------
- BlenderBMeshConverter::~BlenderBMeshConverter() {
- DestroyTriMesh();
- }
- // ------------------------------------------------------------------------------------------------
- bool BlenderBMeshConverter::ContainsBMesh() const {
- // TODO - Should probably do some additional verification here
- return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
- }
- // ------------------------------------------------------------------------------------------------
- const Mesh *BlenderBMeshConverter::TriangulateBMesh() {
- AssertValidMesh();
- AssertValidSizes();
- PrepareTriMesh();
- for (int i = 0; i < BMesh->totpoly; ++i) {
- const MPoly &poly = BMesh->mpoly[i];
- ConvertPolyToFaces(poly);
- }
- return triMesh;
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::AssertValidMesh() {
- if (!ContainsBMesh()) {
- ThrowException("BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first");
- }
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::AssertValidSizes() {
- if (BMesh->totpoly != static_cast<int>(BMesh->mpoly.size())) {
- ThrowException("BMesh poly array has incorrect size");
- }
- if (BMesh->totloop != static_cast<int>(BMesh->mloop.size())) {
- ThrowException("BMesh loop array has incorrect size");
- }
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::PrepareTriMesh() {
- if (triMesh) {
- DestroyTriMesh();
- }
- triMesh = new Mesh(*BMesh);
- triMesh->totface = 0;
- triMesh->mface.clear();
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::DestroyTriMesh() {
- delete triMesh;
- triMesh = nullptr;
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::ConvertPolyToFaces(const MPoly &poly) {
- const MLoop *polyLoop = &BMesh->mloop[poly.loopstart];
- if (poly.totloop == 3 || poly.totloop == 4) {
- AddFace(polyLoop[0].v, polyLoop[1].v, polyLoop[2].v, poly.totloop == 4 ? polyLoop[3].v : 0);
- // UVs are optional, so only convert when present.
- if (BMesh->mloopuv.size()) {
- if ((poly.loopstart + poly.totloop) > static_cast<int>(BMesh->mloopuv.size())) {
- ThrowException("BMesh uv loop array has incorrect size");
- }
- const MLoopUV *loopUV = &BMesh->mloopuv[poly.loopstart];
- AddTFace(loopUV[0].uv, loopUV[1].uv, loopUV[2].uv, poly.totloop == 4 ? loopUV[3].uv : nullptr);
- }
- } else if (poly.totloop > 4) {
- #if ASSIMP_BLEND_WITH_GLU_TESSELLATE
- BlenderTessellatorGL tessGL(*this);
- tessGL.Tessellate(polyLoop, poly.totloop, triMesh->mvert);
- #elif ASSIMP_BLEND_WITH_POLY_2_TRI
- BlenderTessellatorP2T tessP2T(*this);
- tessP2T.Tessellate(polyLoop, poly.totloop, triMesh->mvert);
- #endif
- }
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::AddFace(int v1, int v2, int v3, int v4) {
- MFace face;
- face.v1 = v1;
- face.v2 = v2;
- face.v3 = v3;
- face.v4 = v4;
- face.flag = 0;
- // TODO - Work out how materials work
- face.mat_nr = 0;
- triMesh->mface.push_back(face);
- triMesh->totface = static_cast<int>(triMesh->mface.size());
- }
- // ------------------------------------------------------------------------------------------------
- void BlenderBMeshConverter::AddTFace(const float *uv1, const float *uv2, const float *uv3, const float *uv4) {
- MTFace mtface;
- memcpy(&mtface.uv[0], uv1, sizeof(float) * 2);
- memcpy(&mtface.uv[1], uv2, sizeof(float) * 2);
- memcpy(&mtface.uv[2], uv3, sizeof(float) * 2);
- if (uv4) {
- memcpy(&mtface.uv[3], uv4, sizeof(float) * 2);
- }
- triMesh->mtface.push_back(mtface);
- }
- #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|