1/****************************************************************************************
2
3 Copyright (C) 2015 Autodesk, Inc.
4 All rights reserved.
5
6 Use of this software is subject to the terms of the Autodesk license agreement
7 provided at the time of installation or download, or which otherwise accompanies
8 this software in either electronic or hard copy form.
9
10****************************************************************************************/
11
12//! \file fbxrenamingstrategy.h
13#ifndef _FBXSDK_UTILS_RENAMINGSTRATEGY_H_
14#define _FBXSDK_UTILS_RENAMINGSTRATEGY_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/core/base/fbxcharptrset.h>
19#include <fbxsdk/utils/fbxnamehandler.h>
20
21#include <fbxsdk/fbxsdk_nsbegin.h>
22
23class FbxScene;
24class FbxNode;
25
26/** This base class is an abstract implementation of a renaming strategy for avoiding name clashes.
27 * An implementation of a reader (FbxReader) or writer (FbxWriter) class must call a concrete implementation
28 * of "FbxRenamingStrategyInterface::Rename()" every time a name is imported or exported to avoid name clashes.
29 * Any class deriving from FbxRenamingStrategyBase must implement FbxRenamingStrategyInterface::Clear(),
30 * FbxRenamingStrategyInterface::Rename(), and FbxRenamingStrategyInterface::Clone().
31 * \nosubgrouping
32 * \see FbxNameHandler FbxRenamingStrategyNumber
33 */
34class FBXSDK_DLL FbxRenamingStrategyInterface
35{
36public:
37 //! Constructor.
38 FbxRenamingStrategyInterface();
39
40 //! Destructor.
41 virtual ~FbxRenamingStrategyInterface ();
42
43 //! Resets internal state regarding assigned names.
44 virtual void Clear() = 0;
45
46 /** Rename a name if necessary to avoid name-clash issues.
47 * \param pName The name to be renamed.
48 * \return Return \c true on success, \c false otherwise.
49 */
50 virtual bool Rename(FbxNameHandler& pName) = 0;
51
52 /** Create a dynamic renaming strategy instance of the same type as the child class.
53 * \return New instance.
54 */
55 virtual FbxRenamingStrategyInterface* Clone() = 0;
56};
57
58/** Implements a renaming strategy that resolves name clashes by adding number postfixes.
59 * For example, when there are three objects with the same names "MyObject",
60 * and they will be renamed to "MyObject", "MyObject1" and "MyObject2".
61 * \nosubgrouping
62 * \see FbxNameHandler FbxRenamingStrategyBase
63 */
64class FBXSDK_DLL FbxRenamingStrategyNumber : public FbxRenamingStrategyInterface
65{
66public:
67 //! Constructor.
68 FbxRenamingStrategyNumber();
69
70 //! Destructor.
71 virtual ~FbxRenamingStrategyNumber ();
72
73 //! Resets internal state regarding assigned names.
74 virtual void Clear();
75
76 /** Rename a name if necessary to avoid name-clash issues.
77 * \param pName The name to be renamed.
78 * \return Return \c true on success, \c false otherwise.
79 */
80 virtual bool Rename(FbxNameHandler& pName);
81
82 /** Create a dynamic renaming strategy instance of the same type as the child class.
83 * \return New instance.
84 */
85 virtual FbxRenamingStrategyInterface* Clone();
86
87/*****************************************************************************************************************************
88** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
89*****************************************************************************************************************************/
90#ifndef DOXYGEN_SHOULD_SKIP_THIS
91private:
92 struct NameCell
93 {
94 NameCell(const char* pName) :
95 mName(pName),
96 mInstanceCount(0)
97 {
98 }
99
100 FbxString mName;
101 int mInstanceCount;
102 };
103
104 FbxArray<NameCell*> mNameArray;
105#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
106};
107
108/** The FbxRenamingStrategy object can be set to rename all the objects in a scene.
109 * It can remove name clashing, remove illegal characters, manage namespaces and manage backward compatibility.
110 * It is better to choose FbxSceneRenamer instead of this class to simplify the usage.
111 * \nosubgrouping
112 * \see FbxSceneRenamer
113 */
114class FBXSDK_DLL FbxRenamingStrategy : public FbxRenamingStrategyInterface
115{
116public:
117 /** \enum EDirection The mode describing the convention direction, from FBX format or to FBX format.
118 * - \e eToFBX Convert to FBX format from another format.
119 * - \e eFromFBX Convert from FBX format to another format.
120 */
121 enum EDirection
122 {
123 eToFBX,
124 eFromFBX
125 };
126
127 /** Constructor.
128 * \param pMod The mode describing the convention direction, from FBX format or to FBX format.
129 * \param pOnCreationRun
130 */
131 FbxRenamingStrategy(EDirection pMod, bool pOnCreationRun = false);
132
133 //! Destructor.
134 virtual ~FbxRenamingStrategy();
135
136 /** Rename a name if necessary.
137 * \param pName The name to be renamed.
138 * \return Return \c true on success, \c false otherwise.
139 */
140 virtual bool Rename(FbxNameHandler& pName);
141
142 //! Resets internal state regarding assigned names.
143 virtual void Clear();
144
145 /** Create a dynamic renaming strategy instance of the same type as the child class.
146 * \return New instance.
147 */
148 virtual FbxRenamingStrategyInterface* Clone();
149
150 /** \enum EClashType
151 * - \e eNameClashAuto
152 * - \e eNameClashType1
153 * - \e eNameClashType2
154 */
155 enum EClashType
156 {
157 eNameClashAuto,
158 eNameClashType1,
159 eNameClashType2
160 };
161
162 /** Setup the strategy to perform this algorithm
163 * \param pType
164 */
165 void SetClashSoverType(EClashType pType);
166
167 /** Returns a name with its prefix removed.
168 * \param pName A name containing a prefix.
169 * \return The part of pName following the "::"
170 */
171 static char* NoPrefixName (const char* pName);
172
173 /** Returns a name with its prefix removed.
174 * \param pName A name containing a prefix.
175 * \return The part of pName following the "::"
176 */
177 static char* NoPrefixName (FbxString& pName);
178
179 /** Get the namespace of the last renamed object.
180 * \return Char pointer to the namespace.
181 */
182 virtual char* GetNameSpace() { return mNameSpace.Buffer(); }
183
184 /** Sets the current scene namespace symbol.
185 * \param pNameSpaceSymbol namespace symbol.
186 */
187 virtual void SetInNameSpaceSymbol(FbxString pNameSpaceSymbol){mInNameSpaceSymbol = pNameSpaceSymbol;}
188
189 /** Sets the wanted scene namespace symbol.
190 * \param pNameSpaceSymbol namespace symbol.
191 */
192 virtual void SetOutNameSpaceSymbol(FbxString pNameSpaceSymbol){mOutNameSpaceSymbol = pNameSpaceSymbol;}
193
194 /** Sets case sensitivity for name clashing.
195 * \param pIsCaseSensitive Set to \c true to make the name clashing case sensitive.
196 */
197 virtual void SetCaseSensibility(bool pIsCaseSensitive){mCaseSensitive = pIsCaseSensitive ;}
198
199 /** Sets the flag for character acceptance during renaming.
200 * \param pReplaceNonAlphaNum Set to \c true to replace illegal characters with an underscore ("_").
201 */
202 virtual void SetReplaceNonAlphaNum(bool pReplaceNonAlphaNum){mReplaceNonAlphaNum = pReplaceNonAlphaNum;}
203
204 /** Sets the flag for first character acceptance during renaming.
205 * \param pFirstNotNum Set to \c true to add an underscore to the name if the first character is a number.
206 */
207 virtual void SetFirstNotNum(bool pFirstNotNum){mFirstNotNum = pFirstNotNum;}
208
209 /** Recursively renames all the unparented namespaced objects (Prefix mode) starting from this node.
210 * \param pNode Parent node.
211 * \param pIsRoot The root node.
212 * \remarks This function adds "_NSclash" when it encounters an unparented namespaced object.
213 */
214 virtual bool RenameUnparentNameSpace(FbxNode* pNode, bool pIsRoot = false);
215
216 /** Recursively removes all the unparented namespaced "key" starting from this node.
217 * \param pNode Parent node.
218 * \remarks This function removes "_NSclash" when encountered. This is the opposite from RenameUnparentNameSpace.
219 */
220 virtual bool RemoveImportNameSpaceClash(FbxNode* pNode);
221
222 /** Recursively get all the namespace starting from this node's parent.
223 * \param pNode Parent node.
224 * \param pNameSpaceList output the namespace list from pNode's parent to the root node.
225 */
226 virtual void GetParentsNameSpaceList(FbxNode* pNode, FbxArray<FbxString*> &pNameSpaceList);
227
228 /** Recursively replace the namespace starting from this node to its children.
229 * \param pNode Current node.
230 * \param OldNS The old namespace to be replaced with the NewNs.
231 * \param NewNS The new namespace to replace OldNs.
232 */
233 virtual bool PropagateNameSpaceChange(FbxNode* pNode, FbxString OldNS, FbxString NewNS);
234
235/*****************************************************************************************************************************
236** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
237*****************************************************************************************************************************/
238#ifndef DOXYGEN_SHOULD_SKIP_THIS
239protected:
240 virtual bool RenameToFBX(FbxNameHandler& pName);
241 virtual bool RenameFromFBX(FbxNameHandler& pName);
242 virtual FbxString& ReplaceNonAlphaNum(FbxString& pName, const char* pReplace, bool pIgnoreNameSpace);
243
244 EDirection mMode;
245 EClashType mType;
246
247 struct NameCell
248 {
249 NameCell(const char* pName) :
250 mName(pName),
251 mInstanceCount(0)
252 {
253 }
254
255 FbxString mName;
256 int mInstanceCount;
257 };
258
259 FbxCharPtrSet mStringNameArray;
260 FbxArray<NameCell*> mExistingNsList;
261 bool mOnCreationRun;
262 bool mCaseSensitive;
263 bool mReplaceNonAlphaNum;
264 bool mFirstNotNum;
265 FbxString mNameSpace;
266 FbxString mInNameSpaceSymbol; //symbol identifying a name space
267 FbxString mOutNameSpaceSymbol;
268#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
269};
270
271/** The FbxSceneRenamer provides a way to easily rename objects in a scene without using the FbxRenamingStrategy class.
272 * FbxSceneRenamer can remove name clashing and illegal characters. It also manages namespaces.
273 *
274 * Example:
275 * Maya only accepts names with letters, digits, or underscores, and we want to convert
276 * all the names of a scene from FBX format to Maya format.
277 * \code
278 * FbxSceneRenamer lSceneRenamer(pScene);
279 * lSceneRenamer.RenameFor(FbxSceneRenamer::eFBX_TO_MAYA);
280 * \endcode
281 * \nosubgrouping
282 * \see FbxRenamingStrategy
283 */
284class FBXSDK_DLL FbxSceneRenamer
285{
286public:
287 /** Constructor
288 * \param pScene A scene which contains objects to be renamed.
289 */
290 FbxSceneRenamer(FbxScene* pScene) {mScene = pScene;};
291
292 //! Destructor.
293 virtual ~FbxSceneRenamer(){};
294
295 /** \enum ERenamingMode The Mode describing from which format to which format.
296 * - \e eNone
297 * - \e eMAYA_TO_FBX5
298 * - \e eMAYA_TO_FBX_MB75
299 * - \e eMAYA_TO_FBX_MB70
300 * - \e eFBXMB75_TO_FBXMB70
301 * - \e eFBX_TO_FBX
302 * - \e eMAYA_TO_FBX
303 * - \e eFBX_TO_MAYA
304 * - \e eLW_TO_FBX
305 * - \e eFBX_TO_LW
306 * - \e eXSI_TO_FBX
307 * - \e eFBX_TO_XSI
308 * - \e eMAX_TO_FBX
309 * - \e eFBX_TO_MAX
310 * - \e eMB_TO_FBX
311 * - \e eFBX_TO_MB
312 * - \e eDAE_TO_FBX
313 * - \e eFBX_TO_DAE
314 */
315 enum ERenamingMode
316 {
317 eNone,
318 eMAYA_TO_FBX5,
319 eMAYA_TO_FBX_MB75,
320 eMAYA_TO_FBX_MB70,
321 eFBXMB75_TO_FBXMB70,
322 eFBX_TO_FBX,
323 eMAYA_TO_FBX,
324 eFBX_TO_MAYA,
325 eLW_TO_FBX,
326 eFBX_TO_LW,
327 eXSI_TO_FBX,
328 eFBX_TO_XSI,
329 eMAX_TO_FBX,
330 eFBX_TO_MAX,
331 eMB_TO_FBX,
332 eFBX_TO_MB,
333 eDAE_TO_FBX,
334 eFBX_TO_DAE
335 };
336
337 /** Rename the objects of the scene according the specific mode.
338 * \param pMode A mode describing from which format to which format.
339 */
340 void RenameFor(ERenamingMode pMode);
341
342/*****************************************************************************************************************************
343** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
344*****************************************************************************************************************************/
345#ifndef DOXYGEN_SHOULD_SKIP_THIS
346private:
347 void ResolveNameClashing( bool pFromFbx, bool pIgnoreNS, bool pIsCaseSensitive,
348 bool pReplaceNonAlphaNum, bool pFirstNotNum,
349 FbxString pInNameSpaceSymbol, FbxString pOutNameSpaceSymbol,
350 bool pNoUnparentNS/*for MB < 7.5*/, bool pRemoveNameSpaceClash);
351
352 FbxRenamingStrategyInterface* mNodeRenamingStrategy;
353 FbxScene* mScene;
354#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
355};
356
357#include <fbxsdk/fbxsdk_nsend.h>
358
359#endif /* _FBXSDK_UTILS_RENAMINGSTRATEGY_H_ */
360
361