GCC Code Coverage Report


Directory: ./
File: src/mesh_loader/assimp.cpp
Date: 2025-04-01 09:23:31
Exec Total Coverage
Lines: 42 48 87.5%
Branches: 27 128 21.1%

Line Branch Exec Source
1 /*
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2019-2021 CNRS - LAAS, INRIA
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Open Source Robotics Foundation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600))
36 #define nullptr NULL
37 #endif
38 #include "coal/mesh_loader/assimp.h"
39
40 // Assimp >= 5.0 is forcing the use of C++11 keywords. A fix has been submitted
41 // https://github.com/assimp/assimp/pull/2758. The next lines fixes the bug for
42 // current version of Coal.
43 #include <assimp/defs.h>
44 #if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) && \
45 defined(AI_NO_EXCEPT)
46 #undef AI_NO_EXCEPT
47 #define AI_NO_EXCEPT
48 #endif
49
50 #include <assimp/DefaultLogger.hpp>
51 #include <assimp/IOStream.hpp>
52 #include <assimp/IOSystem.hpp>
53 #include <assimp/Importer.hpp>
54 #include <assimp/postprocess.h>
55 #include <assimp/scene.h>
56
57 namespace coal {
58
59 namespace internal {
60
61
1/2
✓ Branch 2 taken 159 times.
✗ Branch 3 not taken.
159 Loader::Loader() : importer(new Assimp::Importer()) {
62 // set list of ignored parameters (parameters used for rendering)
63 159 importer->SetPropertyInteger(
64 AI_CONFIG_PP_RVC_FLAGS,
65 aiComponent_TANGENTS_AND_BITANGENTS | aiComponent_COLORS |
66 aiComponent_BONEWEIGHTS | aiComponent_ANIMATIONS |
67 aiComponent_LIGHTS | aiComponent_CAMERAS | aiComponent_TEXTURES |
68 aiComponent_TEXCOORDS | aiComponent_MATERIALS | aiComponent_NORMALS);
69
70 // remove LINES and POINTS
71 159 importer->SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,
72 aiPrimitiveType_LINE | aiPrimitiveType_POINT);
73 159 }
74
75 159 Loader::~Loader() {
76
2/4
✓ Branch 0 taken 159 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
✗ Branch 3 not taken.
159 if (importer) delete importer;
77 159 }
78
79 159 void Loader::load(const std::string& resource_path) {
80 159 scene = importer->ReadFile(
81 resource_path.c_str(),
82 aiProcess_SortByPType | aiProcess_Triangulate |
83 aiProcess_RemoveComponent | aiProcess_ImproveCacheLocality |
84 aiProcess_FindDegenerates | aiProcess_JoinIdenticalVertices);
85
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 159 times.
159 if (!scene) {
87 const std::string exception_message(
88 std::string("Could not load resource ") + resource_path +
89 std::string("\n") + importer->GetErrorString() + std::string("\n") +
90 "Hint: the mesh directory may be wrong.");
91 COAL_THROW_PRETTY(exception_message.c_str(), std::invalid_argument);
92 }
93
94
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
159 if (!scene->HasMeshes())
95 COAL_THROW_PRETTY(
96 (std::string("No meshes found in file ") + resource_path).c_str(),
97 std::invalid_argument);
98 159 }
99
100 /**
101 * @brief Recursive procedure for building a mesh
102 *
103 * @param[in] scale Scale to apply when reading the ressource
104 * @param[in] scene Pointer to the assimp scene
105 * @param[in] node Current node of the scene
106 * @param[in] vertices_offset Current number of vertices in the model
107 * @param tv Triangles and Vertices of the mesh submodels
108 */
109 604 unsigned recurseBuildMesh(const coal::Vec3s& scale, const aiScene* scene,
110 const aiNode* node, unsigned vertices_offset,
111 TriangleAndVertices& tv) {
112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 604 times.
604 if (!node) return 0;
113
114 604 aiMatrix4x4 transform = node->mTransformation;
115 604 aiNode* pnode = node->mParent;
116
2/2
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 604 times.
1049 while (pnode) {
117 // Don't convert to y-up orientation, which is what the root node in
118 // Assimp does
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 445 times.
445 if (pnode->mParent != NULL) {
120 transform = pnode->mTransformation * transform;
121 }
122 445 pnode = pnode->mParent;
123 }
124
125 604 unsigned nbVertices = 0;
126
2/2
✓ Branch 0 taken 433 times.
✓ Branch 1 taken 604 times.
1037 for (uint32_t i = 0; i < node->mNumMeshes; i++) {
127 433 aiMesh* input_mesh = scene->mMeshes[node->mMeshes[i]];
128
129 // Add the vertices
130
2/2
✓ Branch 0 taken 196351 times.
✓ Branch 1 taken 433 times.
196784 for (uint32_t j = 0; j < input_mesh->mNumVertices; j++) {
131 196351 aiVector3D p = input_mesh->mVertices[j];
132
1/2
✓ Branch 1 taken 196351 times.
✗ Branch 2 not taken.
196351 p *= transform;
133
1/2
✓ Branch 1 taken 196351 times.
✗ Branch 2 not taken.
196351 tv.vertices_.push_back(
134
4/8
✓ Branch 1 taken 196351 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 196351 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 196351 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 196351 times.
✗ Branch 11 not taken.
392702 coal::Vec3s(p.x * scale[0], p.y * scale[1], p.z * scale[2]));
135 }
136
137 // add the indices
138
2/2
✓ Branch 0 taken 220047 times.
✓ Branch 1 taken 433 times.
220480 for (uint32_t j = 0; j < input_mesh->mNumFaces; j++) {
139 220047 aiFace& face = input_mesh->mFaces[j];
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 220047 times.
220047 assert(face.mNumIndices == 3 && "The size of the face is not valid.");
141
1/2
✓ Branch 1 taken 220047 times.
✗ Branch 2 not taken.
220047 tv.triangles_.push_back(
142 220047 coal::Triangle(vertices_offset + face.mIndices[0],
143 220047 vertices_offset + face.mIndices[1],
144
1/2
✓ Branch 1 taken 220047 times.
✗ Branch 2 not taken.
220047 vertices_offset + face.mIndices[2]));
145 }
146
147 433 nbVertices += input_mesh->mNumVertices;
148 }
149
150
2/2
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 604 times.
1049 for (uint32_t i = 0; i < node->mNumChildren; ++i) {
151 445 nbVertices +=
152
1/2
✓ Branch 1 taken 445 times.
✗ Branch 2 not taken.
445 recurseBuildMesh(scale, scene, node->mChildren[i], nbVertices, tv);
153 }
154
155 604 return nbVertices;
156 }
157
158 159 void buildMesh(const coal::Vec3s& scale, const aiScene* scene,
159 unsigned vertices_offset, TriangleAndVertices& tv) {
160 159 recurseBuildMesh(scale, scene, scene->mRootNode, vertices_offset, tv);
161 159 }
162
163 } // namespace internal
164 } // namespace coal
165