Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-13 08:40:10

0001 /*
0002 Open Asset Import Library (assimp)
0003 ----------------------------------------------------------------------
0004 
0005 Copyright (c) 2006-2025, assimp team
0006 
0007 All rights reserved.
0008 
0009 Redistribution and use of this software in source and binary forms,
0010 with or without modification, are permitted provided that the
0011 following conditions are met:
0012 
0013 * Redistributions of source code must retain the above
0014   copyright notice, this list of conditions and the
0015   following disclaimer.
0016 
0017 * Redistributions in binary form must reproduce the above
0018   copyright notice, this list of conditions and the
0019   following disclaimer in the documentation and/or other
0020   materials provided with the distribution.
0021 
0022 * Neither the name of the assimp team, nor the names of its
0023   contributors may be used to endorse or promote products
0024   derived from this software without specific prior
0025   written permission of the assimp team.
0026 
0027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0028 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0029 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0030 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0031 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0032 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0033 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0034 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0035 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0037 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0038 
0039 ----------------------------------------------------------------------
0040 */
0041 
0042 /** @file Declares a helper class, "SceneCombiner" providing various
0043  *  utilities to merge scenes.
0044  */
0045 #pragma once
0046 #ifndef AI_SCENE_COMBINER_H_INC
0047 #define AI_SCENE_COMBINER_H_INC
0048 
0049 #ifdef __GNUC__
0050 #pragma GCC system_header
0051 #endif
0052 
0053 #include <assimp/ai_assert.h>
0054 #include <assimp/types.h>
0055 
0056 #include <cstddef>
0057 #include <cstdint>
0058 #include <list>
0059 #include <set>
0060 #include <vector>
0061 
0062 struct aiScene;
0063 struct aiNode;
0064 struct aiMaterial;
0065 struct aiTexture;
0066 struct aiCamera;
0067 struct aiLight;
0068 struct aiMetadata;
0069 struct aiBone;
0070 struct aiMesh;
0071 struct aiAnimMesh;
0072 struct aiAnimation;
0073 struct aiNodeAnim;
0074 struct aiMeshMorphAnim;
0075 
0076 namespace Assimp {
0077 
0078 // ---------------------------------------------------------------------------
0079 /** \brief Helper data structure for SceneCombiner.
0080  *
0081  *  Describes to which node a scene must be attached to.
0082  */
0083 struct AttachmentInfo {
0084     AttachmentInfo() :
0085             scene(nullptr),
0086             attachToNode(nullptr) {}
0087 
0088     AttachmentInfo(aiScene *_scene, aiNode *_attachToNode) :
0089             scene(_scene), attachToNode(_attachToNode) {}
0090 
0091     aiScene *scene;
0092     aiNode *attachToNode;
0093 };
0094 
0095 // ---------------------------------------------------------------------------
0096 struct NodeAttachmentInfo {
0097     NodeAttachmentInfo() :
0098             node(nullptr),
0099             attachToNode(nullptr),
0100             resolved(false),
0101             src_idx(SIZE_MAX) {}
0102 
0103     NodeAttachmentInfo(aiNode *_scene, aiNode *_attachToNode, size_t idx) :
0104             node(_scene), attachToNode(_attachToNode), resolved(false), src_idx(idx) {}
0105 
0106     aiNode *node;
0107     aiNode *attachToNode;
0108     bool resolved;
0109     size_t src_idx;
0110 };
0111 
0112 // ---------------------------------------------------------------------------
0113 /** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES
0114  *  Generate unique names for all named scene items
0115  */
0116 #define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1
0117 
0118 /** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES
0119  *  Generate unique names for materials, too.
0120  *  This is not absolutely required to pass the validation.
0121  */
0122 #define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2
0123 
0124 /** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY
0125  * Use deep copies of duplicate scenes
0126  */
0127 #define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4
0128 
0129 /** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS
0130  * If attachment nodes are not found in the given master scene,
0131  * search the other imported scenes for them in an any order.
0132  */
0133 #define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8
0134 
0135 /** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY
0136  * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES.
0137  * Unique names are generated, but only if this is absolutely
0138  * required to avoid name conflicts.
0139  */
0140 #define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
0141 
0142 typedef std::pair<aiBone *, unsigned int> BoneSrcIndex;
0143 
0144 // ---------------------------------------------------------------------------
0145 /** @brief Helper data structure for SceneCombiner::MergeBones.
0146  */
0147 struct BoneWithHash : public std::pair<uint32_t, aiString *> {
0148     std::vector<BoneSrcIndex> pSrcBones;
0149 };
0150 
0151 // ---------------------------------------------------------------------------
0152 /** @brief Utility for SceneCombiner
0153  */
0154 struct SceneHelper {
0155     SceneHelper() :
0156             scene(nullptr),
0157             idlen(0) {
0158         id[0] = 0;
0159     }
0160 
0161     explicit SceneHelper(aiScene *_scene) :
0162             scene(_scene), idlen(0) {
0163         id[0] = 0;
0164     }
0165 
0166     AI_FORCE_INLINE aiScene *operator->() const {
0167         return scene;
0168     }
0169 
0170     // scene we're working on
0171     aiScene *scene;
0172 
0173     // prefix to be added to all identifiers in the scene ...
0174     char id[32];
0175 
0176     // and its strlen()
0177     unsigned int idlen;
0178 
0179     // hash table to quickly check whether a name is contained in the scene
0180     std::set<unsigned int> hashes;
0181 };
0182 
0183 // ---------------------------------------------------------------------------
0184 /** \brief Static helper class providing various utilities to merge two
0185  *    scenes. It is intended as internal utility and NOT for use by
0186  *    applications.
0187  *
0188  * The class is currently being used by various postprocessing steps
0189  * and loaders (ie. LWS).
0190  */
0191 class ASSIMP_API SceneCombiner {
0192 public:
0193     // class cannot be instanced
0194     SceneCombiner() = delete;
0195     ~SceneCombiner() = delete;
0196 
0197     // -------------------------------------------------------------------
0198     /** Merges two or more scenes.
0199      *
0200      *  @param dest  Receives a pointer to the destination scene. If the
0201      *    pointer doesn't point to nullptr when the function is called, the
0202      *    existing scene is cleared and refilled.
0203      *  @param src Non-empty list of scenes to be merged. The function
0204      *    deletes the input scenes afterwards. There may be duplicate scenes.
0205      *  @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
0206      */
0207     static void MergeScenes(aiScene **dest, std::vector<aiScene *> &src,
0208             unsigned int flags = 0);
0209 
0210     // -------------------------------------------------------------------
0211     /** Merges two or more scenes and attaches all scenes to a specific
0212      *  position in the node graph of the master scene.
0213      *
0214      *  @param dest Receives a pointer to the destination scene. If the
0215      *    pointer doesn't point to nullptr when the function is called, the
0216      *    existing scene is cleared and refilled.
0217      *  @param master Master scene. It will be deleted afterwards. All
0218      *    other scenes will be inserted in its node graph.
0219      *  @param src Non-empty list of scenes to be merged along with their
0220      *    corresponding attachment points in the master scene. The function
0221      *    deletes the input scenes afterwards. There may be duplicate scenes.
0222      *  @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
0223      */
0224     static void MergeScenes(aiScene **dest, aiScene *master,
0225             std::vector<AttachmentInfo> &src,
0226             unsigned int flags = 0);
0227 
0228     // -------------------------------------------------------------------
0229     /** Merges two or more meshes
0230      *
0231      *  The meshes should have equal vertex formats. Only components
0232      *  that are provided by ALL meshes will be present in the output mesh.
0233      *  An exception is made for VColors - they are set to black. The
0234      *  meshes should have the same material indices, too. The output
0235      *  material index is always the material index of the first mesh.
0236      *
0237      *  @param dest Destination mesh. Must be empty.
0238      *  @param flags Currently no parameters
0239      *  @param begin First mesh to be processed
0240      *  @param end Points to the mesh after the last mesh to be processed
0241      */
0242     static void MergeMeshes(aiMesh **dest, unsigned int flags,
0243             std::vector<aiMesh *>::const_iterator begin,
0244             std::vector<aiMesh *>::const_iterator end);
0245 
0246     // -------------------------------------------------------------------
0247     /** Merges two or more bones
0248      *
0249      *  @param out Mesh to receive the output bone list
0250      *  @param flags Currently no parameters
0251      *  @param begin First mesh to be processed
0252      *  @param end Points to the mesh after the last mesh to be processed
0253      */
0254     static void MergeBones(aiMesh *out, std::vector<aiMesh *>::const_iterator it,
0255             std::vector<aiMesh *>::const_iterator end);
0256 
0257     // -------------------------------------------------------------------
0258     /** Merges two or more materials
0259      *
0260      *  The materials should be complementary as much as possible. In case
0261      *  of a property present in different materials, the first occurrence
0262      *  is used.
0263      *
0264      *  @param dest Destination material. Must be empty.
0265      *  @param begin First material to be processed
0266      *  @param end Points to the material after the last material to be processed
0267      */
0268     static void MergeMaterials(aiMaterial **dest,
0269             std::vector<aiMaterial *>::const_iterator begin,
0270             std::vector<aiMaterial *>::const_iterator end);
0271 
0272     // -------------------------------------------------------------------
0273     /** Builds a list of uniquely named bones in a mesh list
0274      *
0275      *  @param asBones Receives the output list
0276      *  @param it      First mesh to be processed
0277      *  @param end     Last mesh to be processed
0278      */
0279     static void BuildUniqueBoneList(std::list<BoneWithHash> &asBones,
0280             std::vector<aiMesh *>::const_iterator it,
0281             std::vector<aiMesh *>::const_iterator end);
0282 
0283     // -------------------------------------------------------------------
0284     /** Add a name prefix to all nodes in a scene.
0285      *
0286      *  @param node   Current node. This function is called recursively.
0287      *  @param prefix Prefix to be added to all nodes
0288      *  @param len    String length
0289      */
0290     static void AddNodePrefixes(aiNode *node, const char *prefix,
0291             unsigned int len);
0292 
0293     // -------------------------------------------------------------------
0294     /** Add an offset to all mesh indices in a node graph
0295      *
0296      *  @param node   Current node. This function is called recursively.
0297      *  @param offset Offset to be added to all mesh indices
0298      */
0299     static void OffsetNodeMeshIndices(aiNode *node, unsigned int offset);
0300 
0301     // -------------------------------------------------------------------
0302     /** Attach a list of node graphs to well-defined nodes in a master
0303      *  graph. This is a helper for MergeScenes()
0304      *
0305      *  @param master Master scene
0306      *  @param srcList List of source scenes along with their attachment
0307      *    points. If an attachment point is nullptr (or does not exist in
0308      *    the master graph), a scene is attached to the root of the master
0309      *    graph (as an additional child node)
0310      *  @duplicates List of duplicates. If elem[n] == n the scene is not
0311      *    a duplicate. Otherwise, elem[n] links scene n to its first occurrence.
0312      */
0313     static void AttachToGraph(aiScene *master,
0314             std::vector<NodeAttachmentInfo> &srcList);
0315 
0316     static void AttachToGraph(aiNode *attach,
0317             std::vector<NodeAttachmentInfo> &srcList);
0318 
0319     // -------------------------------------------------------------------
0320     /** Get a deep copy of a scene
0321      *
0322      *  @param dest     Receives a pointer to the destination scene
0323      *  @param source   Source scene - remains unmodified.
0324      *  @param allocate true for allocation a new scene
0325      */
0326     static void CopyScene(aiScene **dest, const aiScene *source, bool allocate = true);
0327 
0328     // -------------------------------------------------------------------
0329     /** Get a flat copy of a scene
0330      *
0331      *  Only the first hierarchy layer is copied. All pointer members of
0332      *  aiScene are shared by source and destination scene.  If the
0333      *    pointer doesn't point to nullptr when the function is called, the
0334      *    existing scene is cleared and refilled.
0335      *  @param dest Receives a pointer to the destination scene
0336      *  @param src Source scene - remains unmodified.
0337      */
0338     static void CopySceneFlat(aiScene **dest, const aiScene *source);
0339 
0340     // -------------------------------------------------------------------
0341     /** Get a deep copy of a mesh
0342      *
0343      *  @param dest Receives a pointer to the destination mesh
0344      *  @param src Source mesh - remains unmodified.
0345      */
0346     static void Copy(aiMesh **dest, const aiMesh *src);
0347 
0348     // similar to Copy():
0349     static void Copy(aiAnimMesh **dest, const aiAnimMesh *src);
0350     static void Copy(aiMaterial **dest, const aiMaterial *src);
0351     static void Copy(aiTexture **dest, const aiTexture *src);
0352     static void Copy(aiAnimation **dest, const aiAnimation *src);
0353     static void Copy(aiCamera **dest, const aiCamera *src);
0354     static void Copy(aiBone **dest, const aiBone *src);
0355     static void Copy(aiLight **dest, const aiLight *src);
0356     static void Copy(aiNodeAnim **dest, const aiNodeAnim *src);
0357     static void Copy(aiMeshMorphAnim **dest, const aiMeshMorphAnim *src);
0358     static void Copy(aiMetadata **dest, const aiMetadata *src);
0359     static void Copy(aiString **dest, const aiString *src);
0360 
0361     // recursive, of course
0362     static void Copy(aiNode **dest, const aiNode *src);
0363 
0364 private:
0365     // -------------------------------------------------------------------
0366     // Same as AddNodePrefixes, but with an additional check
0367     static void AddNodePrefixesChecked(aiNode *node, const char *prefix,
0368             unsigned int len,
0369             std::vector<SceneHelper> &input,
0370             unsigned int cur);
0371 
0372     // -------------------------------------------------------------------
0373     // Add node identifiers to a hashing set
0374     static void AddNodeHashes(aiNode *node, std::set<unsigned int> &hashes);
0375 
0376     // -------------------------------------------------------------------
0377     // Search for duplicate names
0378     static bool FindNameMatch(const aiString &name,
0379             std::vector<SceneHelper> &input, unsigned int cur);
0380 };
0381 
0382 } // namespace Assimp
0383 
0384 #endif // !! AI_SCENE_COMBINER_H_INC