fbxclonemanager.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /****************************************************************************************
  2. Copyright (C) 2015 Autodesk, Inc.
  3. All rights reserved.
  4. Use of this software is subject to the terms of the Autodesk license agreement
  5. provided at the time of installation or download, or which otherwise accompanies
  6. this software in either electronic or hard copy form.
  7. ****************************************************************************************/
  8. //! \file fbxclonemanager.h
  9. #ifndef _FBXSDK_UTILS_CLONE_MANAGER_H_
  10. #define _FBXSDK_UTILS_CLONE_MANAGER_H_
  11. #include <fbxsdk/fbxsdk_def.h>
  12. #include <fbxsdk/core/fbxobject.h>
  13. #include <fbxsdk/core/fbxquery.h>
  14. #include <fbxsdk/fbxsdk_nsbegin.h>
  15. /** The clone manager is a utility for cloning entire networks of FbxObject.
  16. * Options are available for specifying how the clones inherit the connections
  17. * of the original.
  18. *
  19. * Networks of FbxObject (inter-connected objects by OO, OP, PO or PP connections)
  20. * can be cloned. How the connections of clones are handled depends on mSrcPolicy and mExternalDstPolicy.
  21. *
  22. * To clone FbxObject instances and their dependents, put them into a CloneSet
  23. * and pass the CloneSet to this class:
  24. * \code
  25. * FbxCloneManager cloneManager;
  26. * FbxCloneManager::CloneSet cloneSet;
  27. * FbxCloneManager::CloneSetElement defaultCloneOptions(FbxCloneManager::sConnectToClone,
  28. * FbxCloneManager::sConnectToOriginal,
  29. * FbxObject::eDeepClone);
  30. * cloneSet.Insert(someObject, defaultCloneOptions);
  31. * cloneManager.AddDependents(cloneSet, someObject, defaultCloneOptions);
  32. * cloneManager.Clone(cloneSet, scene)
  33. * \endcode
  34. *
  35. * \remark If cloning occurs on the same scene as the original objects, the system will contain duplicated names. Although this is acceptable in FBX,
  36. * some applications may not behave correctly with duplicated names. It is the responsability of the caller to resolve any conflicts.
  37. *
  38. * \see FbxCloneManager::CloneSetElement
  39. * \see FbxCloneManager::CloneSet
  40. * \nosubgrouping
  41. */
  42. class FBXSDK_DLL FbxCloneManager
  43. {
  44. public:
  45. //! Maximum depth to clone dependents.
  46. static const int sMaximumCloneDepth;
  47. /** Connect to objects that are connected to original object.
  48. * This is a flag to mSrcPolicy or mExternalDstPolicy.
  49. */
  50. static const int sConnectToOriginal;
  51. /** Connect to clones of objects that are connected to original object.
  52. * (only if those original objects are also in the clone set)
  53. * This is a flag to mSrcPolicy.
  54. */
  55. static const int sConnectToClone;
  56. /** This represents an element in FbxCloneManager::CloneSet to be cloned.
  57. * This class contains the option for specifying how connections are cloned and the
  58. * cloned object.
  59. * \see FbxCloneManager
  60. * \see FbxCloneManager::CloneSet
  61. */
  62. struct FBXSDK_DLL CloneSetElement
  63. {
  64. public:
  65. /** Constructor.
  66. * \param pSrcPolicy Specify how to handle source connections. Valid values are 0, sConnectToOriginal,
  67. * sConnectToClone or sConnectToOriginal|sConnectToClone.
  68. * \param pExternalDstPolicy Specify how to handle destination connections to objects NOT in
  69. * the clone set. Valid values are 0 or sConnectToOriginal.
  70. * \param pCloneType Specify the type of cloning. FbxObject::Clone uses the same parameter.
  71. */
  72. CloneSetElement( int pSrcPolicy = 0,
  73. int pExternalDstPolicy = 0,
  74. FbxObject::ECloneType pCloneType = FbxObject::eReferenceClone );
  75. //! the type of cloning to perform
  76. FbxObject::ECloneType mType;
  77. /** Policy on how to handle source connections on the original object. Valid values are 0
  78. * or any bitwise OR'd combination of sConnectToOriginal, and sConnectToClone.
  79. */
  80. int mSrcPolicy;
  81. /** policy on how to handle destination connections on the original object to
  82. * objects NOT in the clone set. (Destination connections to objects in the set
  83. * are handled by that object's source policy) Valid values are 0 or sConnectToOriginal.
  84. */
  85. int mExternalDstPolicy;
  86. /** This is a pointer to the newly created clone.
  87. * It is set after the call to FbxCloneManager::Clone()
  88. */
  89. FbxObject* mObjectClone;
  90. /** Internal use.
  91. */
  92. bool mLayerElementProcessed;
  93. bool mConnectionsProcessed;
  94. };
  95. /** The CloneSet is a collection of pointers to objects that will be cloned in Clone()
  96. * Attached to each object is a CloneSetElement. Its member variables dictate how
  97. * the corresponding object will be cloned, and how it will inherit connections
  98. * on the original object.
  99. */
  100. typedef FbxMap<FbxObject*,CloneSetElement> CloneSet;
  101. /** Constructor
  102. */
  103. FbxCloneManager();
  104. /** Destructor
  105. */
  106. virtual ~FbxCloneManager();
  107. /** This function simplifies the process of cloning one object and all its depedency graph by automatically preparing
  108. * the CloneSet and calling the Clone method using the code below.
  109. *
  110. * \code
  111. * FbxCloneManager cloneManager;
  112. * FbxCloneManager::CloneSet cloneSet;
  113. * FbxCloneManager::CloneSetElement defaultCloneOptions(FbxCloneManager::sConnectToClone,
  114. * FbxCloneManager::sConnectToOriginal,
  115. * FbxObject::eDeepClone);
  116. * FbxObject* lReturnObj = (FbxObject*)pObject;
  117. *
  118. * cloneManager.AddDependents(cloneSet, pObject, defaultCloneOptions, FbxCriteria::ObjectType(FbxObject::ClassId));
  119. * cloneSet.Insert((FbxObject*)pObject, defaultCloneOptions);
  120. *
  121. * // collect all the FbxCharacters, if any (these are indirect dependencies not visible by the AddDependents recursion)
  122. * FbxArray<FbxObject*> lExtras;
  123. * FbxCloneManager::CloneSet::RecordType* lIterator = cloneSet.Minimum();
  124. * while( lIterator )
  125. * {
  126. * FbxObject* lObj = lIterator->GetKey();
  127. * cloneManager.LookForIndirectDependent(lObj, cloneSet, lExtras);
  128. * lIterator = lIterator->Successor();
  129. * }
  130. *
  131. * // and add them to cloneSet
  132. * for (int i = 0, c = lExtras.GetCount(); i < c; i++)
  133. * {
  134. * FbxObject* lObj = lExtras[i];
  135. * cloneManager.AddDependents(cloneSet, lObj, defaultCloneOptions);
  136. * cloneSet.Insert(lObj, defaultCloneOptions);
  137. * }
  138. *
  139. * // clone everything
  140. * if (cloneManager.Clone(cloneSet, pContainer))
  141. * {
  142. * // get the clone of pObject
  143. * CloneSet::RecordType* lIterator = cloneSet.Find((FbxObject* const)pObject);
  144. * if( lIterator )
  145. * {
  146. * lReturnObj = lIterator->GetValue().mObjectClone;
  147. * }
  148. * }
  149. * return lReturnObj;
  150. * \endcode
  151. *
  152. * \param pObject Object to clone.
  153. * \param pContainer This object (typically a scene or document) will contain the new clones.
  154. * \return The clone of \e pObject if all its depedency graph have been cloned successfully, NULL otherwise.
  155. * \remark It is advised not to use an FbxNode object for \e pContainer to group the cloned dependency graph.
  156. * Some objects of the FBX SDK are not meant to be connected to FbxNode objects and if they are, the final scene
  157. * will not comply to the FBX standard and its behavior cannot be guaranteed.
  158. * \remark If \e pContainer is left \c NULL the cloned objects only exists in the FbxSdkManager and need to be
  159. * manually connected to the scene in order to be saved to disk.
  160. *
  161. * Example:
  162. * \code
  163. * FbxObject* lObj2BCloned = ...
  164. * FbxNode* myNewParent = FbxNode::Create(lNewScene, "Clone");
  165. * lNewScene->GetRootNode()->AddChild(lN);
  166. *
  167. * FbxCloneManager cloneManager;
  168. * FbxNode *lClone = (FbxNode*)cloneManager.Clone(lObj2BCloned);
  169. *
  170. * // make sure the cloned object is connected to the scene
  171. * lClone->ConnectDstObject(lNewScene);
  172. * \endcode
  173. */
  174. static FbxObject* Clone(const FbxObject* pObject, FbxObject* pContainer = NULL);
  175. /** Clone all objects in the set using the given policies for duplication
  176. * of connections. Each CloneSetElement in the set will have its mObjectClone
  177. * pointer set to the newly created clone. The following code shows how to access the cloned objects:
  178. *
  179. * \code
  180. * if (cloneManager.Clone(cloneSet, pContainer))
  181. * {
  182. * // access the clones
  183. * FbxCloneManager::CloneSet::RecordType* lIterator = cloneSet.Minimum();
  184. * while( lIterator )
  185. * {
  186. * FbxObject* lOriginalObject = lIterator->GetKey();
  187. * FbxObject* lClonedObject = lIterator->GetValue().mObjectClone;
  188. * lIterator = lIterator->Successor();
  189. * }
  190. * }
  191. * \endcode
  192. *
  193. * \param pSet Set of objects to clone
  194. * \param pContainer This object (typically a scene or document) will contain the new clones
  195. * \return true if all objects were cloned, false otherwise.
  196. * \remark It is advised not to use an FbxNode object for \e pContainer to group the cloned dependency graph.
  197. * Some objects of the FBX SDK are not meant to be connected to FbxNode objects and if they are, the final scene
  198. * will not comply to the FBX standard and its behavior cannot be guaranteed.
  199. * \remark If \e pContainer is left \c NULL the cloned objects only exists in the FbxSdkManager and need to be
  200. * manually connected to the scene in order to be saved to disk.
  201. */
  202. virtual bool Clone( CloneSet& pSet, FbxObject* pContainer = NULL ) const;
  203. /** Add all dependents of the given object to the CloneSet.
  204. * Dependents of items already in the set are ignored to prevent
  205. * infinite recursion on cyclic dependencies.
  206. * \param pSet The set to add items.
  207. * \param pObject Object to add dependents to
  208. * \param pCloneOptions
  209. * \param pTypes Types of dependent objects to consider
  210. * \param pDepth Maximum recursive depth. Valid range is [0,sMaximumCloneDepth]
  211. *
  212. * The following example shows how to perform multiple calls to AddDependents() to collect several
  213. * subgraphs to be cloned:
  214. * \code
  215. * FbxObject* lRoot = ... // initialized with the root of the graph to be cloned
  216. * FbxCharacter* lCharacter = ... // points to the FbxCharacter driving the character defined by "lRoot" graph
  217. *
  218. * FbxCloneManager cloneManager;
  219. * FbxCloneManager::CloneSet cloneSet;
  220. *
  221. * cloneManager.AddDependents(cloneSet, lRoot);
  222. * cloneSet.Insert(lRoot, defaultCloneOptions);
  223. *
  224. * cloneManager.AddDependents(cloneSet, lCharacter);
  225. * cloneSet.Insert(lCharacter, defaultCloneOptions);
  226. *
  227. * \endcode
  228. */
  229. virtual void AddDependents( CloneSet& pSet,
  230. const FbxObject* pObject,
  231. const CloneSetElement& pCloneOptions = CloneSetElement(),
  232. FbxCriteria pTypes = FbxCriteria::ObjectType(FbxObject::ClassId),
  233. int pDepth = sMaximumCloneDepth ) const;
  234. /*****************************************************************************************************************************
  235. ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
  236. *****************************************************************************************************************************/
  237. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  238. static FbxObject* Clone(const FbxObject* pObject, CloneSet* pSet, FbxObject* pContainer = NULL);
  239. private:
  240. friend class FbxScene;
  241. bool ReAssignLayerElements( FbxCloneManager::CloneSet::RecordType* pIterator, const FbxCloneManager::CloneSet& pSet) const;
  242. bool CloneConnections( CloneSet::RecordType* pIterator, const CloneSet& pSet) const;
  243. bool CheckIfCloneOnSameScene(const FbxObject* pObject, FbxObject* pContainer) const;
  244. virtual void LookForIndirectDependent(const FbxObject* pObject, CloneSet& pSet, FbxArray<FbxObject*>& lIndirectDepend);
  245. virtual bool NeedToBeExcluded(FbxObject* lObj) const;
  246. bool mCloneOnSameScene;
  247. #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
  248. };
  249. #include <fbxsdk/fbxsdk_nsend.h>
  250. #define CloneSetCast(x) ((FbxCloneManager::CloneSet*)(x))
  251. #define CloneSetElementCast(x) ((FbxCloneManager::CloneSetElement*)((x!=NULL)?&(x->GetValue()):NULL))
  252. #endif /* _FBXSDK_UTILS_CLONE_MANAGER_H_ */