fbxsdk/fileio/collada/fbxcolladaelement.h Source File
 
 
 
fbxsdk/fileio/collada/fbxcolladaelement.h
Go to the documentation of this file.
00001 /****************************************************************************************
00002  
00003    Copyright (C) 2013 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 #include <fbxsdk.h>
00017 
00018 #include <fbxsdk/fbxsdk_nsbegin.h>
00019 
00020 // Utility functions to convert type to array tag used in COLLADA source element
00021 template <typename T>
00022 inline const FbxString TypeToArrayTag()
00023 {
00024     return COLLADA_FLOAT_ARRAY_STRUCTURE;
00025 }
00026 
00027 template <>
00028 inline const FbxString TypeToArrayTag<bool>()
00029 {
00030     return COLLADA_BOOL_ARRAY_STRUCTURE;
00031 }
00032 
00033 template <>
00034 inline const FbxString TypeToArrayTag<int>()
00035 {
00036     return COLLADA_INT_ARRAY_STRUCTURE;
00037 }
00038 
00039 template <>
00040 inline const FbxString TypeToArrayTag<FbxString>()
00041 {
00042     return COLLADA_NAME_ARRAY_STRUCTURE;
00043 }
00044 
00045 // Utility functions to convert type to parameter tag used in COLLADA source element
00046 template <typename T>
00047 inline const FbxString TypeToParameterTag()
00048 {
00049     return COLLADA_FLOAT_TYPE;
00050 }
00051 
00052 template <>
00053 inline const FbxString TypeToParameterTag<bool>()
00054 {
00055     return COLLADA_BOOL_TYPE;
00056 }
00057 
00058 template <>
00059 inline const FbxString TypeToParameterTag<int>()
00060 {
00061     return COLLADA_INT_TYPE;
00062 }
00063 
00064 template <>
00065 inline const FbxString TypeToParameterTag<FbxString>()
00066 {
00067     return COLLADA_NAME_TYPE;
00068 }
00069 
00070 //----------------------------------------------------------------------------//
00071 
00074 struct ElementContentAccessor
00075 {
00076     ElementContentAccessor();
00077     ElementContentAccessor(xmlNode * pElement);
00078     virtual ~ElementContentAccessor();
00079 
00080     template <typename TYPE>
00081     bool GetNext(TYPE * pData)
00082     {
00083         return FromString(pData, mPointer, &mPointer);
00084     }
00085 
00086     template <typename TYPE>
00087     int GetArray(TYPE * pArray,
00088         int pSourceUnitOffset = 0, int pSourceUnitValidCount = 1, int pSourceUnitSize = 1,
00089         int pDestUnitOffset = 0, int pDestUnitValidCount = 1, int pDestUnitSize = 1,
00090         TYPE pDefaultValue = TYPE())
00091     {
00092         if (pArray)
00093         {
00094             return FromStringToArray(mPointer, pArray,
00095                 pSourceUnitOffset, pSourceUnitValidCount, pSourceUnitSize,
00096                 pDestUnitOffset, pDestUnitValidCount, pDestUnitSize, pDefaultValue);
00097         }
00098         return 0;
00099     }
00100 
00101     xmlChar * mContent;
00102     const char * mPointer;
00103 };
00104 
00105 //----------------------------------------------------------------------------//
00106 
00109 template <typename TYPE>
00110 struct SourceElementContentAccessor : public ElementContentAccessor
00111 {
00112     SourceElementContentAccessor(xmlNode * pSourceElement)
00113         : mCount(0), mStride(1), mOffset(0)
00114     {
00115         bool lReadCount = true;
00116         xmlNode* lTechniqueElement = DAE_FindChildElementByTag(pSourceElement, COLLADA_TECHNIQUE_COMMON_ELEMENT);
00117         if (lTechniqueElement)
00118         {
00119             xmlNode* lAccessorElement = DAE_FindChildElementByTag(lTechniqueElement, COLLADA_ACCESSOR_STRUCTURE);
00120             FBX_ASSERT(lAccessorElement);
00121             if (!lAccessorElement)
00122                 return;
00123 
00124             DAE_GetElementAttributeValue(lAccessorElement, COLLADA_COUNT_PROPERTY, mCount);
00125             DAE_GetElementAttributeValue(lAccessorElement, COLLADA_STRIDE_PROPERTY, mStride);
00126             DAE_GetElementAttributeValue(lAccessorElement, COLLADA_OFFSET_PROPERTY, mOffset);
00127             lReadCount = false;
00128         }
00129 
00130         xmlNode * lDataArrayElement = DAE_FindChildElementByTag(pSourceElement,
00131             TypeToArrayTag<TYPE>());
00132         // Some COLLADA exporters use IDREF_array instead of Name_array
00133         if (!lDataArrayElement && TypeToArrayTag<TYPE>() == COLLADA_NAME_ARRAY_STRUCTURE)
00134             lDataArrayElement = DAE_FindChildElementByTag(pSourceElement, COLLADA_IDREF_ARRAY_STRUCTURE);
00135         FBX_ASSERT(lDataArrayElement);
00136 
00137         if (lDataArrayElement && lReadCount)
00138             DAE_GetElementAttributeValue(lDataArrayElement, COLLADA_COUNT_PROPERTY, mCount);
00139 
00140         mContent = xmlNodeGetContent(lDataArrayElement);
00141         mPointer = (const char *)mContent;
00142     }
00143 
00144     int mCount;
00145     int mStride;
00146     int mOffset;
00147 };
00148 
00149 //----------------------------------------------------------------------------//
00150 
00153 class ElementBase
00154 {
00155 public:
00156     enum
00157     {
00158         MATRIX_STRIDE = 16,
00159     };
00160 
00161     // The name of user property in FBX which is used to preserve the ID of COLLADA element
00162     static const char* smID_PROPERTY_NAME;    
00163 
00166     ElementBase();
00167     virtual ~ElementBase();
00168 
00171     void SetXMLElement(xmlNode * pElement) { mXMLElement = pElement; }
00172     xmlNode * GetXMLElement() const { return mXMLElement; }
00173 
00177     const FbxString & GetID() const;
00178 
00183     const FbxSystemUnit * GetUnit() const;
00184 
00185 private:
00186     xmlNode * mXMLElement;
00187     mutable FbxString * mID;
00188     mutable FbxSystemUnit * mUnit;
00189 };
00190 
00195 inline const FbxString URL(const FbxString & pID)
00196 {
00197     return FbxString("#") + pID;
00198 }
00199 
00210 template <typename T>
00211 xmlNode * AddSourceElement(xmlNode * pParentElement, const char * pID,
00212                            const T * pData, int pCount, int pStride = 1)
00213 {
00214     FBX_ASSERT(pParentElement && pData);
00215     if (!pParentElement || !pData)
00216         return NULL;
00217 
00218     xmlNode * lSourceElement = DAE_AddChildElement(pParentElement, COLLADA_SOURCE_STRUCTURE);
00219     DAE_AddAttribute(lSourceElement, COLLADA_ID_PROPERTY, pID);
00220 
00221     FbxString lContent;
00222     const int lDataCount = pCount * pStride;
00223     for (int lIndex = 0; lIndex < lDataCount; ++lIndex)
00224     {
00225         lContent += ToString(pData[lIndex]);
00226         if (lIndex != lDataCount - 1)
00227             lContent += " ";
00228     }
00229     const FbxString lArrayID = FbxString(pID) + "-array";
00230     xmlNode * lArrayElement = DAE_AddChildElement(lSourceElement, TypeToArrayTag<T>(), lContent);
00231     DAE_AddAttribute(lArrayElement, COLLADA_ID_PROPERTY, lArrayID);
00232     DAE_AddAttribute(lArrayElement, COLLADA_COUNT_PROPERTY, lDataCount);
00233 
00234     xmlNode * lTechniqueCommonElement = DAE_AddChildElement(lSourceElement,
00235         COLLADA_TECHNIQUE_COMMON_ELEMENT);
00236     xmlNode * lAccessElement = DAE_AddChildElement(lTechniqueCommonElement, 
00237         COLLADA_ACCESSOR_STRUCTURE);
00238     DAE_AddAttribute(lAccessElement, COLLADA_SOURCE_PROPERTY, URL(lArrayID));
00239     DAE_AddAttribute(lAccessElement, COLLADA_COUNT_PROPERTY, pCount);
00240     DAE_AddAttribute(lAccessElement, COLLADA_STRIDE_PROPERTY, pStride);
00241 
00242     for (int lStrideIndex = 0; lStrideIndex < pStride; ++lStrideIndex)
00243     {
00244         xmlNode * lParamElement = DAE_AddChildElement(lAccessElement, COLLADA_PARAMETER_STRUCTURE);
00245         DAE_AddAttribute(lParamElement, COLLADA_TYPE_PROPERTY, TypeToParameterTag<T>());
00246     }
00247 
00248     return lSourceElement;
00249 }
00250 
00257 template <typename TYPE> FbxLayerElementArray * PopulateLayerElementDirectArray(FbxLayerElement * pLayerElement, xmlNode * pSourceElement, int pSize)
00258 {
00259     SourceElementContentAccessor<TYPE> lSourceElementAccessor(pSourceElement);
00260 
00261     FbxLayerElementTemplate<TYPE> * lLayerElement = (FbxLayerElementTemplate<TYPE> *)pLayerElement;
00262     lLayerElement->SetMappingMode(FbxLayerElement::eByPolygonVertex);
00263     lLayerElement->SetReferenceMode(FbxLayerElement::eIndexToDirect);
00264     lLayerElement->GetDirectArray().SetCount(lSourceElementAccessor.mCount);
00265 
00266     TYPE * lArray = NULL;
00267     lArray = lLayerElement->GetDirectArray().GetLocked(lArray);
00268     lSourceElementAccessor.GetArray((double *)lArray, 0, pSize,
00269         lSourceElementAccessor.mStride, 0, pSize, sizeof(TYPE)/sizeof(double), 1.0);
00270     lLayerElement->GetDirectArray().Release(&lArray, lArray);
00271 
00272     return &(lLayerElement->GetIndexArray());
00273 }
00274 
00275 #include <fbxsdk/fbxsdk_nsend.h>
00276 
00277 #endif /* _FBXSDK_FILEIO_COLLADA_ELEMENT_H_ */