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 fbxlayer.h
13#ifndef _FBXSDK_SCENE_GEOMETRY_LAYER_H_
14#define _FBXSDK_SCENE_GEOMETRY_LAYER_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/core/fbxdatatypes.h>
19#include <fbxsdk/core/fbxstream.h>
20#include <fbxsdk/scene/shading/fbxsurfacematerial.h>
21#include <fbxsdk/scene/shading/fbxtexture.h>
22
23#include <fbxsdk/fbxsdk_nsbegin.h>
24
25class FbxLayerElementArray;
26class FbxLayerContainer;
27
28/** Base class for elements of layers (FbxLayer).
29 * A layer element type is identified by EType.
30 * A FbxLayerElement describes how the layer element is mapped to a geometry surface
31 * and how the mapping information is arranged in memory.
32 * A FbxLayerElement contains Normals, UVs or other kind of information.
33 *
34 * \see FbxLayer
35 * \see FbxLayerElement::EMappingMode
36 * \see FbxLayerElement::EReferenceMode
37 */
38class FBXSDK_DLL FbxLayerElement
39{
40public:
41 /** \enum EType Layer Element type identifier.
42 * - \e eUnknown Undefined Layer Element class.
43 * - \e eNormal Layer Element of type FbxLayerElementNormal.
44 * - \e eBiNormal Layer Element of type FbxLayerElementBinormal.
45 * - \e eTangent Layer Element of type FbxLayerElementTangent.
46 * - \e eMaterial Layer Element of type FbxLayerElementMaterial.
47 * - \e eTextureDiffuse Layer Element of type FbxLayerElementTexture.
48 * - \e ePolygonGroup Layer Element of type FbxLayerElementPolygonGroup.
49 * - \e eUV Layer Element of type FbxLayerElementUV.
50 * - \e eVertexColor Layer Element of type FbxLayerElementVertexColor.
51 * - \e eSmoothing Layer Element of type FbxLayerElementSmoothing.
52 * - \e eVertexCrease Layer Element of type FbxLayerElementCrease.
53 * - \e eEdgeCrease Layer Element of type FbxLayerElementCrease.
54 * - \e eHole Layer Element of type FbxLayerElementHole.
55 * - \e eUserData Layer Element of type FbxLayerElementUserData.
56 * - \e eVisibility Layer Element of type FbxLayerElementVisibility.
57 * - \e eTextureEmissive Layer Element of type FbxLayerElementTexture.
58 * - \e eTextureEmissiveFactor Layer Element of type FbxLayerElementTexture.
59 * - \e eTextureAmbient Layer Element of type FbxLayerElementTexture.
60 * - \e eTextureAmbientFactor Layer Element of type FbxLayerElementTexture.
61 * - \e eTextureDiffuseFactor Layer Element of type FbxLayerElementTexture.
62 * - \e eTextureSpecular Layer Element of type FbxLayerElementTexture.
63 * - \e eTextureNormalMap Layer Element of type FbxLayerElementTexture.
64 * - \e eTextureSpecularFactor Layer Element of type FbxLayerElementTexture.
65 * - \e eTextureShininess Layer Element of type FbxLayerElementTexture.
66 * - \e eTextureBump Layer Element of type FbxLayerElementTexture.
67 * - \e eTextureTransparency Layer Element of type FbxLayerElementTexture.
68 * - \e eTextureTransparencyFactor Layer Element of type FbxLayerElementTexture.
69 * - \e eTextureReflection Layer Element of type FbxLayerElementTexture.
70 * - \e eTextureReflectionFactor Layer Element of type FbxLayerElementTexture.
71 * - \e eTextureDisplacement Layer Element of type FbxLayerElementTexture.
72 * - \e eTextureDisplacementVector Layer Element of type FbxLayerElementTexture.
73 * - \e eTypeCount
74 */
75 enum EType
76 {
77 eUnknown,
78
79 //Non-Texture layer element types
80 //Note: Make sure to update static index below if you change this enum!
81 eNormal,
82 eBiNormal,
83 eTangent,
84 eMaterial,
85 ePolygonGroup,
86 eUV,
87 eVertexColor,
88 eSmoothing,
89 eVertexCrease,
90 eEdgeCrease,
91 eHole,
92 eUserData,
93 eVisibility,
94
95 //Texture layer element types
96 //Note: Make sure to update static index below if you change this enum!
97 eTextureDiffuse,
98 eTextureDiffuseFactor,
99 eTextureEmissive,
100 eTextureEmissiveFactor,
101 eTextureAmbient,
102 eTextureAmbientFactor,
103 eTextureSpecular,
104 eTextureSpecularFactor,
105 eTextureShininess,
106 eTextureNormalMap,
107 eTextureBump,
108 eTextureTransparency,
109 eTextureTransparencyFactor,
110 eTextureReflection,
111 eTextureReflectionFactor,
112 eTextureDisplacement,
113 eTextureDisplacementVector,
114
115 eTypeCount
116 };
117
118 const static int sTypeTextureStartIndex = int(eTextureDiffuse); //!< The start index of texture type layer elements.
119 const static int sTypeTextureEndIndex = int(eTypeCount) - 1; //!< The end index of texture type layer elements.
120 const static int sTypeTextureCount = sTypeTextureEndIndex - sTypeTextureStartIndex + 1; //!< The count of texture type layer elements.
121 const static int sTypeNonTextureStartIndex = int(eNormal); //!< The start index of non-texture type layer elements.
122 const static int sTypeNonTextureEndIndex = int(eVisibility); //!< The end index of non-texture type layer elements.
123 const static int sTypeNonTextureCount = sTypeNonTextureEndIndex - sTypeNonTextureStartIndex + 1; //!< The count of non-texture type layer elements.
124 static const char* const sTextureNames[]; //!< Array of names of texture type layer elements.
125 static const char* const sTextureUVNames[]; //!< Array of names of UV layer elements.
126 static const char* const sNonTextureNames[]; //!< Array of names of non-texture type layer elements.
127 static const FbxDataType sTextureDataTypes[]; //!< Array of texture types.
128 static const char* const sTextureChannelNames[]; //!< Array of texture channels.
129
130 /** \enum EMappingMode Determines how the element is mapped to a surface.
131 * - \e eNone The mapping is undetermined.
132 * - \e eByControlPoint There will be one mapping coordinate for each surface control point/vertex.
133 * - \e eByPolygonVertex There will be one mapping coordinate for each vertex, for every polygon of which it is a part.
134 This means that a vertex will have as many mapping coordinates as polygons of which it is a part.
135 * - \e eByPolygon There can be only one mapping coordinate for the whole polygon.
136 * - \e eByEdge There will be one mapping coordinate for each unique edge in the mesh.
137 This is meant to be used with smoothing layer elements.
138 * - \e eAllSame There can be only one mapping coordinate for the whole surface.
139 */
140 enum EMappingMode
141 {
142 eNone,
143 eByControlPoint,
144 eByPolygonVertex,
145 eByPolygon,
146 eByEdge,
147 eAllSame
148 };
149
150 /** \enum EReferenceMode Determines how the mapping information is stored in the array of coordinates.
151 * - \e eDirect This indicates that the mapping information for the n'th element is found in the n'th place of
152 FbxLayerElementTemplate::mDirectArray.
153 * - \e eIndex, This symbol is kept for backward compatibility with FBX v5.0 files. In FBX v6.0 and higher,
154 this symbol is replaced with eIndexToDirect.
155 * - \e eIndexToDirect This indicates that the FbxLayerElementTemplate::mIndexArray
156 contains, for the n'th element, an index in the FbxLayerElementTemplate::mDirectArray
157 array of mapping elements. eIndexToDirect is usually useful for storing eByPolygonVertex mapping
158 mode elements coordinates. Since the same coordinates are usually
159 repeated many times, this saves spaces by storing the coordinate only one time
160 and then referring to them with an index. Materials and Textures are also referenced with this
161 mode and the actual Material/Texture can be accessed via the FbxLayerElementTemplate::mDirectArray
162 */
163 enum EReferenceMode
164 {
165 eDirect,
166 eIndex,
167 eIndexToDirect
168 };
169
170
171 /** Sets the Mapping Mode.
172 * \param pMappingMode Specifies the way that layer element is mapped to a surface.
173 */
174 void SetMappingMode(EMappingMode pMappingMode) { mMappingMode = pMappingMode; }
175
176 /** Sets the Reference Mode.
177 * \param pReferenceMode Specifies the reference mode.
178 */
179 void SetReferenceMode(EReferenceMode pReferenceMode) { mReferenceMode = pReferenceMode; }
180
181 /** Returns the Mapping Mode.
182 * \return The current Mapping Mode.
183 */
184 EMappingMode GetMappingMode() const { return mMappingMode; }
185
186 /** Returns the Reference Mode.
187 * \return The current Reference Mode.
188 */
189 EReferenceMode GetReferenceMode() const { return mReferenceMode; }
190
191 /** Sets the name of this object.
192 * \param pName Specifies the name of this LayerElement object.
193 */
194 void SetName(const char* pName) { mName = FbxString(pName); }
195
196 /** Returns the name of this object.
197 * \return The current name of this LayerElement object.
198 */
199 const char* GetName() const { return ((FbxLayerElement*)this)->mName.Buffer(); }
200
201 /** Equivalence operator
202 * \param pOther Layer element to be compared.
203 * \return \c True if equal, \c false otherwise.
204 */
205 bool operator==(const FbxLayerElement& pOther) const
206 {
207 return (mName == pOther.mName) &&
208 (mMappingMode == pOther.mMappingMode) &&
209 (mReferenceMode == pOther.mReferenceMode);
210 }
211
212 /** Assignment operator
213 * \param pOther Layer element assigned to this one.
214 * \return This layer element after assignment.
215 */
216 FbxLayerElement& operator=( FbxLayerElement const& pOther )
217 {
218 mMappingMode = pOther.mMappingMode;
219 mReferenceMode = pOther.mReferenceMode;
220 // name, type and owner should not be copied because they are
221 // initialized when this object is created
222 return *this;
223 }
224
225 //! Removes this layer element from its owner and delete it.
226 void Destroy();
227
228 //! Clears all the data from this layer element.
229 virtual bool Clear()
230 {
231 return true;
232 }
233
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 void SetType(const FbxDataType* pType) { mType = pType; }
239 const FbxLayerContainer* GetOwner() const { return mOwner; }
240
241protected:
242 FbxLayerElement()
243 : mMappingMode(eNone)
244 , mReferenceMode(eDirect)
245 , mName("")
246 , mOwner(NULL)
247 {
248 }
249
250 virtual ~FbxLayerElement()
251 {
252 }
253
254 EMappingMode mMappingMode;
255 EReferenceMode mReferenceMode;
256
257 FbxString mName;
258 const FbxDataType* mType;
259 FbxLayerContainer* mOwner;
260
261 void Destruct() { FbxDelete(this); }
262 virtual void SetOwner(FbxLayerContainer* pOwner, int pInstance = 0);
263
264 FBXSDK_FRIEND_NEW();
265
266public:
267 virtual int MemorySize() const { return 0; }
268 virtual bool ContentWriteTo(FbxStream& pStream) const;
269 virtual bool ContentReadFrom(const FbxStream& pStream);
270
271 friend class FbxLayerContainer;
272#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
273};
274
275/** \internal
276 * Identifies what error occurs when the data arrays are manipulated.
277 * \nosubgrouping
278 */
279
280class FBXSDK_DLL LockAccessStatus
281{
282public:
283 /** \internal
284 * \enum ELockAccessStatus Identifies what error occurs when the data arrays are manipulated.
285 * - \e eSuccess Operation Successful.
286 * - \e eUnsupportedDTConversion Attempts to convert to an unsupported DataType.
287 * - \e eCorruptedCopyback The Release of a converted buffer fails and corrupts the main data.
288 * - \e eBadValue Invalid value.
289 * - \e eLockMismatch Attempts to change to an incompatible lock.
290 * - \e eNoWriteLock A write operation is attempted but no WriteLock is available.
291 * - \e eNoReadLock A read operation is attempted but the WriteLock is active.
292 * - \e eNotOwner Attempts to release a lock on an invalid data buffer pointer.
293 * - \e eDirectLockExist A direct access lock is still active.
294 */
295 enum ELockAccessStatus
296 {
297 eSuccess,
298 eUnsupportedDTConversion,
299 eCorruptedCopyback,
300 eBadValue,
301 eLockMismatch,
302 eNoWriteLock,
303 eNoReadLock,
304 eNotOwner,
305 eDirectLockExist
306 };
307};
308
309//Special conversion types, we do not want them to resolve to undefined.
310typedef FbxHandle* FbxRefPtr;
311typedef FbxLayerElementArray* FbxLayerElementArrayPtr;
312typedef FbxSurfaceMaterial* FbxSurfaceMaterialPtr;
313typedef FbxTexture* FbxTexturePtr;
314
315inline EFbxType FbxTypeOf(const FbxRefPtr&){ return eFbxReference; }
316inline EFbxType FbxTypeOf(const FbxLayerElementArrayPtr&){ return eFbxReference; }
317inline EFbxType FbxTypeOf(const FbxSurfaceMaterialPtr&){ return eFbxReference; }
318inline EFbxType FbxTypeOf(const FbxTexturePtr&){ return eFbxReference; }
319
320/** FbxLayerElementArray is the base class for FbxLayerElementArrayTemplate,
321 * it provides lock handling and data array manipulation of the data buffer for FbxLayerElement.
322 * \nosubgrouping
323 */
324
325class FBXSDK_DLL FbxLayerElementArray
326{
327public:
328 /**
329 * \name Constructor and Destructor
330 */
331 //@{
332
333 /** Constructor.
334 * \param pDataType The data type of the items in the data array.
335 */
336 FbxLayerElementArray(EFbxType pDataType);
337
338 //!Destructor.
339 virtual ~FbxLayerElementArray();
340
341 //@}
342
343 /**
344 * \name Status handling
345 */
346 //@{
347
348 //!Clears the access state and sets it to eSuccess.
349 inline void ClearStatus() { mStatus = LockAccessStatus::eSuccess; }
350
351 //!Retrieves the access state.
352 inline LockAccessStatus::ELockAccessStatus GetStatus() const { return mStatus; }
353 //@}
354
355 /**
356 * \name Locks handling
357 */
358 //@{
359
360 /** Returns whether write is locked.
361 * \return \c True if write is locked, \c false otherwise.
362 */
363 inline bool IsWriteLocked() const { return mWriteLock; };
364
365 /** Retrieves the read lock count.
366 * \return The read lock count.
367 */
368 inline int GetReadLockCount() const { return mReadLockCount; }
369 //@}
370
371 /** Returns whether this Array is accessed in any way.
372 * \return \c True if it is in use, \c false otherwise.
373 */
374 bool IsInUse() const;
375
376 /** Increments the number of read locks on this array.
377 * \return The current number of read locks (including the one just grabbed) or 0 if a write lock is active.
378 */
379 int ReadLock() const;
380
381 /** Releases a read lock on this array.
382 * \return The remaining read locks or -1 if a write lock is active.
383 */
384 int ReadUnlock() const;
385
386 /** Locks this array for writing. The data in the array is wiped out.
387 * \return \c True if a write lock has been successfully granted, \c false if one or more read locks
388 * are active.
389 */
390 bool WriteLock() const;
391
392 /** Releases the write lock on this array.
393 */
394 void WriteUnlock() const;
395
396 /** Locks this array for writing. The data that already exists in the array is kept and is valid.
397 * \return \c True if a write lock has been successfully granted, \c false if one or more read locks
398 * are active.
399 */
400 bool ReadWriteLock() const;
401
402 /** Releases the write lock on this array.
403 */
404 void ReadWriteUnlock() const;
405
406
407 /** \enum ELockMode Identifies the access mode to the data buffer.
408 * - \e eReadLock Read mode.
409 * - \e eWriteLock Write mode.
410 * - \e eReadWriteLock Read-write mode.
411 */
412 enum ELockMode
413 {
414 eReadLock = 1,
415 eWriteLock = 2,
416 eReadWriteLock = 3
417 };
418
419 /** Grants a locked access to the data buffer.
420 * \param pLockMode Access mode to the data buffer.
421 * \param pDataType If defined, tries to return the data as this type.
422 * \return A pointer to the data buffer or NULL if a failure occurs.
423 * \remarks In the case of a failure, the Status is updated with the
424 * reason for the failure. Also, when a type conversion occurs, a second buffer
425 * of the new type is allocated. In this case, the LockMode does not apply to the
426 * returned buffer since it is a copy but it does apply to the internal data of this
427 * object. The returned buffer still remains a property of this object and is
428 * deleted when the pointer is released or the object is destroyed. At the moment of
429 * release or destruction, the values in this buffer are copied back into this object.
430 */
431 virtual void* GetLocked(ELockMode pLockMode, EFbxType pDataType);
432
433 /** Grants a locked access to the data buffer.
434 * \param pLockMode Access mode to the data buffer.
435 * \return A pointer to the data buffer or NULL if a failure occurs.
436 * \remarks In the case of a failure, the Status is updated with the
437 * reason for the failure. Also, when a type conversion occurs, a second buffer
438 * of the new type is allocated. In this case, the LockMode does not apply to the
439 * returned buffer since it is a copy but it does apply to the internal data of this
440 * object. The returned buffer still remains a property of this object and is
441 * deleted when the pointer is released or the object is destroyed. At the moment of
442 * release or destruction, the values in this buffer are copied back into this object.
443 */
444 void* GetLocked(ELockMode pLockMode=eReadWriteLock) { return GetLocked(pLockMode, mDataType); }
445
446 /** Grants a locked access to the data buffer.
447 * \param pLockMode Access mode to the data buffer.
448 * \return A pointer to the data buffer or NULL if a failure occurs.
449 * \remarks In the case of a failure, the Status is updated with the
450 * reason for the failure. Also, when a type conversion occurs, a second buffer
451 * of the new type is allocated. In this case, the LockMode does not apply to the
452 * returned buffer since it is a copy but it does apply to the internal data of this
453 * object. The returned buffer still remains a property of this object and is
454 * deleted when the pointer is released or the object is destroyed. At the moment of
455 * release or destruction, the values in this buffer are copied back into this object.
456 */
457 template <class T> inline T* GetLocked(T*, ELockMode pLockMode=eReadWriteLock) {T v; return (T*)GetLocked(pLockMode, FbxTypeOf(v)); }
458
459 /** Unlock the data buffer.
460 * \param pDataPtr The buffer to be released.
461 * \param pDataType The data type of the data buffer.
462 * \remarks The passed pointer must be the one obtained by the call to GetLocked().
463 * Any other pointer causes this method to fail and the Status is updated with
464 * the reason for the failure. If the passed pointer refers a converted data
465 * buffer (see comment of GetLocked), this method copies the GetCount() items
466 * of the received buffer back into this object. Any other items that may have been added
467 * using a realloc call are ignored.
468 */
469 virtual void Release(void** pDataPtr, EFbxType pDataType);
470
471 /** Unlock the data buffer.
472 * \param pDataPtr The buffer to be released.
473 * \remarks The passed pointer must be the one obtained by the call to GetLocked().
474 * Any other pointer causes this method to fail and the Status is updated with
475 * the reason for the failure. If the passed pointer refers a converted data
476 * buffer (see comment of GetLocked), this method copies the GetCount() items
477 * of the received buffer back into this object. Any other items that may have been added
478 * using a realloc call are ignored.
479 */
480 void Release(void** pDataPtr) { Release(pDataPtr, mDataType); }
481
482 /** Unlock the data buffer.
483 * \param pDataPtr The buffer to be released.
484 * \param dummy The data type of dummy is used to specialize this function.
485 * \remarks The passed pointer must be the one obtained by the call to GetLocked().
486 * Any other pointer causes this method to fail and the Status is updated with
487 * the reason for the failure. If the passed pointer refers a converted data
488 * buffer (see comment of GetLocked), this method copies the GetCount() items
489 * of the received buffer back into this object. Any other items that may have been added
490 * using a realloc call are ignored.
491 */
492 template <class T> inline void Release(T** pDataPtr, T* dummy)
493 {
494 T*** voidPtr = &pDataPtr;
495 Release((void**)*voidPtr, FbxTypeOf(*dummy));
496 }
497
498 /** Returns the Stride size which equals the size of the data type of the data buffer.
499 */
500 virtual size_t GetStride() const;
501
502 /**
503 * \name Data array manipulation
504 */
505 //@{
506
507 //! Returns the count of items in the data buffer.
508 int GetCount() const;
509
510 /** Sets the count of items in the data buffer.
511 * \param pCount The count of items to be set.
512 */
513 void SetCount(int pCount);
514
515 //! Clears the data buffer.
516 void Clear();
517
518 /** Resizes the data buffer.
519 * \param pItemCount The new size of the data buffer.
520 */
521 void Resize(int pItemCount);
522
523 /** Appends space to the data buffer.
524 * \param pItemCount The appended space size
525 */
526 void AddMultiple(int pItemCount);
527
528 /** Appends a new item to the end of the data buffer.
529 * \param pItem Pointer of the new item to be added
530 * \param pValueType Data type of the new item
531 * \return The index of the new item
532 */
533 int Add(const void* pItem, EFbxType pValueType);
534
535 /** Inserts a new item at the specified position of the data buffer.
536 * \param pIndex The specified position
537 * \param pItem Pointer of the new item to be inserted
538 * \param pValueType Data type of the new item
539 * \return The index of the inserted item
540 * \remarks The input index must be within valid range and no error will be thrown if it is invalid.
541 */
542 int InsertAt(int pIndex, const void* pItem, EFbxType pValueType);
543
544 /** Sets the value for the specified item.
545 * \param pIndex The index of the item to be updated.
546 * \param pItem Pointer of the item whose value is copied to pIndex'th item
547 * \param pValueType Data type of the item
548 * \remarks The input index must be within valid range and no error will be thrown if it is invalid.
549 */
550 void SetAt(int pIndex, const void* pItem, EFbxType pValueType);
551
552 /** Sets the value of the last item.
553 * \param pItem Pointer of the item whose value is copied to the last item
554 * \param pValueType Data type of the item
555 * \remarks The array should contain at least one item and no error will be thrown if it is empty.
556 */
557 void SetLast(const void* pItem, EFbxType pValueType);
558
559 /** Removes the specified item from the data buffer.
560 * \param pIndex The index of the item to be removed
561 * \param pItem Place to hold the value of the removed item.
562 * \param pValueType Data type of the item
563 * \remarks The input index must be within valid range and no error will be thrown if it is invalid.
564 */
565 void RemoveAt(int pIndex, void** pItem, EFbxType pValueType);
566
567 /** Removes the last item from the data buffer.
568 * \param pItem Place to hold the value of the removed item.
569 * \param pValueType Data type of the item
570 * \remarks The array should contain at least one item and no error will be thrown if it is empty.
571 */
572 void RemoveLast(void** pItem, EFbxType pValueType);
573
574 /** Removes one item from the data buffer.
575 * \param pItem The first item who equals pItem is to be removed
576 * \param pValueType Data type of the item
577 * \return \c True if the item is removed successfully, \c false otherwise
578 */
579 bool RemoveIt(void** pItem, EFbxType pValueType);
580
581 /** Returns the specified item's value.
582 * \param pIndex Index of the item
583 * \param pItem Place to hold the item's value
584 * \param pValueType Data type of the item
585 * \return \c True if the item's value is returned successfully, \c false otherwise
586 * \remarks If the index is invalid, pItem is set to zero.
587 */
588 bool GetAt(int pIndex, void** pItem, EFbxType pValueType) const;
589
590 /** Returns the first item's value.
591 * \param pItem Place to hold the item's value
592 * \param pValueType Data type of the item
593 * \return \c True if the item's value is returned successfully, \c false otherwise
594 */
595 bool GetFirst(void** pItem, EFbxType pValueType) const;
596
597 /** Returns the last item's value.
598 * \param pItem Place to hold the item's value
599 * \param pValueType Data type of the item
600 * \return \c True if the item's value is returned successfully, \c false otherwise
601 */
602 bool GetLast(void** pItem, EFbxType pValueType) const;
603
604 /** Searches for an item in the data buffer.
605 * \param pItem The value of the item for which to search.
606 * \param pValueType Data type of the item
607 * \return The index of the item found, -1 if not found.
608 * \remarks The index of the first item whose value equals pItem is returned.
609 */
610 int Find(const void* pItem, EFbxType pValueType) const;
611
612 /** Searches for an item after the specified index in the data buffer.
613 * \param pAfterIndex The specified index after which the searching begins
614 * \param pItem The value of the item for which to search, the searching begins after pAfterIndex.
615 * \param pValueType Data type of the item
616 * \return The index of the item found, -1 if not found.
617 * \remarks The index of the first item whose value equals pItem is returned.
618 */
619 int FindAfter(int pAfterIndex, const void* pItem, EFbxType pValueType) const;
620
621 /** Searches for an item before the specified index in the data buffer.
622 * \param pBeforeIndex The specified index before which the searching begins
623 * \param pItem The value of the item for which to search, the searching begins before pBeforeIndex.
624 * \param pValueType The item's data type.
625 * \return The index of the item found, -1 if not found.
626 * \remarks The index of the first item whose value equals pItem is returned.
627 */
628 int FindBefore(int pBeforeIndex, const void* pItem, EFbxType pValueType) const;
629
630 /** Equivalence operator
631 * \param pArray Array compared to this one
632 * \return \c True if equal. \c false otherwise.
633 */
634 bool IsEqual(const FbxLayerElementArray& pArray) const;
635
636 /** Appends a new item to the end of the data buffer.
637 * \param pItem The new item to be added
638 * \return The index of the new item
639 */
640 template <class T> inline int Add(T const& pItem) { return Add((const void*)&pItem, FbxTypeOf(pItem)); }
641
642 /** Inserts a new item at the specified position of the data buffer.
643 * \param pIndex The specified position
644 * \param pItem The new item to be inserted
645 * \return The index of the inserted item
646 * \remarks The input index must be within valid range and no error will be thrown if it is invalid.
647 */
648 template <class T> inline int InsertAt(int pIndex, T const& pItem) { return InsertAt(pIndex, (const void*)&pItem, FbxTypeOf(pItem)); }
649
650 /** Sets the value of the specified item.
651 * \param pIndex The index of the item to be updated.
652 * \param pItem The item whose value is copied to pIndex'th item
653 * \remarks The input index must be within valid range and no error will be thrown if it is invalid.
654 */
655 template <class T> inline void SetAt(int pIndex, T const& pItem) { SetAt(pIndex, (const void*)&pItem, FbxTypeOf(pItem)); }
656
657 /** Sets the value of the last item.
658 * \param pItem The item whose value is copied to the last item
659 * \remarks The array should contain at least one item and no error will be thrown if it is empty.
660 */
661 template <class T> inline void SetLast(T const& pItem) { SetLast((const void*)&pItem, FbxTypeOf(pItem)); }
662
663 /** Removes the specified item from the data buffer.
664 * \param pIndex The index of the item to be removed
665 * \param pItem Place to hold the value of the removed item.
666 * \remarks The input index must be within valid range and no error will be thrown if it is invalid.
667 */
668 template <class T> inline void RemoveAt(int pIndex, T* pItem)
669 {
670 T** voidPtr = &pItem;
671 RemoveAt(pIndex, (void**)voidPtr, FbxTypeOf(*pItem));
672 }
673
674 /** Removes the last item from the data buffer.
675 * \param pItem Place to hold the value of the removed item.
676 * \remarks The array should contain at least one item and no error will be thrown if it is empty.
677 */
678 template <class T> inline void RemoveLast(T* pItem)
679 {
680 T** voidPtr = &pItem;
681 RemoveLast((void**)voidPtr, FbxTypeOf(*pItem));
682 }
683
684 /** Removes one item from the data buffer.
685 * \param pItem The first item who equals pItem is to be removed
686 * \return \c True if the item is removed successfully, \c false otherwise
687 */
688 template <class T> inline bool RemoveIt(T* pItem)
689 {
690 T** voidPtr = &pItem;
691 return RemoveIt((void**)voidPtr, FbxTypeOf(*pItem));
692 }
693
694 /** Returns the specified item's value.
695 * \param pIndex Index of the item
696 * \param pItem Place to hold the item's value
697 * \return \c True if the item's value is returned successfully, \c false otherwise
698 * \remarks If the index is invalid, pItem is set to zero.
699 */
700 template <class T> inline bool GetAt(int pIndex, T* pItem) const
701 {
702 T** voidPtr = &pItem;
703 return GetAt(pIndex, (void**)voidPtr, FbxTypeOf(*pItem));
704 }
705
706 /** Returns the first item's value.
707 * \param pItem Place to hold the item's value
708 * \return \c True if the item's value is returned successfully, \c false otherwise
709 */
710 template <class T> inline bool GetFirst(T* pItem) const
711 {
712 T** voidPtr = &pItem;
713 return GetFirst((void**)voidPtr, FbxTypeOf(*pItem));
714 }
715
716 /** Returns the last item's value.
717 * \param pItem Place to hold the item's value
718 * \return \c True if the item's value is returned successfully, \c false otherwise
719 */
720 template <class T> inline bool GetLast(T* pItem) const
721 {
722 T** voidPtr = &pItem;
723 return GetLast((void**)voidPtr, FbxTypeOf(*pItem));
724 }
725
726 /** Searches for an item in the data buffer.
727 * \param pItem The value of the item for which to search.
728 * \return The index of the item found, -1 if not found.
729 * \remarks The index of the first item whose value equals pItem is returned.
730 */
731 template <class T> inline int Find(T const& pItem) const { return Find((const void*)&pItem, FbxTypeOf(pItem)); }
732
733 /** Searches for an item after the specified index in the data buffer.
734 * \param pAfterIndex The specified index after which the searching begins
735 * \param pItem The value of the item for which to search, the searching begins after pAfterIndex.
736 * \return The index of the item found, -1 if not found.
737 * \remarks The index of the first item whose value equals pItem is returned.
738 */
739 template <class T> inline int FindAfter(int pAfterIndex, T const& pItem) const { return FindAfter(pAfterIndex, (const void*)&pItem, FbxTypeOf(pItem)); }
740
741 /** Searches for one item before the specified index in the data buffer.
742 * \param pBeforeIndex The specified index before which the searching begins
743 * \param pItem The value of the item for which to search, the searching begins before pBeforeIndex.
744 * \return The index of the item found, -1 if not found.
745 * \remarks The index of the first item whose value equals pItem is returned.
746 */
747 template <class T> inline int FindBefore(int pBeforeIndex, T const& pItem) const { return FindBefore(pBeforeIndex, (const void*)&pItem, FbxTypeOf(pItem)); }
748
749
750 /** Copies the items in the data buffer to an array.
751 * \param pDst The destination array where the items are to be copied.
752 */
753 template<typename T> inline void CopyTo(FbxArray<T>& pDst)
754 {
755 T src;
756 T* srcPtr = &src;
757
758 pDst.Clear();
759 if (mDataType != FbxTypeOf(src))
760 {
761 SetStatus(LockAccessStatus::eUnsupportedDTConversion);
762 return;
763 }
764
765 pDst.Resize(GetCount());
766 for (int i = 0; i < GetCount(); i++)
767 {
768 if (GetAt(i, (void**)&srcPtr, mDataType))
769 {
770 pDst.SetAt(i, src);
771 }
772 }
773 SetStatus(LockAccessStatus::eSuccess);
774 }
775 //@}
776
777protected:
778 void* GetDataPtr();
779 void* GetReference(int pIndex, EFbxType pValueType);
780 void GetReferenceTo(int pIndex, void** pRef, EFbxType pValueType);
781
782 inline void SetStatus(LockAccessStatus::ELockAccessStatus pVal) const
783 {
784 const_cast<FbxLayerElementArray*>(this)->mStatus = pVal;
785 }
786
787 void SetImplementation(void* pImplementation);
788 inline void* GetImplementation() { return mImplementation; }
789 virtual void ConvertDataType(EFbxType pDataType, void** pDataPtr, size_t* pStride);
790
791 EFbxType mDataType;
792
793private:
794 LockAccessStatus::ELockAccessStatus mStatus;
795
796 int mReadLockCount;
797 bool mWriteLock;
798 void* mImplementation;
799 size_t mStride;
800 int mDirectLockOn;
801 bool mDirectAccessOn;
802
803 FbxArray<void*> mConvertedData;
804
805};
806
807/** \internal
808 * This class provides simple RAII-style read locking of a FbxLayerElementArray object.
809 */
810template <typename T>
811struct FbxLayerElementArrayReadLock
812{
813 /** \internal
814 * On construction, this class requires the read lock.
815 */
816 FbxLayerElementArrayReadLock(FbxLayerElementArray& pArray) : mArray(pArray)
817 {
818 mLockedData = mArray.GetLocked((T*)NULL, FbxLayerElementArray::eReadLock);
819 }
820
821 /** \internal
822 * On destruction, this class releases the read lock.
823 */
824 ~FbxLayerElementArrayReadLock()
825 {
826 if( mLockedData )
827 {
828 mArray.Release((void **) &mLockedData);
829 }
830 }
831
832 /** \internal
833 * Retrieve the locked array data.
834 */
835 const T* GetData() const
836 {
837 return mLockedData;
838 }
839
840private:
841 FbxLayerElementArray& mArray;
842 T* mLockedData;
843};
844
845class FbxLayerElementUserData;
846
847/** FbxLayerElementArrayTemplate provides data array manipulation of the data buffer for FbxLayerElement.
848 * It is the subclass of FbxLayerElementArray.
849 * \nosubgrouping
850 */
851template <class T> class FbxLayerElementArrayTemplate : public FbxLayerElementArray
852{
853public:
854
855 /** Constructor
856 * \param pDataType The data type of the array items.
857 */
858 FbxLayerElementArrayTemplate(EFbxType pDataType) :
859 FbxLayerElementArray(pDataType)
860 {
861 }
862
863 /** Appends a new item to the end of the data buffer.
864 * \param pItem The new item to be added
865 * \return The index of the new item
866 */
867 inline int Add( T const &pItem ) { return FbxLayerElementArray::Add(pItem); }
868
869 /** Inserts a new item at the specified position of the data buffer.
870 * \param pIndex The specified position
871 * \param pItem The new item to be inserted
872 * \return The index of the inserted item
873 */
874 inline int InsertAt(int pIndex, T const &pItem) { return FbxLayerElementArray::InsertAt(pIndex, pItem); }
875
876 /** Sets the value of the specified item.
877 * \param pIndex The index of the item to be updated.
878 * \param pItem The item whose value is copied to pIndex'th item
879 */
880 inline void SetAt(int pIndex, T const &pItem) { FbxLayerElementArray::SetAt(pIndex, pItem); }
881
882 /** Sets the value of the last item.
883 * \param pItem The item whose value is copied to the last item
884 */
885 inline void SetLast( T const &pItem) { FbxLayerElementArray::SetLast(pItem); }
886
887 /** Removes the specified item from the data buffer.
888 * \param pIndex The index of the item to be removed
889 * \return The value of the item removed
890 */
891 inline T RemoveAt(int pIndex) { T lValue; FbxLayerElementArray::RemoveAt(pIndex, &lValue); return lValue; }
892
893 /** Removes the last item from the data buffer.
894 * \return The value of the last item removed
895 */
896 inline T RemoveLast() { T lValue; FbxLayerElementArray::RemoveLast(&lValue); return lValue; }
897
898 /** Removes one item from the data buffer.
899 * \param pItem The first item who equals pItem is to be removed
900 * \return \c True if the item is removed successfully, \c false otherwise
901 */
902 inline bool RemoveIt(T const &pItem) { return FbxLayerElementArray::RemoveIt(&pItem); }
903
904 /** Returns the specified item's value.
905 * \param pIndex Index of the item
906 * \return The value of the specified item
907 * \remarks If the index is invalid, pItem is set to zero.
908 */
909 inline T GetAt(int pIndex) const { T lValue; FbxLayerElementArray::GetAt(pIndex, &lValue); return lValue; }
910
911 /** Returns the first item's value.
912 * \return The first item's value.
913 */
914 inline T GetFirst() const { T lValue; FbxLayerElementArray::GetFirst(&lValue); return lValue; }
915
916 /** Returns the last item's value.
917 * \return The last item's value.
918 */
919 inline T GetLast() const { T lValue; FbxLayerElementArray::GetLast(&lValue); return lValue; }
920
921 /** Searches for an item in the data buffer.
922 * \param pItem The value of the item for which to search
923 * \return The index of the item found, -1 if not found.
924 * \remarks The index of the first item whose value equals pItem is returned.
925 */
926 inline int Find(T const &pItem) { return FbxLayerElementArray::Find(pItem); }
927
928 /** Searches for an item after the specified index in the data buffer.
929 * \param pAfterIndex The specified index after which the searching begins
930 * \param pItem The value of the item for which to search, the searching begins after pAfterIndex.
931 * \return The index of the item found, -1 if not found.
932 * \remarks The index of the first item whose value equals pItem is returned.
933 */
934 inline int FindAfter(int pAfterIndex, T const &pItem) { return FbxLayerElementArray::FindAfter(pAfterIndex, pItem); }
935
936 /** Searches for one item before the specified index in the data buffer.
937 * \param pBeforeIndex The specified index before which the searching begins
938 * \param pItem The value of the item for which to search, the searching begins before pBeforeIndex.
939 * \return The index of the item found, -1 if not found.
940 * \remarks The index of the first item whose value equals pItem is returned.
941 */
942 inline int FindBefore(int pBeforeIndex, T const &pItem) { return FbxLayerElementArray::FindBefore(pBeforeIndex, pItem); }
943
944 /** Returns the specified item's value.
945 * \param pIndex Index of the item
946 * \return The value of the item
947 * \remarks If the index is invalid, pItem is set to zero.
948 */
949 T operator[](int pIndex) const { T lValue; FbxLayerElementArray::GetAt(pIndex, &lValue); return lValue; }
950
951 /** Assignment operator.
952 * \param pArrayTemplate The source array whose items are copied to this array.
953 */
954 FbxLayerElementArray& operator=(const FbxArray<T>& pArrayTemplate)
955 {
956 SetStatus(LockAccessStatus::eNoWriteLock);
957 if (WriteLock())
958 {
959 SetCount(pArrayTemplate.GetCount());
960 for (int i = 0; i < pArrayTemplate.GetCount(); i++)
961 SetAt(i, pArrayTemplate.GetAt(i));
962 WriteUnlock();
963 SetStatus(LockAccessStatus::eSuccess);
964 }
965 return *this;
966 }
967
968 /** Assignment operator.
969 * \param pArrayTemplate The source array whose items are copied to this array.
970 */
971 FbxLayerElementArrayTemplate<T>& operator=(const FbxLayerElementArrayTemplate<T>& pArrayTemplate)
972 {
973 if ( this != &pArrayTemplate )
974 {
975 SetStatus(LockAccessStatus::eNoWriteLock);
976 if (WriteLock())
977 {
978 SetCount(pArrayTemplate.GetCount());
979 for (int i = 0; i < pArrayTemplate.GetCount(); i++)
980 SetAt(i, pArrayTemplate.GetAt(i));
981 WriteUnlock();
982 SetStatus(LockAccessStatus::eSuccess);
983 }
984 }
985 return *this;
986 }
987
988private:
989 // This one is not the best thing to do, but at least I don't get deprecated calls inside this file.
990 // Note that FbxLayerElementUserData is kind of a weird class in the first place anyway. So either
991 // we clean it up, or we live with this piece of code ;-)
992 friend class FbxLayerElementUserData;
993 T& AsReference(int pIndex) { T* v = (T*)FbxLayerElementArray::GetReference(pIndex, mDataType); return (v)?*v:dummy;}
994
995 T dummy;
996};
997
998
999/** Remap the index array to a new EMappingMode
1000 * \param pLayerEl The layer element to remap
1001 * \param pNewMapping The new mapping mode
1002 * \param pIndexArray The index array to modify
1003 * \return return -1 if the layer element is FbxLayerElement::eDirect
1004 * 0 if layer element or index array is \c NULL and 1 if the remap is successful
1005 */
1006extern FBXSDK_DLL int RemapIndexArrayTo(FbxLayerElement* pLayerEl,
1007 FbxLayerElement::EMappingMode pNewMapping,
1008 FbxLayerElementArrayTemplate<int>* pIndexArray);
1009
1010
1011/** This class complements the FbxLayerElement class.
1012 * It provides interfaces to access the direct array and index array of different layer elements.
1013 * \nosubgrouping
1014 */
1015template <class Type> class FbxLayerElementTemplate : public FbxLayerElement
1016{
1017public:
1018
1019 /** Returns the direct array of Layer Elements.
1020 * \return A reference to the Layer Elements direct array.
1021 * \remarks You cannot put elements in the direct array when the reference mode is set to eIndex.
1022 */
1023 FbxLayerElementArrayTemplate<Type>& GetDirectArray() const
1024 {
1025 FBX_ASSERT(mReferenceMode == FbxLayerElement::eDirect || mReferenceMode == FbxLayerElement::eIndexToDirect);
1026 return *mDirectArray;
1027 }
1028
1029 /** Returns the direct array of Layer Elements.
1030 * \return A reference to the Layer Elements direct array.
1031 * \remarks You cannot put elements in the direct array when the reference mode is set to eIndex.
1032 */
1033 FbxLayerElementArrayTemplate<Type>& GetDirectArray()
1034 {
1035 FBX_ASSERT(mReferenceMode == FbxLayerElement::eDirect || mReferenceMode == FbxLayerElement::eIndexToDirect);
1036 return *mDirectArray;
1037 }
1038
1039 /** Returns the index array of Layer Elements.
1040 * \return A reference to the index array.
1041 * \remarks You cannot put elements in the index array when the mapping mode is set to eDirect.
1042 */
1043 FbxLayerElementArrayTemplate<int>& GetIndexArray() const
1044 {
1045 FBX_ASSERT(mReferenceMode == FbxLayerElement::eIndex || mReferenceMode == FbxLayerElement::eIndexToDirect);
1046 return *mIndexArray;
1047 }
1048
1049 /** Returns the index array of Layer Elements.
1050 * \return A reference to the index array.
1051 * \remarks You cannot put elements in the index array when the mapping mode is set to eDirect.
1052 */
1053 FbxLayerElementArrayTemplate<int>& GetIndexArray()
1054 {
1055 FBX_ASSERT(mReferenceMode == FbxLayerElement::eIndex || mReferenceMode == FbxLayerElement::eIndexToDirect);
1056 return *mIndexArray;
1057 }
1058
1059 /** Removes all elements from the direct and the index arrays.
1060 * \remarks This function fails if there is a lock on the arrays.
1061 * \return \c True if successful, \c false if a lock is present.
1062 */
1063 bool Clear()
1064 {
1065 bool ret = true;
1066 mDirectArray->Clear();
1067 ret = (mDirectArray->GetStatus() == LockAccessStatus::eSuccess);
1068
1069 mIndexArray->Clear();
1070 ret |= (mIndexArray->GetStatus() == LockAccessStatus::eSuccess);
1071
1072 return ret;
1073 }
1074
1075public:
1076
1077 /** Equivalence operator.
1078 * \param pOther Another element compared to this object
1079 * \return \c True if equal, \c false if unequal.
1080 */
1081 bool operator==(const FbxLayerElementTemplate& pOther) const
1082 {
1083 bool ret = true;
1084
1085 if (pOther.GetReferenceMode() == FbxLayerElement::eDirect ||
1086 pOther.GetReferenceMode() == FbxLayerElement::eIndexToDirect)
1087 {
1088 const FbxLayerElementArrayTemplate<Type>& directArray = pOther.GetDirectArray();
1089 if( directArray.GetCount() != mDirectArray->GetCount() ||
1090 !directArray.ReadLock() || !mDirectArray->ReadLock() )
1091 {
1092 ret = false;
1093 }
1094
1095 if( ret && !mDirectArray->IsEqual(directArray) )
1096 ret = false;
1097
1098 directArray.ReadUnlock();
1099 mDirectArray->ReadUnlock();
1100 }
1101
1102 if (ret)
1103 {
1104 if (pOther.GetReferenceMode() == FbxLayerElement::eIndex ||
1105 pOther.GetReferenceMode() == FbxLayerElement::eIndexToDirect)
1106 {
1107 const FbxLayerElementArrayTemplate<int>& indexArray = pOther.GetIndexArray();
1108 if( indexArray.GetCount() != mIndexArray->GetCount() ||
1109 !indexArray.ReadLock() || !mIndexArray->ReadLock() )
1110 {
1111 ret = false;
1112 }
1113
1114 if( ret && !mIndexArray->IsEqual(indexArray) )
1115 ret = false;
1116
1117 indexArray.ReadUnlock();
1118 mIndexArray->ReadUnlock();
1119 }
1120 }
1121
1122 if (ret == false)
1123 return false;
1124
1125 return FbxLayerElement::operator==(pOther);
1126 }
1127
1128 /** Assignment operator.
1129 * \param pOther Another element assigned to this one
1130 */
1131 FbxLayerElementTemplate& operator=( FbxLayerElementTemplate const& pOther )
1132 {
1133 FBX_ASSERT(mDirectArray != NULL);
1134 FBX_ASSERT(mIndexArray != NULL);
1135
1136 if (pOther.GetReferenceMode() == FbxLayerElement::eDirect ||
1137 pOther.GetReferenceMode() == FbxLayerElement::eIndexToDirect)
1138 {
1139 const FbxLayerElementArrayTemplate<Type>& directArray = pOther.GetDirectArray();
1140 *mDirectArray = directArray;
1141 }
1142
1143 if (pOther.GetReferenceMode() == FbxLayerElement::eIndex ||
1144 pOther.GetReferenceMode() == FbxLayerElement::eIndexToDirect)
1145 {
1146 const FbxLayerElementArrayTemplate<int>& indexArray = pOther.GetIndexArray();
1147 *mIndexArray = indexArray;
1148 }
1149
1150 FbxLayerElement* myself = (FbxLayerElement*)this;
1151 FbxLayerElement* myOther = (FbxLayerElement*)&pOther;
1152 *myself = *myOther;
1153 return *this;
1154 }
1155
1156 /** Changes the Mapping mode to the new one and re-computes the index array.
1157 * \param pNewMapping New mapping mode.
1158 * \return If the remapping is successful, returns 1.
1159 * If an error occurs, returns 0. In case the function cannot
1160 * remap to the desired mode because of incompatible modes or
1161 * unsupported modes, returns -1.
1162 */
1163 int RemapIndexTo(FbxLayerElement::EMappingMode pNewMapping)
1164 {
1165 return RemapIndexArrayTo(this, pNewMapping, mIndexArray);
1166 }
1167
1168/*****************************************************************************************************************************
1169** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
1170*****************************************************************************************************************************/
1171#ifndef DOXYGEN_SHOULD_SKIP_THIS
1172protected:
1173 FbxLayerElementTemplate()
1174 {
1175 mDirectArray = NULL;
1176 mIndexArray = NULL;
1177 }
1178
1179 ~FbxLayerElementTemplate()
1180 {
1181 FbxDelete(mDirectArray);
1182 FbxDelete(mIndexArray);
1183 }
1184
1185 virtual void AllocateArrays()
1186 {
1187 mDirectArray = FbxNew< FbxLayerElementArrayTemplate<Type> >(mType->GetType());
1188 mIndexArray = FbxNew< FbxLayerElementArrayTemplate<int> >(FbxIntDT.GetType());
1189 }
1190
1191public:
1192 virtual int MemorySize() const
1193 {
1194 int size = FbxLayerElement::MemorySize();
1195 size += (mDirectArray->GetCount()*sizeof(Type));
1196 size += (mIndexArray->GetCount()*sizeof(int));
1197 return size;
1198 }
1199
1200 /**
1201 * \name Serialization section
1202 */
1203 //@{
1204 virtual bool ContentWriteTo(FbxStream& pStream) const
1205 {
1206 void* a;
1207 int s,v;
1208 int count = 0;
1209
1210 // direct array
1211 count = mDirectArray->GetCount();
1212 s = pStream.Write(&count, sizeof(int));
1213 if (s != sizeof(int)) return false;
1214 if (count > 0)
1215 {
1216 a = mDirectArray->GetLocked();
1217 FBX_ASSERT(a != NULL);
1218 v = count*sizeof(Type);
1219 s = pStream.Write(a, v);
1220 mDirectArray->Release(&a);
1221 if (s != v) return false;
1222 }
1223
1224 // index array
1225 count = mIndexArray->GetCount();
1226 s = pStream.Write(&count, sizeof(int));
1227 if (s != sizeof(int)) return false;
1228 if (count > 0)
1229 {
1230 a = mIndexArray->GetLocked();
1231 FBX_ASSERT(a != NULL);
1232 v = count*sizeof(int);
1233 s = pStream.Write(a, v);
1234 mIndexArray->Release(&a);
1235 if (s != v) return false;
1236 }
1237
1238 return FbxLayerElement::ContentWriteTo(pStream);
1239 }
1240
1241 virtual bool ContentReadFrom(const FbxStream& pStream)
1242 {
1243 void* a;
1244 int s,v;
1245 int count = 0;
1246
1247 // direct array
1248 s = pStream.Read(&count, sizeof(int));
1249 if (s != sizeof(int)) return false;
1250 mDirectArray->Resize(count);
1251 if (count > 0)
1252 {
1253 a = mDirectArray->GetLocked();
1254 FBX_ASSERT(a != NULL);
1255 v = count*sizeof(Type);
1256 s = pStream.Read(a, v);
1257 mDirectArray->Release(&a);
1258 if (s != v) return false;
1259 }
1260
1261 // index array
1262 s = pStream.Read(&count, sizeof(int));
1263 if (s != sizeof(int)) return false;
1264 mIndexArray->Resize(count);
1265 if (count > 0)
1266 {
1267 a = mIndexArray->GetLocked();
1268 FBX_ASSERT(a != NULL);
1269 v = count*sizeof(int);
1270 s = pStream.Read(a, v);
1271 mIndexArray->Release(&a);
1272 if (s != v) return false;
1273 }
1274 return FbxLayerElement::ContentReadFrom(pStream);
1275 }
1276 //@}
1277
1278 typedef Type ArrayElementType;
1279 typedef FbxLayerElementArrayTemplate<Type> DirectArrayType;
1280 typedef FbxLayerElementArrayTemplate<int> IndexArrayType;
1281
1282 FbxLayerElementArrayTemplate<Type>* mDirectArray;
1283 FbxLayerElementArrayTemplate<int>* mIndexArray;
1284#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
1285};
1286
1287#define FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(classDesc) \
1288 FBXSDK_FRIEND_NEW(); \
1289 static Fbx##classDesc* Create(FbxLayerContainer* pOwner, const char* pName);
1290
1291/** \brief Layer element for mapping Normals to a geometry.
1292 * \remarks To be correctly saved in FBX file, this type of Layer element should have its reference
1293 * mode set to \e eIndexToDirect.
1294 * \nosubgrouping
1295 */
1296class FBXSDK_DLL FbxLayerElementNormal : public FbxLayerElementTemplate<FbxVector4>
1297{
1298public:
1299
1300 /** Allocation method.
1301 * \return A pointer to the layer element or \c NULL if creation fails.
1302 */
1303 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementNormal);
1304
1305protected:
1306 FbxLayerElementNormal();
1307 ~FbxLayerElementNormal();
1308};
1309
1310/** \brief Layer element for mapping Binormals to a geometry.
1311 * \nosubgrouping
1312 */
1313class FBXSDK_DLL FbxLayerElementBinormal : public FbxLayerElementTemplate<FbxVector4>
1314{
1315public:
1316
1317 /** Allocation method.
1318 * \return A pointer to the layer element or \c NULL if creation fails.
1319 */
1320 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementBinormal);
1321
1322protected:
1323 FbxLayerElementBinormal();
1324 ~FbxLayerElementBinormal();
1325};
1326
1327/** \brief Layer element for mapping Tangents to a geometry.
1328 * \nosubgrouping
1329 */
1330class FBXSDK_DLL FbxLayerElementTangent : public FbxLayerElementTemplate<FbxVector4>
1331{
1332public:
1333
1334 /** Allocation method.
1335 * \return A pointer to the layer element or \c NULL if creation fails.
1336 */
1337 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementTangent);
1338
1339protected:
1340 FbxLayerElementTangent();
1341 ~FbxLayerElementTangent();
1342};
1343
1344/** Layer element for mapping materials (FbxSurfaceMaterial) to a geometry.
1345 *
1346 * FBX SDK 2011 and later connects materials (FbxSurfaceMaterial) to nodes (FbxNode).
1347 * The direct array of this class is no longer used.
1348 * The integer "n" in the index array of this class represents the n-th material (zero-based) connected to the node.
1349 *
1350 * For example:
1351 *
1352 * Mapping mode eAllSame and index array {0} means the whole geometry is assigned with the 0-th material
1353 * connected to the node.
1354 *
1355 * Mapping mode eByPolygon and index array {0, 1} means the first polygon is assigned with the 0-th material and
1356 * the second polygon is assigned with the 1-th material.
1357 *
1358 *
1359 * You can access the materials from a node by using FbxNode::GetMaterialCount() and FbxNode::GetMaterial(int pIndex)
1360 * or the more generic calls to GetSrcObjectCount<FbxSurfaceMaterial>() and
1361 * GetSrcObject<FbxSurfaceMaterial>(index)
1362 *
1363 * For example:
1364 *
1365 * \code
1366 * FbxNode* node;
1367 * int nbMat = node->GetMaterialCount();
1368 * int nbMat1= node->GetSrcObjectCount<FbxSurfaceMaterial>();
1369 *
1370 * FbxSurfaceMaterial* material;
1371 * FbxLayerElementMaterial* layerElement;
1372 * if (layerElement->GetMappingMode() == FbxLayerElement::eAllSame)
1373 * {
1374 * int index = layerElement->GetIndexArray()[0];
1375 * material = node->GetMaterial(index);
1376 * }
1377 * \endcode
1378 *
1379 * \remarks
1380 * The DirectArray() methods still exist for legacy reasons but has been made private and should not be used.
1381 * Therefore, to be correctly saved in FBX file, this type of Layer element should have its reference
1382 * mode set to \e eIndexToDirect.
1383 *
1384 * \see FbxSurfaceMaterial
1385 * \see FbxNode
1386 */
1387class FBXSDK_DLL FbxLayerElementMaterial : public FbxLayerElementTemplate<FbxSurfaceMaterial*>
1388{
1389public:
1390 typedef FbxLayerElementTemplate<FbxSurfaceMaterial*> ParentClass;
1391
1392 /** Allocation method.
1393 * \return A pointer to the layer element or \c NULL if creation fails.
1394 */
1395 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementMaterial);
1396
1397 /** \internal
1398 * Internal class to maintain backward compatibility with old FBX code (prior to FBX SDK 2011).
1399 * This class synchronizes the direct array with FbxNode connections.
1400 * Thus, changes on the direct array will reflect on FbxNode.
1401 */
1402 class LayerElementArrayProxy : public FbxLayerElementArrayTemplate<FbxSurfaceMaterial*>
1403 {
1404 public:
1405 typedef FbxLayerElementArrayTemplate<FbxSurfaceMaterial*> ParentClass;
1406
1407 LayerElementArrayProxy(EFbxType pType);
1408 void SetContainer( FbxLayerContainer* pContainer, int pInstance = 0);
1409 };
1410
1411/*****************************************************************************************************************************
1412** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
1413*****************************************************************************************************************************/
1414#ifndef DOXYGEN_SHOULD_SKIP_THIS
1415 virtual void AllocateArrays();
1416 virtual void SetOwner( FbxLayerContainer* pOwner, int pInstance = 0);
1417 virtual void SetInstance( int pInstance ) { SetOwner( mOwner, pInstance ); }
1418
1419protected:
1420 FbxLayerElementMaterial();
1421 ~FbxLayerElementMaterial();
1422
1423private:
1424 FbxLayerElementArrayTemplate<FbxSurfaceMaterial*>& GetDirectArray() const
1425 {
1426 return ParentClass::GetDirectArray();
1427 }
1428
1429 FbxLayerElementArrayTemplate<FbxSurfaceMaterial*>& GetDirectArray()
1430 {
1431 return ParentClass::GetDirectArray();
1432 }
1433
1434 friend class FbxLayerContainer;
1435#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
1436};
1437
1438/** \brief Layer element for grouping related polygons together.
1439 * \remarks To be correctly saved in FBX file, this type of Layer element should have its reference
1440 * mode set to \e eIndexToDirect.
1441 * \nosubgrouping
1442 */
1443class FBXSDK_DLL FbxLayerElementPolygonGroup : public FbxLayerElementTemplate<int>
1444{
1445public:
1446
1447 /** Allocation method.
1448 * \return A pointer to the layer element or \c NULL if creation fails.
1449 */
1450 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementPolygonGroup);
1451
1452protected:
1453 FbxLayerElementPolygonGroup();
1454 ~FbxLayerElementPolygonGroup();
1455};
1456
1457/** \brief Layer element for mapping UVs to a geometry.
1458 *
1459 * This class represents a UV set belongs to a geometry. Each UV set in a geometry
1460 * has a name to identify itself. The string property FbxTexture.UVSet indicates
1461 * the UV set to use.
1462 *
1463 * \remarks if the Mapping mode of this LayerElement is \e eNone, the stored data
1464 * should be treated as irrelevant. In some circumstances, you can still send this data
1465 * to systems that cannot function without UV coordinates, but ensure
1466 * that you have enough coordinates to do so.
1467 *
1468 * \see FbxTexture
1469 * \nosubgrouping
1470 */
1471class FBXSDK_DLL FbxLayerElementUV : public FbxLayerElementTemplate<FbxVector2>
1472{
1473public:
1474 /** Allocation method.
1475 * \return A pointer to the layer element or \c NULL if creation fails.
1476 */
1477 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementUV);
1478
1479protected:
1480 FbxLayerElementUV();
1481 ~FbxLayerElementUV();
1482};
1483
1484/** \brief Layer element for mapping Vertex Colors to a geometry.
1485 * \nosubgrouping
1486 */
1487class FBXSDK_DLL FbxLayerElementVertexColor : public FbxLayerElementTemplate<FbxColor>
1488{
1489public:
1490
1491 /** Allocation method.
1492 * \return A pointer to the layer element or \c NULL if creation fails.
1493 */
1494 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementVertexColor);
1495
1496protected:
1497 FbxLayerElementVertexColor();
1498 ~FbxLayerElementVertexColor();
1499};
1500
1501template <class T> inline FbxLayerElementArrayTemplate<T>& FbxGetDirectArray(FbxLayerElementUserData *pLayerElement, int pIndex, bool* pStatus = NULL);
1502template <class T> inline FbxLayerElementArrayTemplate<T> const& FbxGetDirectArray(FbxLayerElementUserData const *pLayerElement, int pIndex, bool* pStatus = NULL);
1503template <class T> inline FbxLayerElementArrayTemplate<T>& FbxGetDirectArray(FbxLayerElementUserData *pLayerElement, const char* pName, bool* pStatus = NULL );
1504template <class T> inline FbxLayerElementArrayTemplate<T> const& FbxGetDirectArray(FbxLayerElementUserData const *pLayerElement, const char* pName, bool* pStatus = NULL );
1505
1506/** \brief Layer element for mapping custom user data to a geometry.
1507 * This layer element is different from the other types of layer elements in that it has multiple direct arrays. There is one array for each user data attribute.
1508 * Each array is indexed by the index array.
1509 * \nosubgrouping
1510 */
1511class FBXSDK_DLL FbxLayerElementUserData : public FbxLayerElementTemplate<void*>
1512{
1513public:
1514 FBXSDK_FRIEND_NEW();
1515
1516 /** Allocation method.
1517 * \param pOwner The owner of this layer element.
1518 * \param pName The layer element name.
1519 * \param pId The layer element ID.
1520 * \param pDataTypes Attribute data types of this layer element, one direct array is allocated for each Attribute data type.
1521 * \param pDataNames Attribute names of this layer element.
1522 * \return A pointer to the layer element or \c NULL if creation fails.
1523 * \remarks Only "bool", "int", "float" and "double" are supported.
1524 */
1525 static FbxLayerElementUserData* Create(FbxLayerContainer* pOwner, const char* pName, int pId, FbxArray<FbxDataType>& pDataTypes, FbxArray<const char*>& pDataNames);
1526
1527 /** Allocation method.
1528 * \param pOwner The owner of this layer element.
1529 * \param pOther Other layer element from which to copy.
1530 * \return A pointer to the layer element or \c NULL if creation fails.
1531 */
1532 static FbxLayerElementUserData* Create(FbxLayerContainer* pOwner, FbxLayerElementUserData const& pOther );
1533
1534 /** Returns the direct array with the specified attribute index.
1535 * \param pIndex Specified attribute index.
1536 * \param pStatus A flag to indicate whether the direct array is returned successfully or not.
1537 * \return The specified attribute's direct array.
1538 */
1539 FbxLayerElementArrayTemplate<void*>* GetDirectArrayVoid( int pIndex, bool* pStatus = NULL)
1540 {
1541 if( pIndex >= 0 || pIndex < GetDirectArray().GetCount() )
1542 {
1543 if (pStatus) *pStatus = true;
1544 return (FbxLayerElementArrayTemplate<void*>*)GetDirectArray().AsReference(pIndex);
1545 }
1546 else
1547 {
1548 if( pStatus ) *pStatus = false;
1549 FBX_ASSERT_NOW("Index out of bounds");
1550 return (FbxLayerElementArrayTemplate<void*>*)NULL;
1551 }
1552 }
1553
1554 /** Returns the direct array with the specified attribute index.
1555 * \param pIndex Specified attribute index.
1556 * \param pStatus A flag to indicate whether the direct array is returned successfully or not.
1557 * \return The specified attribute's direct array.
1558 */
1559 const FbxLayerElementArrayTemplate<void*>* GetDirectArrayVoid( int pIndex, bool* pStatus = NULL) const
1560 {
1561 if( pIndex >= 0 || pIndex < GetDirectArray().GetCount() )
1562 {
1563 if (pStatus) *pStatus = true;
1564 return (FbxLayerElementArrayTemplate<void*>*)GetDirectArray().AsReference(pIndex);
1565 }
1566 else
1567 {
1568 if( pStatus ) *pStatus = false;
1569 FBX_ASSERT_NOW("Index out of bounds");
1570 return (const FbxLayerElementArrayTemplate<void*>*)NULL;
1571 }
1572 }
1573
1574
1575 /** Returns the direct array with the specified attribute name.
1576 * \param pName Specified attribute name.
1577 * \param pStatus A flag to indicate whether the direct array is returned successfully or not.
1578 * \return The specified attribute's direct array.
1579 */
1580 FbxLayerElementArrayTemplate<void *>* GetDirectArrayVoid ( const char* pName, bool* pStatus = NULL )
1581 {
1582 FbxString lName( pName );
1583 for( int i = 0; i < mDataNames.GetCount(); ++i )
1584 {
1585 if( *mDataNames[i] == lName )
1586 return GetDirectArrayVoid(i, pStatus);
1587 }
1588
1589 if (pStatus) *pStatus = false;
1590 return (FbxLayerElementArrayTemplate<void *>*)NULL;
1591 }
1592
1593 /** Returns the direct array with the specified attribute name.
1594 * \param pName Specified attribute name.
1595 * \param pStatus A flag to indicate whether the direct array is returned successfully or not.
1596 * \return The specified attribute's direct array.
1597 */
1598 const FbxLayerElementArrayTemplate<void*>* GetDirectArrayVoid ( const char* pName, bool* pStatus = NULL ) const
1599 {
1600 FbxString lName( pName );
1601 for( int i = 0; i < mDataNames.GetCount(); ++i )
1602 {
1603 if( *mDataNames[i] == lName )
1604 return GetDirectArrayVoid(i, pStatus);
1605 }
1606
1607 if (pStatus) *pStatus = false;
1608 return (const FbxLayerElementArrayTemplate<void*>*)NULL;
1609 }
1610
1611 /** Returns the data type for the specified index
1612 * \param pIndex The index of the attribute being queried
1613 * \return The data type, or FbxUndefinedDT if pIndex is out of range
1614 */
1615 FbxDataType GetDataType( int pIndex ) const
1616 {
1617 if( pIndex < 0 || pIndex >= mDataTypes.GetCount() )
1618 return FbxUndefinedDT;
1619
1620 return mDataTypes[pIndex];
1621 }
1622
1623 /** Returns the specified attribute data type.
1624 * \param pName The name of the attribute being queried
1625 * \return The data type, or FbxUndefinedDT if no attribute has the given name
1626 */
1627 FbxDataType GetDataType( const char* pName ) const
1628 {
1629 FbxString lName( pName );
1630
1631 for( int i = 0; i < mDataNames.GetCount(); ++i )
1632 {
1633 if( *mDataNames[i] == lName )
1634 return mDataTypes[i];
1635 }
1636
1637 return FbxUndefinedDT;
1638 }
1639
1640 /** Returns the attribute name at the specified index
1641 * \param pIndex Attribute index
1642 * \return The name, or \c NULL if pIndex is out of range.
1643 */
1644 const char* GetDataName( int pIndex ) const
1645 {
1646 if( pIndex >= 0 && pIndex < mDataNames.GetCount() )
1647 return mDataNames[pIndex]->Buffer();
1648
1649 return NULL;
1650 }
1651
1652 /** Resizes all direct arrays to the specified size.
1653 * \param pSize The new size of the direct arrays.
1654 */
1655 void ResizeAllDirectArrays( int pSize )
1656 {
1657 for( int i = 0; i < GetDirectArray().GetCount(); ++i )
1658 {
1659 switch( mDataTypes[i].GetType() )
1660 {
1661 case eFbxBool: FbxGetDirectArray<bool>(this,i).Resize( pSize ) ; break;
1662 case eFbxInt: FbxGetDirectArray<int>(this,i).Resize( pSize ) ; break;
1663 case eFbxFloat: FbxGetDirectArray<float>(this,i).Resize( pSize ) ; break;
1664 case eFbxDouble: FbxGetDirectArray<double>(this,i).Resize( pSize ); break;
1665 //case eFbxDouble3: GetDirectArray< FbxDouble3 >(i).Resize( pSize ); break;
1666 //case eFbxDouble4: GetDirectArray< FbxDouble4 >(i).Resize( pSize ); break;
1667 //case eFbxDouble4x4: GetDirectArray< FbxDouble4x4>(i).Resize( pSize ); break;
1668 default:
1669 FBX_ASSERT_NOW("unknown type" ); break;
1670 }
1671 }
1672 }
1673
1674 /** Removes a single element at pIndex from every direct array.
1675 * \param pIndex The index of the element to be removed.
1676 */
1677 void RemoveFromAllDirectArrays( int pIndex )
1678 {
1679 for( int i = 0; i < GetDirectArray().GetCount(); ++i )
1680 {
1681 switch( mDataTypes[i].GetType() )
1682 {
1683 case eFbxBool: FbxGetDirectArray<bool>(this,i).RemoveAt( pIndex ) ; break;
1684 case eFbxInt: FbxGetDirectArray<int>(this,i).RemoveAt( pIndex ) ; break;
1685 case eFbxFloat: FbxGetDirectArray<float>(this,i).RemoveAt( pIndex ) ; break;
1686 case eFbxDouble: FbxGetDirectArray<double>(this,i).RemoveAt( pIndex ); break;
1687 //case eFbxDouble3: GetDirectArray< FbxDouble3 >(i).RemoveAt( pIndex ); break;
1688 //case eFbxDouble4: GetDirectArray< FbxDouble4 >(i).RemoveAt( pIndex ); break;
1689 //case eFbxDouble4x4: GetDirectArray< FbxDouble4x4>(i).RemoveAt( pIndex ); break;
1690 default:
1691 FBX_ASSERT_NOW("unknown type" ); break;
1692 }
1693 }
1694 }
1695
1696 /** Returns the direct array count for the attribute at pIndex
1697 * \param pIndex The attribute index
1698 * \return The specified attribute's direct array count.
1699 */
1700 int GetArrayCount( int pIndex ) const
1701 {
1702 if( pIndex >= 0 && pIndex < GetDirectArray().GetCount() )
1703 {
1704 switch( mDataTypes[pIndex].GetType() )
1705 {
1706 case eFbxBool: return FbxGetDirectArray<bool>(this,pIndex).GetCount();
1707 case eFbxInt: return FbxGetDirectArray<int>(this,pIndex).GetCount();
1708 case eFbxFloat: return FbxGetDirectArray<float>(this,pIndex).GetCount();
1709 case eFbxDouble: return FbxGetDirectArray<double>(this,pIndex).GetCount();
1710 //case eFbxDouble3: return GetDirectArray< FbxDouble3 >(pIndex).GetCount();
1711 //case eFbxDouble4: return GetDirectArray< FbxDouble4 >(pIndex).GetCount();
1712 //case eFbxDouble4x4: return GetDirectArray< FbxDouble4x4>(pIndex).GetCount();
1713 default:
1714 FBX_ASSERT_NOW("Unknown type" ); break;
1715 }
1716 }
1717
1718 return -1;
1719 }
1720
1721 /** Queries the this layer element's ID.
1722 * \return The ID expressed as an int
1723 */
1724 int GetId() const { return mId; }
1725
1726 /** Returns this layer element's direct array count.
1727 * \return The direct array count expressed as an int.
1728 * \remarks This count should be equal to the count of user data attributes.
1729 */
1730 int GetDirectArrayCount() const { return GetDirectArray().GetCount(); }
1731
1732 /** Assignment operator which performs a deep copy.
1733 * \param pOther Other FbxLayerElementUserData from which to perform a deep copy.
1734 * \return This FbxLayerElementUserData.
1735 */
1736 FbxLayerElementUserData& operator=( FbxLayerElementUserData const& pOther )
1737 {
1738 if (this == &pOther)
1739 return *this;
1740
1741 Clear();
1742
1743 mId = pOther.mId;
1744 mDataTypes = pOther.mDataTypes;
1745 mDataNames.Resize(pOther.mDataNames.GetCount());
1746 for(int i = 0; i < pOther.mDataNames.GetCount(); ++i)
1747 mDataNames.SetAt(i, FbxNew< FbxString >( *pOther.mDataNames[i] ) );
1748
1749 Init();
1750 for(int i = 0; i < pOther.GetDirectArrayCount(); ++i)
1751 {
1752 switch (mDataTypes[i].GetType())
1753 {
1754 case eFbxBool:
1755 FbxGetDirectArray<bool>(this, i) = FbxGetDirectArray<bool>(&pOther, i);
1756 break;
1757
1758 case eFbxInt:
1759 FbxGetDirectArray<int>(this, i) = FbxGetDirectArray<int>(&pOther, i);
1760 break;
1761
1762 case eFbxFloat:
1763 FbxGetDirectArray<float>(this, i) = FbxGetDirectArray<float>(&pOther, i);
1764 break;
1765
1766 case eFbxDouble:
1767 FbxGetDirectArray<double>(this, i) = FbxGetDirectArray<double>(&pOther, i);
1768 break;
1769
1770 default:
1771 FBX_ASSERT_NOW("Unknown type" );
1772 break;
1773 }
1774 }
1775
1776 if ( ( mReferenceMode == FbxLayerElement::eIndex ||
1777 mReferenceMode == FbxLayerElement::eIndexToDirect) &&
1778 ( pOther.GetReferenceMode() == FbxLayerElement::eIndex ||
1779 pOther.GetReferenceMode() == FbxLayerElement::eIndexToDirect))
1780 {
1781 GetIndexArray() = pOther.GetIndexArray();
1782 }
1783
1784 return *this;
1785 }
1786
1787 /** Removes all data from this layer element.
1788 * \return \c True always
1789 */
1790 bool Clear()
1791 {
1792 int i;
1793 const int lCount = GetDirectArray().GetCount();
1794 FbxLayerElementArray** directArray = NULL;
1795 directArray = GetDirectArray().GetLocked(directArray);
1796 for( i = 0; directArray != NULL && i < lCount; ++i )
1797 {
1798 if( directArray[i] )
1799 FbxDelete(directArray[i]);
1800 }
1801 FbxLayerElementArray*** ptr = &directArray;
1802 GetDirectArray().Release((void**)ptr);
1803 for( i = 0; i < mDataNames.GetCount(); ++i )
1804 {
1805 FBX_SAFE_DELETE(mDataNames[i]);
1806 }
1807 mDataNames.Clear();
1808 mDataTypes.Clear();
1809
1810 FbxLayerElementTemplate<void*>::Clear();
1811
1812 return true;
1813 }
1814
1815 /** Queries the amount of memory used by this
1816 * object as well as its content. It does not consider the content pointed.
1817 * \return The amount of memory used.
1818 */
1819 virtual int MemorySize() const
1820 {
1821 int size = FbxLayerElementTemplate<void*>::MemorySize();
1822 size += sizeof(mId);
1823
1824 for(int i = 0; i < mDataTypes.GetCount(); i++)
1825 {
1826 size += sizeof(mDataTypes[i]);
1827 }
1828 size += (mDataNames.GetCount() * sizeof(FbxString*));
1829
1830 return size;
1831 }
1832
1833/*****************************************************************************************************************************
1834** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
1835*****************************************************************************************************************************/
1836#ifndef DOXYGEN_SHOULD_SKIP_THIS
1837protected:
1838 /**
1839 * \name Constructor and Destructor.
1840 */
1841 //@{
1842 /** Constructs a user data layer element.
1843 * \param pId An identifier for this UserData layer element
1844 * \param pDataTypes Attribute data types for this layer element
1845 * \param pDataNames Attribute names for this layer element
1846 */
1847 FbxLayerElementUserData( int pId, FbxArray<FbxDataType>& pDataTypes, FbxArray<const char*>& pDataNames )
1848 :
1849 mId( pId ),
1850 mDataTypes( pDataTypes )
1851 {
1852 FBX_ASSERT( pDataTypes.GetCount() == pDataNames.GetCount() );
1853 for( int i = 0; i < pDataNames.GetCount(); ++i )
1854 {
1855 mDataNames.Add( FbxNew< FbxString >( pDataNames[i] ) );
1856 }
1857 }
1858
1859 /** Copy constructor. A deep copy is made.
1860 * \param pOther Another FbxLayerElementUserData object to be copied.
1861 */
1862 FbxLayerElementUserData( FbxLayerElementUserData const& pOther ) : mId(pOther.mId), mDataTypes(pOther.mDataTypes)
1863 {
1864 for (int lIndex = 0; lIndex < pOther.mDataNames.GetCount(); ++lIndex)
1865 {
1866 mDataNames.Add(FbxNew<FbxString>(*(pOther.mDataNames[lIndex])));
1867 }
1868
1869 SetType(&FbxLayerElementUserDataDT);
1870 AllocateArrays();
1871
1872 for(int i = 0; i < pOther.GetDirectArrayCount(); ++i)
1873 {
1874 switch (mDataTypes[i].GetType())
1875 {
1876 case eFbxBool:
1877 FbxGetDirectArray<bool>(this, i) = FbxGetDirectArray<bool>(&pOther, i);
1878 break;
1879
1880 case eFbxInt:
1881 FbxGetDirectArray<int>(this, i) = FbxGetDirectArray<int>(&pOther, i);
1882 break;
1883
1884 case eFbxFloat:
1885 FbxGetDirectArray<float>(this, i) = FbxGetDirectArray<float>(&pOther, i);
1886 break;
1887
1888 case eFbxDouble:
1889 FbxGetDirectArray<double>(this, i) = FbxGetDirectArray<double>(&pOther, i);
1890 break;
1891
1892 default:
1893 FBX_ASSERT_NOW("Unknown type" );
1894 break;
1895 }
1896 }
1897
1898 if ( ( mReferenceMode == FbxLayerElement::eIndex ||
1899 mReferenceMode == FbxLayerElement::eIndexToDirect) &&
1900 ( pOther.GetReferenceMode() == FbxLayerElement::eIndex ||
1901 pOther.GetReferenceMode() == FbxLayerElement::eIndexToDirect))
1902 {
1903 GetIndexArray() = pOther.GetIndexArray();
1904 }
1905 }
1906
1907 //!Destructor.
1908 ~FbxLayerElementUserData()
1909 {
1910 Clear();
1911 }
1912
1913 //@}
1914 virtual void AllocateArrays()
1915 {
1916 FbxLayerElementTemplate<void*>::AllocateArrays();
1917 Init();
1918 }
1919
1920
1921private:
1922
1923 void Init()
1924 {
1925 int i;
1926 GetDirectArray().Resize( mDataTypes.GetCount() );
1927
1928 // initialize arrays
1929 for( i = 0; i < mDataTypes.GetCount(); ++i )
1930 {
1931 FbxHandle** dst = NULL;
1932 dst = GetDirectArray().GetLocked(dst);
1933 if (dst)
1934 {
1935 switch( mDataTypes[i].GetType() )
1936 {
1937 case eFbxBool: dst[i] = (FbxHandle*)FbxNew< FbxLayerElementArrayTemplate<bool> >(mDataTypes[i].GetType()); break;
1938 case eFbxInt: dst[i] = (FbxHandle*)FbxNew< FbxLayerElementArrayTemplate<int> >(mDataTypes[i].GetType()); break;
1939 case eFbxFloat: dst[i] = (FbxHandle*)FbxNew< FbxLayerElementArrayTemplate<float> >(mDataTypes[i].GetType()); break;
1940 case eFbxDouble: dst[i] = (FbxHandle*)FbxNew< FbxLayerElementArrayTemplate<double> >(mDataTypes[i].GetType()); break;
1941 default:
1942 FBX_ASSERT_NOW("Trying to assign an unknown type" ); break;
1943 }
1944 FbxHandle*** ptr = &dst;
1945 GetDirectArray().Release((void**)ptr);
1946 }
1947 }
1948 }
1949
1950 int mId;
1951 FbxArray<FbxDataType> mDataTypes;
1952 FbxArray<FbxString*> mDataNames;
1953#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
1954};
1955
1956/** Returns the direct array with the given attribute index. The template type must match the attribute type at pIndex.
1957 * \param pLayerElement The layer element whose direct array to return.
1958 * \param pIndex The direct array index
1959 * \param pStatus Will be set to \c false if accessing the direct array encounters an error.
1960 * \return If pStatus receives \c true, the direct array at the given index is
1961 * returned. Otherwise the return value is \c undefined.
1962 */
1963template <class T>
1964inline FbxLayerElementArrayTemplate<T>& FbxGetDirectArray( FbxLayerElementUserData *pLayerElement,int pIndex, bool* pStatus)
1965{
1966 return *(FbxLayerElementArrayTemplate<T>*)pLayerElement->GetDirectArrayVoid(pIndex,pStatus);
1967}
1968
1969/** Returns the direct array with the given attribute index. The template type must match the attribute type at pIndex.
1970 * \param pLayerElement The layer element whose direct array to return.
1971 * \param pIndex The direct array index
1972 * \param pStatus Will be set to \c false if accessing the direct array encounters an error.
1973 * \return If pStatus receives \c true, the direct array at the given index is
1974 * returned. Otherwise the return value is \c undefined.
1975 */
1976template <class T>
1977inline FbxLayerElementArrayTemplate<T> const& FbxGetDirectArray(FbxLayerElementUserData const *pLayerElement, int pIndex, bool* pStatus)
1978{
1979 return *(const FbxLayerElementArrayTemplate<T>*)pLayerElement->GetDirectArrayVoid(pIndex,pStatus);
1980}
1981
1982
1983/** Returns the direct array with the given attribute name.The template type must match the attribute type with pName.
1984 * \param pLayerElement The layer element whose direct array to return.
1985 * \param pName The given attribute name.
1986 * \param pStatus Will be set to false if accessing the direct array encounters an error.
1987 * \return If pStatus receives \c true, the direct array at the given index is
1988 * returned. Otherwise the return value is \c undefined.
1989 */
1990template <class T>
1991inline FbxLayerElementArrayTemplate<T>& FbxGetDirectArray( FbxLayerElementUserData *pLayerElement,const char* pName, bool* pStatus )
1992{
1993 return *(FbxLayerElementArrayTemplate<T>*)pLayerElement->GetDirectArrayVoid(pName,pStatus);
1994}
1995
1996/** Returns the direct array with the given attribute name.The template type must match the attribute type with pName.
1997 * \param pLayerElement The layer element whose direct array to return.
1998 * \param pName The given attribute name.
1999 * \param pStatus Will be set to false if accessing the direct array encounters an error.
2000 * \return If pStatus receives \c true, the direct array at the given index is
2001 * returned. Otherwise the return value is \c undefined.
2002 */
2003template <class T>
2004inline FbxLayerElementArrayTemplate<T> const& FbxGetDirectArray(FbxLayerElementUserData const *pLayerElement, const char* pName, bool* pStatus )
2005{
2006 return *(const FbxLayerElementArrayTemplate<T>*)pLayerElement->GetDirectArrayVoid(pName,pStatus);
2007}
2008
2009
2010/** Layer element for indicating smoothness of components of a geometry.
2011 * \remarks To be correctly saved in FBX file, this type of Layer element should have its reference
2012 * mode set to \e eDirect.
2013 *
2014 * \nosubgrouping
2015 */
2016class FBXSDK_DLL FbxLayerElementSmoothing : public FbxLayerElementTemplate<int>
2017{
2018public:
2019 FBXSDK_FRIEND_NEW();
2020
2021 /** Allocation method.
2022 * \param pOwner The owner of this layer element.
2023 * \param pName The name of this layer element.
2024 * \return A pointer to the layer element or \c NULL if creation fails.
2025 */
2026 static FbxLayerElementSmoothing* Create(FbxLayerContainer* pOwner, const char* pName);
2027
2028 /** Sets the Reference Mode.
2029 * \param pMode Specifies the reference mode.
2030 * \remarks Only support eDirect.
2031 */
2032 void SetReferenceMode( FbxLayerElement::EReferenceMode pMode )
2033 {
2034 if( pMode != FbxLayerElement::eDirect )
2035 {
2036 FBX_ASSERT_NOW( "Smoothing layer elements must be direct mapped" );
2037 return;
2038 }
2039 }
2040
2041/*****************************************************************************************************************************
2042** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
2043*****************************************************************************************************************************/
2044#ifndef DOXYGEN_SHOULD_SKIP_THIS
2045protected:
2046 FbxLayerElementSmoothing()
2047 {
2048 mReferenceMode = FbxLayerElement::eDirect;
2049 }
2050#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
2051};
2052
2053/** Layer element for indicating crease of components of a geometry.
2054 * \nosubgrouping
2055 */
2056class FBXSDK_DLL FbxLayerElementCrease : public FbxLayerElementTemplate<double>
2057{
2058public:
2059 FBXSDK_FRIEND_NEW();
2060
2061 /** Allocation method.
2062 * \param pOwner The owner of this layer element.
2063 * \param pName The name of this layer element.
2064 * \return A pointer to the layer element or \c NULL if creation fails.
2065 */
2066 static FbxLayerElementCrease* Create(FbxLayerContainer* pOwner, const char* pName);
2067
2068 /** Sets the Reference Mode.
2069 * \param pMode Specifies the reference mode.
2070 * \remarks Only support eDirect.
2071 */
2072 void SetReferenceMode( FbxLayerElement::EReferenceMode pMode )
2073 {
2074 if( pMode != FbxLayerElement::eDirect )
2075 {
2076 FBX_ASSERT_NOW( "Crease layer elements must be direct mapped" );
2077 return;
2078 }
2079 }
2080
2081/*****************************************************************************************************************************
2082** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
2083*****************************************************************************************************************************/
2084#ifndef DOXYGEN_SHOULD_SKIP_THIS
2085protected:
2086 FbxLayerElementCrease()
2087 {
2088 mReferenceMode = FbxLayerElement::eDirect;
2089 }
2090#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
2091};
2092
2093/** Layer element for indicating hole of polygon of a geometry.
2094* \nosubgrouping
2095*/
2096class FBXSDK_DLL FbxLayerElementHole : public FbxLayerElementTemplate<bool>
2097{
2098public:
2099 FBXSDK_FRIEND_NEW();
2100
2101 /** Allocation method.
2102 * \param pOwner The owner of this layer element.
2103 * \param pName The name of this layer element.
2104 * \return A pointer to the layer element or \c NULL if creation fails.
2105 */
2106 static FbxLayerElementHole* Create(FbxLayerContainer* pOwner, const char* pName);
2107
2108 /** Sets the Reference Mode.
2109 * \param pMode Specifies the reference mode.
2110 * \remarks Only support eDirect.
2111 */
2112 void SetReferenceMode( FbxLayerElement::EReferenceMode pMode )
2113 {
2114 if( pMode != FbxLayerElement::eDirect )
2115 {
2116 FBX_ASSERT_NOW( "hole layer elements must be direct mapped" );
2117 return;
2118 }
2119 }
2120
2121/*****************************************************************************************************************************
2122** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
2123*****************************************************************************************************************************/
2124#ifndef DOXYGEN_SHOULD_SKIP_THIS
2125protected:
2126 FbxLayerElementHole()
2127 {
2128 mReferenceMode = FbxLayerElement::eDirect;
2129 }
2130#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
2131};
2132
2133/** Layer element for indicating if specified components are shown/hidden
2134 */
2135class FBXSDK_DLL FbxLayerElementVisibility : public FbxLayerElementTemplate<bool>
2136{
2137public:
2138
2139 /** Allocation method.
2140 * \return A pointer to the layer element or \c NULL if creation fails.
2141 */
2142 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementVisibility);
2143
2144/*****************************************************************************************************************************
2145** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
2146*****************************************************************************************************************************/
2147#ifndef DOXYGEN_SHOULD_SKIP_THIS
2148protected:
2149 FbxLayerElementVisibility();
2150 ~FbxLayerElementVisibility();
2151#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
2152};
2153
2154/** \brief Layer element for mapping Textures to a geometry. This class is deprecated.
2155 *
2156 * Deprecated since FBX SDK 2011. Textures (FbxTexture derived classes) should be connected
2157 * to material properties.
2158 *
2159 * For example:
2160 *
2161 * \code
2162 * FbxFileTexture* file;
2163 * FbxSurfacePhong* phong;
2164 * phong->Diffuse.ConnectSrcObject(file);
2165 * \endcode
2166 * \see FbxSurfaceMaterial
2167 *
2168 * \remarks To be correctly saved in FBX file, this type of Layer element should have its reference
2169 * mode set to \e eIndexToDirect.
2170 * \nosubgrouping
2171 */
2172class FBXSDK_DLL FbxLayerElementTexture : public FbxLayerElementTemplate<FbxTexture*>
2173{
2174public:
2175 /** Allocation method.
2176 * \return A pointer to the layer element or \c NULL if creation fails.
2177 */
2178 FBXSDK_LAYER_ELEMENT_CREATE_DECLARE(LayerElementTexture);
2179
2180 /** \enum EBlendMode Lets you control how textures are combined when you apply multiple layers of texture to a surface.
2181 * - \e eTranslucent The new texture layer is transparent (depending on the Alpha value).
2182 * - \e eAdd Add the color of the new texture to the previous texture.
2183 * - \e eModulate Multiples the color value of the new texture by the color values of all previous layers of texture.
2184 * - \e eModulate2 Multiples the color value of the new texture by two and then by the color values of all previous layers of texture.
2185 * - \e eOver Equivalent to eTranslucent. Blends the new texture over top of the old texture, according to the new texture's alpha channel.
2186 * - \e eNormal, The colors of the two layers will not interact in any way, and it will display the full value of the colors in layer 1.
2187 * - \e eDissolve, Dissolve makes the lower layer take on the colors of the top layer, and how much depends on the opacity of the upper layer.
2188 * - \e eDarken, Darken compares each pixel value of the upper layer to its counterpart's pixel value of the lower layer and chooses the darker of the two to display.
2189 * - \e eColorBurn, Color Burn burns in the color of the upper layer with the lower layer. No part of the image will get lighter.
2190 * - \e eLinearBurn, Linear Burn works like multiply but the results are more intense.
2191 * - \e eDarkerColor, This blend mode simply divides pixel values of one layer with the other.
2192 * - \e eLighten, Lighten compares the two layers pixel for pixel and uses the lightest pixel value. No part of the image gets darker.
2193 * - \e eScreen, Screen brightens by lightning the lower layer based on the lightness of the upper layer
2194 * - \e eColorDodge, Color Dodge dodges the lower layer with the upper layer, resulting in a lighter image. No part of the image will be darkened.
2195 * - \e eLinearDodge, Linear Dodge works like screen but with more intense results.
2196 * - \e eLighterColor, This blend mode has the opposite effect of the Darker Color mode. It compares all the values in both layers, then displays the lightest values.
2197 * - \e eSoftLight, Soft Light will multiply the dark tones and screen the light tones.
2198 * - \e eHardLight, Hard Light multiplies the dark colors and screens the light colors.
2199 * - \e eVividLight, Vivid Light will dodges or burn the lower layer pixels depending on whether the upper layer pixels are brighter or darker than neutral gray. It works on the contrast of the lower layer.
2200 * - \e eLinearLight, Linear Light is the same as Vivid light but it works on the brightness of the lower layer.
2201 * - \e ePinLight, Pin Light changes the lower layer pixels depending on how bright the pixels are in the upper layer.
2202 * - \e eHardMix, Produces either white or black, depending on similarities between A and B.
2203 * - \e eDifference, Difference reacts to the differences between the upper and lower layer pixels.
2204 * - \e eExclusion, Exclusion uses the darkness of the lower layer to mask the difference between upper and lower layers.
2205 * - \e eSubtract, The result color is the foreground color subtracted from the background color. The result color is then applied over the background color using the foreground alpha to define the opacity of the result.
2206 * - \e eDivide, This blend mode simply divides pixel values of one layer with the other.
2207 * - \e eHue, Hue changes the hue of the lower layer to the hue of the upper layer but leaves brightness and saturation alone.
2208 * - \e eSaturation, Saturation changes the saturation of the lower layer to the hue of the upper layer but leaves brightness and hue alone.
2209 * - \e eColor, Color changes the hue and saturation of the lower layer to the hue and saturation of the upper layer but leaves luminosity alone.
2210 * - \e eLuminosity, Luminosity changes the luminosity of the lower layer to the luminosity of the upper layer while leaving hue and saturation the same.
2211 * - \e eOverlay, Multiplies (darkens) when the layer on which the mode is set is dark and screens (brightens) when the layer on which the mode is applied is lighter.
2212 * - \e eBlendModeCount Marks the end of the blend mode enum.
2213 */
2214 enum EBlendMode
2215 {
2216 eTranslucent,
2217 eAdd,
2218 eModulate,
2219 eModulate2,
2220 eOver,
2221 eNormal,
2222 eDissolve,
2223 eDarken,
2224 eColorBurn,
2225 eLinearBurn,
2226 eDarkerColor,
2227 eLighten,
2228 eScreen,
2229 eColorDodge,
2230 eLinearDodge,
2231 eLighterColor,
2232 eSoftLight,
2233 eHardLight,
2234 eVividLight,
2235 eLinearLight,
2236 ePinLight,
2237 eHardMix,
2238 eDifference,
2239 eExclusion,
2240 eSubtract,
2241 eDivide,
2242 eHue,
2243 eSaturation,
2244 eColor,
2245 eLuminosity,
2246 eOverlay,
2247 eBlendModeCount
2248 };
2249
2250 /** Sets the way Textures blend between layers.
2251 * \param pBlendMode A valid blend mode.
2252 */
2253 void SetBlendMode(EBlendMode pBlendMode) { mBlendMode = pBlendMode; }
2254
2255 /** Sets the transparency level between multiple texture levels.
2256 * \param pAlpha Set to a value between 0.0 and 1.0, where 0.0 is totally transparent and 1.0 is totally opaque.
2257 * \remarks Values smaller than 0.0 are clipped to 0.0, while values greater than 1.0 are clipped to 1.0.
2258 */
2259 void SetAlpha(double pAlpha)
2260 {
2261 if (pAlpha > 1.0)
2262 mAlpha = 1.0;
2263 else if (pAlpha < 0.0)
2264 mAlpha = 0.0;
2265 else
2266 mAlpha = pAlpha;
2267 }
2268
2269 /** Returns the way Textures blend between layers.
2270 * \return The current Blend Mode.
2271 */
2272 EBlendMode GetBlendMode() const { return mBlendMode; }
2273
2274 /** Returns the transparency level between multiple levels of textures.
2275 * \return An alpha value between 0.0 and 1.0, where 0.0 is totally transparent and 1.0 is totally opaque.
2276 */
2277 double GetAlpha() const { return mAlpha; }
2278
2279/*****************************************************************************************************************************
2280** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
2281*****************************************************************************************************************************/
2282#ifndef DOXYGEN_SHOULD_SKIP_THIS
2283 virtual int MemorySize() const
2284 {
2285 int size = FbxLayerElementTemplate<FbxTexture*>::MemorySize();
2286 size += sizeof(mBlendMode);
2287 size += sizeof(mAlpha);
2288 return size;
2289 }
2290
2291protected:
2292 /** Constructor
2293 * By default, textures have a Blend Mode of eTranslucent,
2294 * a Reference Mode of eIndexToDirect, and an Alpha value of 1.0.
2295 */
2296 FbxLayerElementTexture() : mBlendMode(eTranslucent)
2297 {
2298 mReferenceMode = eIndexToDirect;
2299 mAlpha = 1.0;
2300 }
2301
2302private:
2303 EBlendMode mBlendMode;
2304 double mAlpha;
2305#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
2306};
2307
2308
2309/** FbxLayer class provides a base for the layering mechanism.
2310 *
2311 * A layer can contain one or more of the following layer elements:
2312 * \li Normals
2313 * \li Binormals
2314 * \li Tangents
2315 * \li Materials
2316 * \li Polygon Groups
2317 * \li UVs
2318 * \li Vertex Colors
2319 * \li Smoothing informations
2320 * \li Vertex Creases
2321 * \li Edge Creases
2322 * \li Custom User Data
2323 * \li Visibilities
2324 * \li Textures (diffuse, ambient, specular, etc.) (deprecated)
2325 *
2326 * A typical layer for a Mesh contains Normals, UVs and Materials. A typical layer for NURBS contains only Materials.
2327 * In the case of the NURBS, the NURBS' parameterization is used for the UVs; no UVs should be specified.
2328 *
2329 * In most cases, you only need a single layer to describe a geometry. Many applications only support what is defined on the first layer.
2330 * Take this into account when you fill the layer. For example, it is legal to define the Layer 0 with the UVs and then
2331 * define the model's Normals on layer 1. However if you construct a file this way, it may not be imported correctly in other applications.
2332 * Store the Normals in Layer 0 to avoid problems.
2333 *
2334 * Since FBX SDK 2011, Textures are connected to the properties of FbxSurfaceMaterial derived classes.
2335 * FbxLayerElementTexture is no longer used. See the code example in FbxLayerElementTexture for how to connect a texture.
2336 *
2337 * Since FBX SDK 2011, texture layering is achieved by FbxLayeredTexture. See the code example in FbxLayeredTexture for how to blend textures.
2338 *
2339 * Normally, you can access layer from FbxLayerContainer like FbxGeometry.
2340 * For example,
2341 * \code
2342 * FbxMesh* mesh;
2343 * FbxLayer* layer0 = mesh->GetLayer(0);
2344 * FbxLayerElementNormal* normals = layer0->GetNormals();
2345 * \endcode
2346 *
2347 * \nosubgrouping
2348 * \see FbxLayerElement
2349 * \see FbxLayerElementNormal
2350 * \see FbxLayerElementBinormal
2351 * \see FbxLayerElementTangent
2352 * \see FbxLayerElementMaterial
2353 * \see FbxLayerElementPolygonGroup
2354 * \see FbxLayerElementUV
2355 * \see FbxLayerElementVertexColor
2356 * \see FbxLayerElementSmoothing
2357 * \see FbxLayerElementCrease
2358 * \see FbxLayerElementUserData
2359 * \see FbxLayerElementHole
2360 * \see FbxLayerElementVisibility
2361 */
2362class FBXSDK_DLL FbxLayer
2363{
2364
2365public:
2366 FBXSDK_FRIEND_NEW();
2367
2368 /**
2369 * \name Layer Element Management
2370 */
2371 //@{
2372
2373 /** Returns this layer's Normals description .
2374 * \return A pointer to the Normals layer element, or \c NULL if no Normals layer element is defined in this layer.
2375 * \remarks FbxNurbs or FbxPatch geometry should not have Normals defined.
2376 */
2377 FbxLayerElementNormal* GetNormals();
2378
2379 /** Returns this layer's Normals description .
2380 * \return A pointer to the Normals layer element, or \c NULL if no Normals layer element is defined in this layer.
2381 * \remarks FbxNurbs or FbxPatch geometry should not have Normals defined.
2382 */
2383 const FbxLayerElementNormal* GetNormals() const;
2384
2385 /** Returns this layer's Tangents description.
2386 * \return A pointer to the Tangents layer element, or \c NULL if no Tangents layer element is defined in this layer.
2387 * \remarks FbxNurbs or FbxPatch geometry should not have Tangents defined.
2388 */
2389 FbxLayerElementTangent* GetTangents();
2390
2391 /** Returns this layer's Tangents description.
2392 * \return A pointer to the Tangents layer element, or \c NULL if no Tangents layer element is defined in this layer.
2393 * \remarks FbxNurbs or FbxPatch geometry should not have Tangents defined.
2394 */
2395 const FbxLayerElementTangent* GetTangents() const;
2396
2397 /** Returns this layer's Binormals description.
2398 * \return A pointer to the Binormals layer element, or \c NULL if no Binormals layer element is defined in this layer.
2399 * \remarks FbxNurbs or FbxPatch geometry should not have Binormals defined.
2400 */
2401 FbxLayerElementBinormal* GetBinormals();
2402
2403 /** Returns this layer's Binormals description.
2404 * \return A pointer to the Binormals layer element, or \c NULL if no Binormals layer element is defined in this layer.
2405 * \remarks FbxNurbs or FbxPatch geometry should not have Binormals defined.
2406 */
2407 const FbxLayerElementBinormal* GetBinormals() const;
2408
2409 /** Returns this layer's Materials description.
2410 * \return A pointer to the Materials layer element, or \c NULL if no Materials layer element is defined in this layer.
2411 */
2412 FbxLayerElementMaterial* GetMaterials();
2413
2414 /** Returns this layer's Materials description.
2415 * \return A pointer to the Materials layer element, or \c NULL if no Materials layer element is defined in this layer.
2416 */
2417 const FbxLayerElementMaterial* GetMaterials() const;
2418
2419 /** Returns this layer's Polygon Groups description.
2420 * \return A pointer to the Polygon Groups layer element, or \c NULL if no Polygon Groups layer element is defined in this layer.
2421 */
2422 FbxLayerElementPolygonGroup* GetPolygonGroups();
2423
2424 /** Returns this layer's Polygon Groups description.
2425 * \return A pointer to the Polygon Groups layer element, or \c NULL if no Polygon Groups layer element is defined in this layer.
2426 */
2427 const FbxLayerElementPolygonGroup* GetPolygonGroups() const;
2428
2429 /** Returns this layer's UV description.
2430 * \param pTypeIdentifier Layer element type identifier, should be a texture type identifier.
2431 * \return A pointer to the UVs layer element, or \c NULL if no UV is defined in this layer.
2432 * \remarks FbxNurbs or FbxPatch geometry should not have UVs defined.
2433 * The NURBS/Patch parameterization is used as UV parameters to map a texture.
2434 */
2435 FbxLayerElementUV* GetUVs(FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
2436
2437 /** Returns this layer's UV description.
2438 * \param pTypeIdentifier Layer element type identifier, should be a texture type identifier.
2439 * \return A pointer to the UVs layer element, or \c NULL if no UV is defined in this layer.
2440 * \remarks FbxNurbs or FbxPatch geometry should not have UVs defined.
2441 * The NURBS/Patch parameterization is used as UV parameters to map a texture.
2442 */
2443 const FbxLayerElementUV* GetUVs(FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse) const;
2444
2445
2446 /** Returns the number of different UV sets in this layer.
2447 */
2448 int GetUVSetCount() const;
2449
2450 /** Returns an array that describes which UV sets are in this layer.
2451 */
2452 FbxArray<FbxLayerElement::EType> GetUVSetChannels() const;
2453
2454 /** Returns an array of UV sets in this layer.
2455 */
2456 FbxArray<const FbxLayerElementUV*> GetUVSets() const;
2457
2458 /** Returns this layer's Vertex Colors description.
2459 * \return A pointer to the Vertex Colors layer element, or \c NULL if no Vertex Color layer element is defined in this layer.
2460 * \remarks FbxNurbs or FbxPatch geometry should not have Vertex Colors defined, since no vertex exists.
2461 */
2462 FbxLayerElementVertexColor* GetVertexColors();
2463
2464 /** Returns this layer's Vertex Colors description.
2465 * \return A pointer to the Vertex Colors layer element, or \c NULL if no Vertex Color layer element is defined in this layer.
2466 * \remarks FbxNurbs or FbxPatch geometry should not have Vertex Colors defined, since no vertex exists.
2467 */
2468 const FbxLayerElementVertexColor* GetVertexColors() const;
2469
2470 /** Returns this layer's Smoothing description.
2471 * \return A pointer to the Smoothing layer element, or \c NULL if no Smoothing layer element is defined in this layer.
2472 * \remarks FbxNurbs or FbxPatch geometry should not have Smoothing defined.
2473 */
2474 FbxLayerElementSmoothing* GetSmoothing();
2475
2476 /** Returns this layer's Smoothing description.
2477 * \return A pointer to the Smoothing layer element, or \c NULL if no Smoothing layer element is defined in this layer.
2478 * \remarks FbxNurbs or FbxPatch geometry should not have Smoothing defined.
2479 */
2480 const FbxLayerElementSmoothing* GetSmoothing() const;
2481
2482 /** Returns this layer's vertex crease description.
2483 * \return A pointer to the Crease layer element, or \c NULL if no Crease layer element is defined in this layer.
2484 * \remarks Crease info should only be defined when the geometry is FbxSubDiv.
2485 */
2486 FbxLayerElementCrease* GetVertexCrease();
2487
2488 /** Returns this layer's vertex crease description.
2489 * \return A pointer to the Crease layer element, or \c NULL if no Crease layer element is defined in this layer.
2490 * \remarks Crease info should only be defined when the geometry is FbxSubDiv.
2491 */
2492 const FbxLayerElementCrease* GetVertexCrease() const;
2493
2494 /** Returns this layer's edge crease description.
2495 * \return A pointer to the Crease layer element, or \c NULL if no Crease layer element is defined in this layer.
2496 * \remarks Crease info should only be defined when the geometry is FbxSubDiv.
2497 */
2498 FbxLayerElementCrease* GetEdgeCrease();
2499
2500 /** Returns this layer's edge crease description.
2501 * \return A pointer to the Crease layer element, or \c NULL if no Crease layer element is defined in this layer.
2502 * \remarks Crease info should only be defined when the geometry is FbxSubDiv.
2503 */
2504 const FbxLayerElementCrease* GetEdgeCrease() const;
2505
2506 /** Returns this layer's Hole description.
2507 * \return A pointer to the Hole layer element, or \c NULL if no Hole layer element is defined in this layer.
2508 * \remarks Hole info should only be defined when the geometry is FbxMesh.
2509 */
2510 FbxLayerElementHole* GetHole();
2511
2512 /** Returns this layer's Hole description.
2513 * \return A pointer to the Hole layer element, or \c NULL if no Hole layer element is defined in this layer.
2514 * \remarks Hole info should only be defined when the geometry is FbxMesh.
2515 */
2516 const FbxLayerElementHole* GetHole() const;
2517
2518 /** Returns this layer's User Data.
2519 * \return A pointer to the User Data layer element, or \c NULL if no User Data layer element is defined in this layer.
2520 */
2521 FbxLayerElementUserData* GetUserData();
2522
2523 /** Returns this layer's User Data.
2524 * \return A pointer to the User Data layer element, or \c NULL if no User Data layer element is defined in this layer.
2525 */
2526 const FbxLayerElementUserData* GetUserData() const;
2527
2528 /** Returns this layer's visibility.
2529 * \return A pointer to the visibility layer element, or \c NULL if no visibility layer element is defined in this layer.
2530 */
2531 FbxLayerElementVisibility* GetVisibility();
2532
2533 /** Returns this layer's visibility.
2534 * \return A pointer to the visibility layer element, or \c NULL if no visibility layer element is defined in this layer.
2535 */
2536 const FbxLayerElementVisibility* GetVisibility() const;
2537
2538 /** Returns this layer's Textures description.
2539 * \param pType Layer element type, should be a texture type identifier.
2540 * \return A pointer to the Textures layer element, or \c NULL if no Textures layer element is defined in this layer.
2541 */
2542 FbxLayerElementTexture* GetTextures(FbxLayerElement::EType pType);
2543
2544 /** Returns this layer's Textures description.
2545 * \param pType Layer element type, should be a texture type identifier.
2546 * \return A pointer to the Textures layer element, or \c NULL if no Textures layer element is defined in this layer.
2547 */
2548 const FbxLayerElementTexture* GetTextures(FbxLayerElement::EType pType) const;
2549
2550 /** Sets this layer's Textures description.
2551 * \param pType Texture type identifier.
2552 * \param pTextures A pointer to the Textures layer element, or \c NULL to remove the Textures definition.
2553 */
2554 void SetTextures(FbxLayerElement::EType pType, FbxLayerElementTexture* pTextures);
2555
2556 /** Returns the specified type of layer element description for this layer.
2557 * \param pType The required Layer element type.
2558 * - Calling with eNormal is the equivalent of calling GetNormals().
2559 * - Calling with eBiNormal is the equivalent of calling GetBinormals().
2560 * - Calling with eTangent is the equivalent of calling GetTangents().
2561 * - Calling with eMaterial is the equivalent of calling GetMaterials().
2562 * - Calling with ePolygonGroup is the equivalent of calling GetPolygonGroups().
2563 * - Calling with eUV is the equivalent of calling GetUVs().
2564 * - Calling with eVertexColor is the equivalent of calling GetVertexColors().
2565 * - Calling with eSmoothing is the equivalent of calling GetSmoothing().
2566 * - Calling with eVertexCrease is the equivalent of calling GetVertexCrease().
2567 * - Calling with eEdgeCrease is the equivalent of calling GetEdgeCrease().
2568 * - Calling with eUserData is the equivalent of calling GetUserData().
2569 * - Calling with eVisibility is the equivalent of calling GetVisibility().
2570 * - Calling with texture type is the equivalent of calling GetTextures(FbxLayerElement::EType pType).
2571 * \param pIsUV If \c true, requests the UV layer element that corresponds with the specified texture type.
2572 * \return A pointer to the requested layer element, or \e NULL if the layer element is not defined in this layer.
2573 */
2574 FbxLayerElement* GetLayerElementOfType(FbxLayerElement::EType pType, bool pIsUV=false);
2575
2576 /** Returns the specified type of layer element description for this layer.
2577 * \param pType The required Layer element type.
2578 * - Calling with eNormal is the equivalent of calling GetNormals().
2579 * - Calling with eBiNormal is the equivalent of calling GetBinormals().
2580 * - Calling with eTangent is the equivalent of calling GetTangents().
2581 * - Calling with eMaterial is the equivalent of calling GetMaterials().
2582 * - Calling with ePolygonGroup is the equivalent of calling GetPolygonGroups().
2583 * - Calling with eUV is the equivalent of calling GetUVs().
2584 * - Calling with eVertexColor is the equivalent of calling GetVertexColors().
2585 * - Calling with eSmoothing is the equivalent of calling GetSmoothing().
2586 * - Calling with eVertexCrease is the equivalent of calling GetVertexCrease().
2587 * - Calling with eEdgeCrease is the equivalent of calling GetEdgeCrease().
2588 * - Calling with eUserData is the equivalent of calling GetUserData().
2589 * - Calling with eVisibility is the equivalent of calling GetVisibility().
2590 * - Calling with texture type is the equivalent of calling GetTextures(FbxLayerElement::EType pType).
2591 * \param pIsUV If \c true, requests the UV layer element that corresponds with the specified texture type.
2592 * \return A pointer to the requested layer element, or \e NULL if the layer element is not defined in this layer.
2593 */
2594 const FbxLayerElement* GetLayerElementOfType(FbxLayerElement::EType pType, bool pIsUV=false) const;
2595
2596 /** Sets this layer's Normals description.
2597 * \param pNormals A pointer to the Normals layer element, or \c NULL to remove the Normals definition.
2598 * \remarks FbxNurbs or FbxPatch geometry should not have Normals defined.
2599 */
2600 void SetNormals(FbxLayerElementNormal* pNormals);
2601
2602 /** Sets this layer's Binormals description.
2603 * \param pBinormals A pointer to the Binormals layer element, or \c NULL to remove the Binormals definition.
2604 * \remarks FbxNurbs or FbxPatch geometry should not have Binormals defined.
2605 */
2606 void SetBinormals(FbxLayerElementBinormal* pBinormals);
2607
2608 /** Sets this layer's Tangents description.
2609 * \param pTangents A pointer to the Tangents layer element, or \c NULL to remove the Tangents definition.
2610 * \remarks FbxNurbs or FbxPatch geometry should not have Tangents defined.
2611 */
2612 void SetTangents(FbxLayerElementTangent* pTangents);
2613
2614 /** Sets this layer's Materials description.
2615 * \param pMaterials A pointer to the Materials layer element, or \c NULL to remove the Material definition.
2616 */
2617 void SetMaterials(FbxLayerElementMaterial* pMaterials);
2618
2619 /** Sets this layer's Polygon Groups description.
2620 * \param pPolygonGroups A pointer to the Polygon Groups layer element, or \c NULL to remove the Polygon Group definition.
2621 */
2622 void SetPolygonGroups(FbxLayerElementPolygonGroup* pPolygonGroups);
2623
2624 /** Sets this layer's UVs description.
2625 * \param pUVs A pointer to the UVs layer element, or \c NULL to remove the UV definition.
2626 * \param pTypeIdentifier Layer element type, should be texture type.
2627 * \remarks FbxNurbs or FbxPatch geometry should not have UVs defined.
2628 * The NURBS/Patch parameterization is used as UV parameters to map a texture.
2629 */
2630 void SetUVs(FbxLayerElementUV* pUVs, FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
2631
2632 /** Sets this layer's Vertex Colors description.
2633 * \param pVertexColors A pointer to the Vertex Colors layer element, or \c NULL to remove the Vertex Color definition.
2634 * \remarks FbxNurbs or FbxPatch geometry should not have Vertex Colors defined, since no vertex exists.
2635 */
2636 void SetVertexColors (FbxLayerElementVertexColor* pVertexColors);
2637
2638 /** Sets this layer's Smoothing description.
2639 * \param pSmoothing A pointer to the Smoothing layer element, or \c NULL to remove the Smoothing definition.
2640 * \remarks FbxNurbs or FbxPatch geometry should not have Smoothing defined.
2641 */
2642 void SetSmoothing (FbxLayerElementSmoothing* pSmoothing);
2643
2644 /** Sets this layer's Vertex Crease description.
2645 * \param pCrease A pointer to the Vertex Crease layer element, or \c NULL to remove the Crease definition.
2646 * \remarks Crease should only be defined when the geometry is FbxSubDiv.
2647 */
2648 void SetVertexCrease (FbxLayerElementCrease* pCrease);
2649
2650 /** Sets this layer's Edge Crease description.
2651 * \param pCrease A pointer to the Edge Crease layer element, or \c NULL to remove the Crease definition.
2652 * \remarks Crease should only be defined when the geometry is FbxSubDiv.
2653 */
2654 void SetEdgeCrease (FbxLayerElementCrease* pCrease);
2655
2656 /** Sets this layer's Hole description.
2657 * \param pHole A pointer to the Hole layer element, or \c NULL to remove the Hole definition.
2658 * \remarks Hole should only be defined when the geometry is FbxMesh.
2659 */
2660 void SetHole (FbxLayerElementHole* pHole);
2661
2662 /** Sets this layer's User Data.
2663 * \param pUserData A pointer to the User Data layer element, or \c NULL to remove the User Data.
2664 */
2665 void SetUserData (FbxLayerElementUserData* pUserData);
2666
2667 /** Sets this layer's the visibility.
2668 * \param pVisibility A pointer to the visibility layer element, or \c NULL to remove the visibility.
2669 */
2670 void SetVisibility( FbxLayerElementVisibility* pVisibility );
2671
2672 /** Sets the specified type of layer element description for this layer.
2673 * \param pLayerElement A pointer to the layer element, or \c NULL to remove the layer element.
2674 * \param pType The required Layer element type.
2675 * - Calling with eNormal is the equivalent of calling GetNormals().
2676 * - Calling with eBiNormal is the equivalent of calling GetBinormals().
2677 * - Calling with eTangent is the equivalent of calling GetTangents().
2678 * - Calling with eMaterial is the equivalent of calling GetMaterials().
2679 * - Calling with ePolygonGroup is the equivalent of calling GetPolygonGroups().
2680 * - Calling with eUV is the equivalent of calling GetUVs().
2681 * - Calling with eVertexColor is the equivalent of calling GetVertexColors().
2682 * - Calling with eSmoothing is the equivalent of calling GetSmoothing().
2683 * - Calling with eVertexCrease is the equivalent of calling GetVertexCrease().
2684 * - Calling with eEdgeCrease is the equivalent of calling GetEdgeCrease().
2685 * - Calling with eUserData is the equivalent of calling GetUserData().
2686 * - Calling with eVisibility is the equivalent of calling GetVisibility().
2687 * - Calling with texture type is the equivalent of calling GetTextures(FbxLayerElement::EType pType).
2688 * \param pIsUV If \c true, requests the UV layer element that corresponds with the specified texture type.
2689 */
2690 void SetLayerElementOfType(FbxLayerElement* pLayerElement, FbxLayerElement::EType pType, bool pIsUV=false);
2691
2692 /** Creates the specified type of layer element description for this layer.
2693 * \param pType The required Layer element type.
2694 * \param pIsUV When \c true, requests the UV LayerElement that corresponds with the specified Layer Element type (only applies to
2695 * TEXTURE type layer elements).
2696 * \return A pointer to the newly created layer element, or \e NULL if the layer element has not been created for this layer.
2697 */
2698 FbxLayerElement* CreateLayerElementOfType(FbxLayerElement::EType pType, bool pIsUV=false);
2699
2700 /** Clone function.
2701 * \param pSrcLayer The source layer to be cloned.
2702 */
2703 void Clone(FbxLayer const& pSrcLayer);
2704
2705/*****************************************************************************************************************************
2706** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
2707*****************************************************************************************************************************/
2708#ifndef DOXYGEN_SHOULD_SKIP_THIS
2709protected:
2710 //! Assignment operator.
2711 FbxLayer& operator=(FbxLayer const& pSrcLayer);
2712 //@}
2713private:
2714
2715 FbxLayer(FbxLayerContainer& pOwner);
2716 virtual ~FbxLayer();
2717
2718 void Clear();
2719
2720 FbxLayerContainer& mOwner;
2721
2722 FbxLayerElement* mNonTexturesArray[FbxLayerElement::sTypeNonTextureCount];
2723 FbxLayerElementUV* mUVsArray[FbxLayerElement::sTypeTextureCount];
2724 FbxLayerElementTexture* mTexturesArray[FbxLayerElement::sTypeTextureCount];
2725
2726
2727 friend class FbxLayerContainer;
2728
2729public:
2730 /**
2731 * \name Serialization section
2732 */
2733 //@{
2734 bool ContentWriteTo(FbxStream& pStream) const;
2735 bool ContentReadFrom(const FbxStream& pStream);
2736 //@}
2737 virtual int MemoryUsage() const;
2738#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
2739};
2740
2741/**
2742 * Utility macro for iterating over texture layer elements
2743 */
2744#define FBXSDK_FOR_EACH_TEXTURE(lLayerIndex) for((lLayerIndex)=0;(lLayerIndex)<FbxLayerElement::sTypeTextureCount;(lLayerIndex)++)
2745
2746/**
2747 * Utility macro for iterating over non-texture layer elements
2748 */
2749#define FBXSDK_FOR_EACH_NON_TEXTURE(lLayerIndex) for((lLayerIndex)=0;(lLayerIndex)<FbxLayerElement::sTypeNonTextureCount;(lLayerIndex)++)
2750
2751/**
2752 * Utility macro for getting texture layer element index by type
2753 */
2754#define FBXSDK_TEXTURE_INDEX(ElementType) (int(ElementType)-FbxLayerElement::sTypeTextureStartIndex)
2755
2756/**
2757 * Utility macro for getting texture layer element type by index
2758 */
2759#define FBXSDK_TEXTURE_TYPE(TextureIndex) (FbxLayerElement::EType((TextureIndex)+FbxLayerElement::sTypeTextureStartIndex))
2760
2761/**
2762 * Utility macro for getting non-texture layer element index by type
2763 */
2764#define FBXSDK_NON_TEXTURE_INDEX(ElementType) (int(ElementType)-FbxLayerElement::sTypeNonTextureStartIndex)
2765
2766/**
2767 * Utility macro for getting non-texture layer element type by index
2768 */
2769#define FBXSDK_NON_TEXTURE_TYPE(Index) (FbxLayerElement::EType((Index)+FbxLayerElement::sTypeNonTextureStartIndex))
2770
2771/** Defines geometry element classes.
2772 * A geometry element describes how the geometry element is mapped to a geometry surface
2773 * and how the mapping information is arranged in memory.
2774 * \remarks Geometry elements are independent of layer elements and hide the complexity of layers.
2775 * \code
2776 * FbxGeometryElementUV* lUVs = lMesh->GetElementUV("map1");
2777 * FbxGeometryElementUV::DirectArrayType lDirectArray = lUVs->GetDirectArray();
2778 * int lDirectUVCount = lDirectArray.GetCount();
2779 * FbxVector2 lFirstUV = lDirectArray[0];
2780 * \endcode
2781 * \see FbxGeometryBase
2782 */
2783typedef FbxLayerElement FbxGeometryElement;
2784typedef FbxLayerElementNormal FbxGeometryElementNormal;
2785typedef FbxLayerElementBinormal FbxGeometryElementBinormal;
2786typedef FbxLayerElementTangent FbxGeometryElementTangent;
2787typedef FbxLayerElementMaterial FbxGeometryElementMaterial;
2788typedef FbxLayerElementPolygonGroup FbxGeometryElementPolygonGroup;
2789typedef FbxLayerElementUV FbxGeometryElementUV;
2790typedef FbxLayerElementVertexColor FbxGeometryElementVertexColor;
2791typedef FbxLayerElementUserData FbxGeometryElementUserData;
2792typedef FbxLayerElementSmoothing FbxGeometryElementSmoothing;
2793typedef FbxLayerElementCrease FbxGeometryElementCrease;
2794typedef FbxLayerElementHole FbxGeometryElementHole;
2795typedef FbxLayerElementVisibility FbxGeometryElementVisibility;
2796
2797#undef FBXSDK_LAYER_ELEMENT_CREATE_DECLARE
2798
2799#include <fbxsdk/fbxsdk_nsend.h>
2800
2801#endif /* _FBXSDK_SCENE_GEOMETRY_LAYER_H_ */
2802