fbxcolladaelement.h

Go to the documentation of this file.
00001 /****************************************************************************************
00002  
00003    Copyright (C) 2012 Autodesk, Inc.
00004    All rights reserved.
00005  
00006    Use of this software is subject to the terms of the Autodesk license agreement
00007    provided at the time of installation or download, or which otherwise accompanies
00008    this software in either electronic or hard copy form.
00009  
00010 ****************************************************************************************/
00011 
00013 #ifndef _FBXSDK_FILEIO_COLLADA_ELEMENT_H_
00014 #define _FBXSDK_FILEIO_COLLADA_ELEMENT_H_
00015 
00016 //----------------------------------------------------------------------------//
00017 
00018 #include <fbxsdk.h>
00019 
00020 // Namespace -----------------------------------------------------------------//
00021 
00022 #include <fbxsdk/fbxsdk_nsbegin.h>
00023 
00024 #define FBX_COLLADA_NAMESPACE_OPEN \
00025     namespace FBX_COLLADA {
00026 #define FBX_COLLADA_NAMESPACE_CLOSE \
00027     };
00028 
00029 FBX_COLLADA_NAMESPACE_OPEN
00030 
00031 //----------------------------------------------------------------------------//
00032 
00033 
00034 // Utility functions to convert type to array tag used in COLLADA source element
00035 template <typename T>
00036 inline const FbxString TypeToArrayTag()
00037 {
00038     return COLLADA_FLOAT_ARRAY_STRUCTURE;
00039 }
00040 
00041 template <>
00042 inline const FbxString TypeToArrayTag<bool>()
00043 {
00044     return COLLADA_BOOL_ARRAY_STRUCTURE;
00045 }
00046 
00047 template <>
00048 inline const FbxString TypeToArrayTag<int>()
00049 {
00050     return COLLADA_INT_ARRAY_STRUCTURE;
00051 }
00052 
00053 template <>
00054 inline const FbxString TypeToArrayTag<FbxString>()
00055 {
00056     return COLLADA_NAME_ARRAY_STRUCTURE;
00057 }
00058 
00059 // Utility functions to convert type to parameter tag used in COLLADA source element
00060 template <typename T>
00061 inline const FbxString TypeToParameterTag()
00062 {
00063     return COLLADA_FLOAT_TYPE;
00064 }
00065 
00066 template <>
00067 inline const FbxString TypeToParameterTag<bool>()
00068 {
00069     return COLLADA_BOOL_TYPE;
00070 }
00071 
00072 template <>
00073 inline const FbxString TypeToParameterTag<int>()
00074 {
00075     return COLLADA_INT_TYPE;
00076 }
00077 
00078 template <>
00079 inline const FbxString TypeToParameterTag<FbxString>()
00080 {
00081     return COLLADA_NAME_TYPE;
00082 }
00083 
00084 //----------------------------------------------------------------------------//
00085 
00088 struct ElementContentAccessor
00089 {
00090     ElementContentAccessor();
00091     ElementContentAccessor(xmlNode * pElement);
00092     virtual ~ElementContentAccessor();
00093 
00094     template <typename TYPE>
00095     bool GetNext(TYPE * pData)
00096     {
00097         return FromString(pData, mPointer, &mPointer);
00098     }
00099 
00100     template <typename TYPE>
00101     int GetArray(TYPE * pArray,
00102         int pSourceUnitOffset = 0, int pSourceUnitValidCount = 1, int pSourceUnitSize = 1,
00103         int pDestUnitOffset = 0, int pDestUnitValidCount = 1, int pDestUnitSize = 1,
00104         TYPE pDefaultValue = TYPE())
00105     {
00106         if (pArray)
00107         {
00108             return FromStringToArray(mPointer, pArray,
00109                 pSourceUnitOffset, pSourceUnitValidCount, pSourceUnitSize,
00110                 pDestUnitOffset, pDestUnitValidCount, pDestUnitSize, pDefaultValue);
00111         }
00112         return 0;
00113     }
00114 
00115     xmlChar * mContent;
00116     const char * mPointer;
00117 };
00118 
00119 //----------------------------------------------------------------------------//
00120 
00123 template <typename TYPE>
00124 struct SourceElementContentAccessor : public ElementContentAccessor
00125 {
00126     SourceElementContentAccessor(xmlNode * pSourceElement)
00127         : mCount(0), mStride(1), mOffset(0)
00128     {
00129         bool lReadCount = true;
00130         xmlNode* lTechniqueElement = DAE_FindChildElementByTag(pSourceElement, COLLADA_TECHNIQUE_COMMON_ELEMENT);
00131         if (lTechniqueElement)
00132         {
00133             xmlNode* lAccessorElement = DAE_FindChildElementByTag(lTechniqueElement, COLLADA_ACCESSOR_STRUCTURE);
00134             FBX_ASSERT(lAccessorElement);
00135             if (!lAccessorElement)
00136                 return;
00137 
00138             DAE_GetElementAttributeValue(lAccessorElement, COLLADA_COUNT_PROPERTY, mCount);
00139             DAE_GetElementAttributeValue(lAccessorElement, COLLADA_STRIDE_PROPERTY, mStride);
00140             DAE_GetElementAttributeValue(lAccessorElement, COLLADA_OFFSET_PROPERTY, mOffset);
00141             lReadCount = false;
00142         }
00143 
00144         xmlNode * lDataArrayElement = DAE_FindChildElementByTag(pSourceElement,
00145             TypeToArrayTag<TYPE>());
00146         // Some COLLADA exporters use IDREF_array instead of Name_array
00147         if (!lDataArrayElement && TypeToArrayTag<TYPE>() == COLLADA_NAME_ARRAY_STRUCTURE)
00148             lDataArrayElement = DAE_FindChildElementByTag(pSourceElement, COLLADA_IDREF_ARRAY_STRUCTURE);
00149         FBX_ASSERT(lDataArrayElement);
00150 
00151         if (lDataArrayElement && lReadCount)
00152             DAE_GetElementAttributeValue(lDataArrayElement, COLLADA_COUNT_PROPERTY, mCount);
00153 
00154         mContent = xmlNodeGetContent(lDataArrayElement);
00155         mPointer = (const char *)mContent;
00156     }
00157 
00158     int mCount;
00159     int mStride;
00160     int mOffset;
00161 };
00162 
00163 //----------------------------------------------------------------------------//
00164 
00167 class ElementBase
00168 {
00169 public:
00170     enum
00171     {
00172         MATRIX_STRIDE = 16,
00173     };
00174 
00175     // The name of user property in FBX which is used to preserve the ID of COLLADA element
00176     static const FbxString smID_PROPERTY_NAME;
00177 
00180     ElementBase();
00181     virtual ~ElementBase();
00182 
00185     void SetXMLElement(xmlNode * pElement) { mXMLElement = pElement; }
00186     xmlNode * GetXMLElement() const { return mXMLElement; }
00187 
00191     const FbxString & GetID() const;
00192 
00197     const FbxSystemUnit * GetUnit() const;
00198 
00199 private:
00200     xmlNode * mXMLElement;
00201     mutable FbxString * mID;
00202     mutable FbxSystemUnit * mUnit;
00203 };
00204 
00209 inline const FbxString URL(const FbxString & pID)
00210 {
00211     return FbxString("#") + pID;
00212 }
00213 
00224 template <typename T>
00225 xmlNode * AddSourceElement(xmlNode * pParentElement, const char * pID,
00226                            const T * pData, int pCount, int pStride = 1)
00227 {
00228     FBX_ASSERT(pParentElement && pData);
00229     if (!pParentElement || !pData)
00230         return NULL;
00231 
00232     xmlNode * lSourceElement = DAE_AddChildElement(pParentElement, COLLADA_SOURCE_STRUCTURE);
00233     DAE_AddAttribute(lSourceElement, COLLADA_ID_PROPERTY, pID);
00234 
00235     FbxString lContent;
00236     const int lDataCount = pCount * pStride;
00237     for (int lIndex = 0; lIndex < lDataCount; ++lIndex)
00238     {
00239         lContent += ToString(pData[lIndex]);
00240         if (lIndex != lDataCount - 1)
00241             lContent += " ";
00242     }
00243     const FbxString lArrayID = FbxString(pID) + "-array";
00244     xmlNode * lArrayElement = DAE_AddChildElement(lSourceElement, TypeToArrayTag<T>(), lContent);
00245     DAE_AddAttribute(lArrayElement, COLLADA_ID_PROPERTY, lArrayID);
00246     DAE_AddAttribute(lArrayElement, COLLADA_COUNT_PROPERTY, lDataCount);
00247 
00248     xmlNode * lTechniqueCommonElement = DAE_AddChildElement(lSourceElement,
00249         COLLADA_TECHNIQUE_COMMON_ELEMENT);
00250     xmlNode * lAccessElement = DAE_AddChildElement(lTechniqueCommonElement, 
00251         COLLADA_ACCESSOR_STRUCTURE);
00252     DAE_AddAttribute(lAccessElement, COLLADA_SOURCE_PROPERTY, URL(lArrayID));
00253     DAE_AddAttribute(lAccessElement, COLLADA_COUNT_PROPERTY, pCount);
00254     DAE_AddAttribute(lAccessElement, COLLADA_STRIDE_PROPERTY, pStride);
00255 
00256     for (int lStrideIndex = 0; lStrideIndex < pStride; ++lStrideIndex)
00257     {
00258         xmlNode * lParamElement = DAE_AddChildElement(lAccessElement, COLLADA_PARAMETER_STRUCTURE);
00259         DAE_AddAttribute(lParamElement, COLLADA_TYPE_PROPERTY, TypeToParameterTag<T>());
00260     }
00261 
00262     return lSourceElement;
00263 }
00264 
00271 template <typename TYPE> FbxLayerElementArray * PopulateLayerElementDirectArray(FbxLayerElement * pLayerElement, xmlNode * pSourceElement, int pSize)
00272 {
00273     SourceElementContentAccessor<TYPE> lSourceElementAccessor(pSourceElement);
00274 
00275     FbxLayerElementTemplate<TYPE> * lLayerElement = (FbxLayerElementTemplate<TYPE> *)pLayerElement;
00276     lLayerElement->SetMappingMode(FbxLayerElement::eByPolygonVertex);
00277     lLayerElement->SetReferenceMode(FbxLayerElement::eIndexToDirect);
00278     lLayerElement->GetDirectArray().SetCount(lSourceElementAccessor.mCount);
00279 
00280     TYPE * lArray = NULL;
00281     lArray = lLayerElement->GetDirectArray().GetLocked(lArray);
00282     lSourceElementAccessor.GetArray((double *)lArray, 0, pSize,
00283         lSourceElementAccessor.mStride, 0, pSize, sizeof(TYPE)/sizeof(double), 1.0);
00284     lLayerElement->GetDirectArray().Release(&lArray, lArray);
00285 
00286     return &(lLayerElement->GetIndexArray());
00287 }
00288 
00289 //----------------------------------------------------------------------------//
00290 
00291 FBX_COLLADA_NAMESPACE_CLOSE
00292 
00293 #include <fbxsdk/fbxsdk_nsend.h>
00294 
00295 //----------------------------------------------------------------------------//
00296 
00297 #endif /* _FBXSDK_FILEIO_COLLADA_ELEMENT_H_ */