Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:30:10

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