fbxpropertypage.h 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747
  1. /****************************************************************************************
  2. Copyright (C) 2015 Autodesk, Inc.
  3. All rights reserved.
  4. Use of this software is subject to the terms of the Autodesk license agreement
  5. provided at the time of installation or download, or which otherwise accompanies
  6. this software in either electronic or hard copy form.
  7. ****************************************************************************************/
  8. //! \file fbxpropertypage.h
  9. #ifndef _FBXSDK_CORE_PROPERTY_PAGE_H_
  10. #define _FBXSDK_CORE_PROPERTY_PAGE_H_
  11. #include <fbxsdk/fbxsdk_def.h>
  12. #include <fbxsdk/core/base/fbxstringlist.h>
  13. #include <fbxsdk/core/fbxobject.h>
  14. #include <fbxsdk/core/fbxsymbol.h>
  15. #include <fbxsdk/core/fbxpropertydef.h>
  16. #include <fbxsdk/fbxsdk_nsbegin.h>
  17. typedef FbxPair<FbxInt, const char*> FbxNameMapKey;
  18. struct FbxNameMapCompare
  19. {
  20. inline int operator()(const FbxNameMapKey& pKeyA, const FbxNameMapKey& pKeyB) const
  21. {
  22. if( pKeyA.mFirst < pKeyB.mFirst ) return -1;
  23. else if( pKeyA.mFirst > pKeyB.mFirst ) return 1;
  24. return strcmp(pKeyA.mSecond, pKeyB.mSecond);
  25. }
  26. };
  27. class FBXSDK_DLL FbxPropertyInfo
  28. {
  29. public:
  30. FBXSDK_FRIEND_NEW();
  31. static FbxPropertyInfo* Create(const char* pName, FbxPropertyPage* pTypeInfo) { return FbxNew< FbxPropertyInfo >(pName,pTypeInfo); }
  32. static FbxPropertyInfo* Create(const char* pName, EFbxType pType=eFbxUndefined) { return FbxNew< FbxPropertyInfo >(pName,pType); }
  33. void Destroy() { FbxDelete(this); }
  34. FbxPropertyInfo* Clone(FbxPropertyPage* /*pPage*/)
  35. {
  36. // @@@@@ Filter is missing
  37. // @@@@@ Clone is incomplete
  38. if (mTypeInfo)
  39. {
  40. return FbxNew< FbxPropertyInfo >(mName,mTypeInfo);
  41. }
  42. else
  43. {
  44. return FbxNew< FbxPropertyInfo >(mName,mType);
  45. }
  46. }
  47. inline void IncRef() { mRef++; }
  48. inline void DecRef() { mRef--; if (mRef==0) FbxDelete(this); }
  49. inline int GetRef() { return mRef; }
  50. // Labels and Types
  51. inline FbxStringSymbol GetName() const { return mName; }
  52. EFbxType GetType() const;
  53. FbxPropertyPage* GetTypeInfo() const { return mTypeInfo; }
  54. inline void SetLabel(const char* pLabel) { mLabel=pLabel; }
  55. inline const char* GetLabel() const { return mLabel.IsEmpty() ? "" : ((const char*)mLabel); }
  56. inline void SetUserTag(int pUserTag) { mUserTag=pUserTag; }
  57. inline int GetUserTag() const { return mUserTag; }
  58. inline void SetUserData(const void* pUserData) { mUserData=(void*)pUserData; }
  59. inline void* GetUserData() const { return mUserData; }
  60. // Enum list
  61. int AddEnumValue(const char* pStringValue)
  62. {
  63. EFbxType lType = GetType();
  64. if (lType == eFbxEnum || lType == eFbxEnumM)
  65. {
  66. if (!mEnumList)
  67. mEnumList.Reset(FbxNew< FbxStringList >());
  68. bool lCanAdd = (lType == eFbxEnumM || mEnumList->FindIndex( pStringValue ) == -1);
  69. if( lCanAdd )
  70. return mEnumList->Add((char*)pStringValue);
  71. }
  72. return -1;
  73. }
  74. void InsertEnumValue(int pIndex, const char* pStringValue)
  75. {
  76. EFbxType lType = GetType();
  77. if (lType == eFbxEnum || lType == eFbxEnumM)
  78. {
  79. if (!mEnumList)
  80. mEnumList.Reset(FbxNew< FbxStringList >());
  81. bool lCanAdd = (lType == eFbxEnumM || mEnumList->FindIndex( pStringValue ) == -1);
  82. if( lCanAdd )
  83. mEnumList->InsertAt(pIndex,(char*)pStringValue);
  84. }
  85. }
  86. int GetEnumCount()
  87. {
  88. return mEnumList ? mEnumList->GetCount() : 0;
  89. }
  90. void SetEnumValue(int pIndex, const char* pStringValue)
  91. {
  92. EFbxType lType = GetType();
  93. if (lType == eFbxEnum || lType == eFbxEnumM)
  94. {
  95. if (!mEnumList)
  96. mEnumList.Reset(FbxNew< FbxStringList >());
  97. bool lCanAdd = (lType == eFbxEnumM || mEnumList->FindIndex( pStringValue ) == -1);
  98. if (lCanAdd)
  99. mEnumList->SetStringAt(pIndex,(char*)pStringValue);
  100. }
  101. }
  102. void RemoveEnumValue(int pIndex)
  103. {
  104. EFbxType lType = GetType();
  105. if (lType == eFbxEnum || lType == eFbxEnumM)
  106. {
  107. if (!mEnumList)
  108. mEnumList.Reset(FbxNew< FbxStringList >());
  109. mEnumList->RemoveAt(pIndex);
  110. }
  111. }
  112. char* GetEnumValue(int pIndex)
  113. {
  114. char* lValue = NULL;
  115. EFbxType lType = GetType();
  116. if (lType == eFbxEnum || lType == eFbxEnumM)
  117. {
  118. lValue = mEnumList ? mEnumList->GetStringAt(pIndex) : 0;
  119. }
  120. return lValue;
  121. }
  122. // Min and Max values
  123. enum EValueIndex {eValueMin, eValueSoftMin, eValueMax, eValueSoftMax, eValueCount};
  124. bool HasMinMax(EValueIndex pId) const
  125. {
  126. return mMinMaxValue[pId] != NULL;
  127. }
  128. bool GetMinMax(EValueIndex pId, void* pValue, EFbxType pValueType) const
  129. {
  130. if (mMinMaxValue[pId]) {
  131. return FbxTypeCopy(pValue, pValueType, mMinMaxValue[pId], GetType());
  132. }
  133. return false;
  134. }
  135. bool SetMinMax(EValueIndex pId, const void* pValue, EFbxType pValueType)
  136. {
  137. if (!mMinMaxValue[pId]) {
  138. size_t lSize = FbxTypeSizeOf(GetType());
  139. if (lSize) {
  140. mMinMaxValue[pId] = FbxMalloc(lSize);
  141. }
  142. }
  143. if (mMinMaxValue[pId]) {
  144. return FbxTypeCopy(mMinMaxValue[pId], GetType(), pValue, pValueType);
  145. }
  146. return false;
  147. }
  148. private:
  149. FbxPropertyInfo(const char* pName, FbxPropertyPage* pTypeInfo)
  150. : mRef(0)
  151. , mName(pName)
  152. , mType(eFbxUndefined)
  153. , mTypeInfo(pTypeInfo)
  154. , mUserTag(0)
  155. , mUserData(0)
  156. , mFilter(0)
  157. {
  158. for (int i=0; i<eValueCount; i++) {
  159. mMinMaxValue[i] = 0;
  160. }
  161. }
  162. FbxPropertyInfo(FbxStringSymbol pName,FbxPropertyPage *pTypeInfo)
  163. : mRef(0)
  164. , mName(pName)
  165. , mType(eFbxUndefined)
  166. , mTypeInfo(pTypeInfo)
  167. , mUserTag(0)
  168. , mUserData(0)
  169. , mFilter(0)
  170. {
  171. for (int i=0; i<eValueCount; i++) {
  172. mMinMaxValue[i] = 0;
  173. }
  174. }
  175. FbxPropertyInfo(const char* pName, EFbxType pType)
  176. : mRef(0)
  177. , mName(pName)
  178. , mType(pType)
  179. , mTypeInfo(0)
  180. , mUserTag(0)
  181. , mUserData(0)
  182. , mFilter(0)
  183. {
  184. for (int i=0; i<eValueCount; i++) {
  185. mMinMaxValue[i] = 0;
  186. }
  187. }
  188. ~FbxPropertyInfo()
  189. {
  190. for (int i=eValueMin; i<eValueCount; i++) {
  191. FbxFree(mMinMaxValue[i]);
  192. }
  193. }
  194. int mRef;
  195. FbxStringSymbol mName;
  196. FbxStringSymbol mLabel;
  197. EFbxType mType;
  198. FbxPropertyPage* mTypeInfo;
  199. int mUserTag;
  200. void* mMinMaxValue[eValueCount];
  201. void* mUserData;
  202. FbxConnectionPointFilter* mFilter;
  203. FbxAutoDeletePtr<FbxStringList> mEnumList;
  204. };
  205. #if defined(FBXSDK_COMPILER_MSC)
  206. #pragma warning (push)
  207. #pragma warning (disable: 4355)
  208. #endif
  209. class FBXSDK_DLL FbxPropertyConnect
  210. {
  211. public:
  212. FBXSDK_FRIEND_NEW();
  213. static FbxPropertyConnect* Create(FbxPropertyPage* pPage,FbxInt pId) { return FbxNew< FbxPropertyConnect >(pPage,pId); }
  214. void Destroy() { FbxDelete(this); }
  215. FbxPropertyConnect* Clone(FbxPropertyPage* pPage)
  216. {
  217. return FbxNew< FbxPropertyConnect >(pPage,mId);
  218. }
  219. inline void IncRef() { mRef++; }
  220. inline void DecRef() { mRef--; if (mRef==0) FbxDelete(this); }
  221. inline int GetRef() { return mRef; }
  222. // Properties
  223. FbxPropertyPage* GetPage() { return mPage; }
  224. FbxInt GetPropertyId() { return mId; }
  225. // ClearConnectCache()
  226. // ------------------------------------------------------
  227. inline void ClearConnectCache()
  228. {
  229. mConnectionPoint.SubConnectRemoveAll();
  230. }
  231. //! Clear all connect without sending any notification (Internal use ONLY)
  232. inline void WipeAllConnections()
  233. {
  234. mConnectionPoint.WipeConnectionList();
  235. }
  236. // Properties
  237. inline bool ConnectSrc(FbxPropertyConnect* pSrc, FbxConnection::EType pType)
  238. {
  239. return mConnectionPoint.ConnectSrc(&pSrc->mConnectionPoint,pType);
  240. }
  241. inline bool DisconnectSrc(FbxPropertyConnect* pSrc)
  242. {
  243. return mConnectionPoint.DisconnectSrc(&pSrc->mConnectionPoint);
  244. }
  245. inline bool IsConnectedSrc(FbxPropertyConnect* pSrc)
  246. {
  247. return mConnectionPoint.IsConnectedSrc(&pSrc->mConnectionPoint);
  248. }
  249. inline int GetSrcCount(FbxConnectionPointFilter* pFilter)
  250. {
  251. return mConnectionPoint.GetSrcCount(pFilter);
  252. }
  253. inline FbxPropertyConnect* GetSrc(FbxConnectionPointFilter* pFilter, int pIndex)
  254. {
  255. FbxConnectionPoint *lCP = mConnectionPoint.GetSrc(pIndex,pFilter);
  256. return lCP ? (FbxPropertyConnect * )lCP->GetData() : 0;
  257. }
  258. inline bool ConnectDst(FbxPropertyConnect* pDst, FbxConnection::EType pType)
  259. {
  260. return mConnectionPoint.ConnectDst(&pDst->mConnectionPoint,pType);
  261. }
  262. inline bool IsConnectedDst(FbxPropertyConnect* pSrc)
  263. {
  264. return mConnectionPoint.IsConnectedSrc(&pSrc->mConnectionPoint);
  265. }
  266. inline bool DisconnectDst(FbxPropertyConnect* pDst)
  267. {
  268. return mConnectionPoint.DisconnectDst(&pDst->mConnectionPoint);
  269. }
  270. inline int GetDstCount(FbxConnectionPointFilter* pFilter)
  271. {
  272. return mConnectionPoint.GetDstCount(pFilter);
  273. }
  274. inline FbxPropertyConnect* GetDst(FbxConnectionPointFilter* pFilter, int pIndex)
  275. {
  276. FbxConnectionPoint *lCP = mConnectionPoint.GetDst(pIndex,pFilter);
  277. return lCP ? (FbxPropertyConnect * )lCP->GetData() : 0;
  278. }
  279. int mRef;
  280. FbxConnectionPoint mConnectionPoint;
  281. FbxPropertyPage* mPage;
  282. FbxInt mId;
  283. private:
  284. FbxPropertyConnect(FbxPropertyPage* pPage,FbxInt pId) :
  285. mRef(0),
  286. mConnectionPoint(this),
  287. mPage(pPage),
  288. mId(pId)
  289. {
  290. }
  291. ~FbxPropertyConnect(){ if( FbxObject::GetWipeMode() ) mConnectionPoint.WipeConnectionList(); }
  292. };
  293. #if defined(FBXSDK_COMPILER_MSC)
  294. #pragma warning (pop)
  295. #endif
  296. class FBXSDK_DLL FbxPropertyEntry
  297. {
  298. public:
  299. static FbxPropertyEntry* Create(FbxInt pParentId, FbxPropertyInfo* pInfo, FbxPropertyValue* pValue, FbxPropertyConnect* pConnect){ return FbxNew<FbxPropertyEntry>(pParentId, pInfo, pValue, pConnect); }
  300. void Destroy() { FbxDelete(this); }
  301. inline FbxInt GetParentId(){ return mParentId; }
  302. inline bool IsEmpty(){ return (mInfo || mValue || mConnect || mFlags.GetMask() != 0) ? false : true; }
  303. inline FbxPropertyInfo* Get(const FbxPropertyInfo* /*pType*/){ return mInfo; }
  304. void Set(FbxPropertyInfo* pInfo)
  305. {
  306. FbxPropertyInfo* lInfo = mInfo;
  307. if( pInfo ) pInfo->IncRef();
  308. mInfo = pInfo;
  309. if( lInfo ) lInfo->DecRef();
  310. }
  311. inline FbxPropertyValue* Get(const FbxPropertyValue* /*pType*/){ return mValue; }
  312. void Set(FbxPropertyValue* pValue)
  313. {
  314. FbxPropertyValue* lValue = mValue;
  315. if( pValue ) pValue->IncRef();
  316. mValue = pValue;
  317. if( lValue ) lValue->DecRef();
  318. }
  319. inline FbxPropertyConnect* Get(const FbxPropertyConnect* /*pType*/){ return mConnect; }
  320. void Set(FbxPropertyConnect* pConnect)
  321. {
  322. FbxPropertyConnect* lConnect = mConnect;
  323. if( pConnect ) pConnect->IncRef();
  324. mConnect = pConnect;
  325. if( lConnect ) lConnect->DecRef();
  326. }
  327. inline FbxPropertyFlags* Get(const FbxPropertyFlags* /*pType*/){ return &mFlags; }
  328. inline void Set(FbxPropertyFlags pType){ mFlags = pType; }
  329. inline void Set(FbxPropertyFlags* pType){ mFlags = pType ? *pType : FbxPropertyFlags(FbxPropertyFlags::eNone); }
  330. private:
  331. FbxPropertyEntry(FbxInt pParentId,FbxPropertyInfo *pInfo,FbxPropertyValue *pValue,FbxPropertyConnect *pConnect) :
  332. mInfo(pInfo),
  333. mValue(pValue),
  334. mConnect(pConnect),
  335. mParentId(pParentId),
  336. mFlags(FbxPropertyFlags::eNone)
  337. {
  338. if( mInfo ) mInfo->IncRef();
  339. if( mValue ) mValue->IncRef();
  340. if( mConnect ) mConnect->IncRef();
  341. }
  342. ~FbxPropertyEntry()
  343. {
  344. if( mInfo ) mInfo->DecRef();
  345. if( mValue ) mValue->DecRef();
  346. if( mConnect ) mConnect->DecRef();
  347. }
  348. FbxPropertyInfo* mInfo;
  349. FbxPropertyValue* mValue;
  350. FbxPropertyConnect* mConnect;
  351. FbxInt mParentId;
  352. FbxPropertyFlags mFlags;
  353. FBXSDK_FRIEND_NEW();
  354. friend class FbxPropertyPage;
  355. };
  356. class FBXSDK_DLL FbxPropertyIdGenerator
  357. {
  358. public:
  359. FbxPropertyIdGenerator() : mRef(0), mNextId(0) {}
  360. inline FbxInt GetNextId() const { return mNextId; }
  361. inline FbxInt GetNextIdAndInc() { return mNextId++; }
  362. inline void IncRef() { mRef++; }
  363. inline void DecRef() { mRef--; if( mRef == 0 ) FbxDelete(this); }
  364. private:
  365. FbxInt mRef, mNextId;
  366. };
  367. class FBXSDK_DLL FbxPropertyPage
  368. {
  369. public:
  370. FBXSDK_FRIEND_NEW();
  371. static FbxPropertyPage* Create (FbxPropertyPage* pInstanceOf=0) { return FbxNew< FbxPropertyPage >(pInstanceOf); }
  372. static FbxPropertyPage* Create (const char* pName, FbxPropertyPage* pTypeInfo) { return FbxNew< FbxPropertyPage >(pName,pTypeInfo); }
  373. static FbxPropertyPage* Create (const char* pName, EFbxType pType=eFbxUndefined) { return FbxNew< FbxPropertyPage >(pName,pType); }
  374. void Destroy() { FbxDelete(this); }
  375. template<class T> inline T* GetPropertyItem(const T* pItemType,FbxInt pIndex,FbxPropertyPage **pFoundIn=0) const
  376. {
  377. FbxPropertyPage* lReferencePage = 0;
  378. FbxPropertyEntry* lReferenceEntry = GetPropertyEntry(pIndex,&lReferencePage);
  379. if (pFoundIn) *pFoundIn = 0;
  380. if (lReferenceEntry) {
  381. T* lItem = lReferenceEntry->Get( FBX_TYPE(T) );
  382. if (lItem) {
  383. if (pFoundIn) *pFoundIn = lReferencePage;
  384. return lItem;
  385. } else {
  386. return lReferencePage->mInstanceOf ? lReferencePage->mInstanceOf->GetPropertyItem(pItemType,pIndex,pFoundIn) : 0 ;
  387. }
  388. }
  389. return 0;
  390. }
  391. template<class T> inline T* ChangePropertyItemState(const T* pItemType, FbxInt pIndex, FbxPropertyFlags::EInheritType pInheritType)
  392. {
  393. FbxPropertyPage* lReferencePage = NULL;
  394. T* lItem = GetPropertyItem(pItemType, pIndex, &lReferencePage);
  395. if( pInheritType == FbxPropertyFlags::eOverride )
  396. {
  397. if( lReferencePage == this )
  398. {
  399. return lItem;
  400. }
  401. else if( lItem )
  402. {
  403. FbxPropertyEntry* lEntry = ChangePropertyEntryState(pIndex, FbxPropertyFlags::eOverride);
  404. lEntry->Set(lItem->Clone(this));
  405. return lEntry->Get(FBX_TYPE(T));
  406. }
  407. }
  408. else
  409. {
  410. // can't inherit entries that were created on our page.
  411. bool lOwnEntry = !mInstanceOf || (mInstanceOf->GetPropertyItem(pItemType, pIndex) == NULL);
  412. if( lOwnEntry && FbxPropertyFlags::eInherit == pInheritType) return 0;
  413. if( lItem && (lReferencePage == this) )
  414. {
  415. FbxPropertyEntry* lEntry = GetPropertyEntry(pIndex);
  416. lEntry->Set((T*)0);
  417. if( lEntry->IsEmpty() )
  418. {
  419. ChangePropertyEntryState(pIndex, FbxPropertyFlags::eInherit);
  420. }
  421. }
  422. return 0;
  423. }
  424. return 0;
  425. }
  426. template<class T> FbxPropertyPage* GetFirstPropertyItem(FbxInt pId, const T* pItem) const
  427. {
  428. FbxPropertyPage* lReferencePage = NULL;
  429. GetPropertyItem(FBX_TYPE(T), pId, &lReferencePage);
  430. if( lReferencePage && lReferencePage->mInstanceOf )
  431. {
  432. FbxPropertyPage* lReferencePage2 = lReferencePage->mInstanceOf->GetFirstPropertyItem(pId, pItem);
  433. return lReferencePage2 ? lReferencePage2 : lReferencePage;
  434. }
  435. return lReferencePage;
  436. }
  437. const char* GetName(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT)
  438. {
  439. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  440. return lPropertyInfo ? ((const char*)lPropertyInfo->GetName()) : "";
  441. }
  442. const char* GetLabel(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT)
  443. {
  444. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  445. return lPropertyInfo ? ((const char*)lPropertyInfo->GetLabel()) : "";
  446. }
  447. bool SetLabel(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT, const char* pLabel="")
  448. {
  449. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  450. // Don't make it writeable (Keep it shared)
  451. if (lPropertyInfo) {
  452. lPropertyInfo->SetLabel(pLabel);
  453. return true;
  454. } else {
  455. return false;
  456. }
  457. }
  458. void* GetUserData(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT)
  459. {
  460. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  461. return lPropertyInfo ? lPropertyInfo->GetUserData() : 0;
  462. }
  463. bool SetUserData(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT, const void* pUserData=0)
  464. {
  465. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  466. // Don't make it writeable (Keep it shared)
  467. if (lPropertyInfo) {
  468. lPropertyInfo->SetUserData(pUserData);
  469. return true;
  470. } else {
  471. return false;
  472. }
  473. }
  474. int GetUserTag(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT)
  475. {
  476. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  477. return lPropertyInfo ? lPropertyInfo->GetUserTag() : 0;
  478. }
  479. bool SetUserTag(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT,int pUserTag=0)
  480. {
  481. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  482. // Don't make it writeable (Keep it shared)
  483. if (lPropertyInfo) {
  484. lPropertyInfo->SetUserTag(pUserTag);
  485. return true;
  486. } else {
  487. return false;
  488. }
  489. }
  490. EFbxType GetType(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT) const
  491. {
  492. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  493. return lPropertyInfo ? lPropertyInfo->GetType() : eFbxUndefined;
  494. }
  495. FbxInt GetParent(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT) const
  496. {
  497. FbxPropertyEntry* lPropertyEntry = GetPropertyEntry( pId );
  498. return lPropertyEntry ? lPropertyEntry->GetParentId() : FBXSDK_PROPERTY_ID_NULL;
  499. }
  500. FbxPropertyPage* GetTypeInfo(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT)
  501. {
  502. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  503. return lPropertyInfo ? lPropertyInfo->GetTypeInfo() : 0;
  504. }
  505. FbxInt Add(FbxInt pParentId, const char* pName, EFbxType pType)
  506. {
  507. return Add(pParentId,FbxPropertyInfo::Create(pName,pType),FbxPropertyValue::Create(0,pType),0);
  508. }
  509. FbxInt Add(FbxInt pParentId, const char* pName, FbxPropertyPage* pTypeInfo)
  510. {
  511. return Add(pParentId,FbxPropertyInfo::Create(pName,pTypeInfo),FbxPropertyValue::Create(0,pTypeInfo->GetType()),0);
  512. }
  513. inline bool Reparent( FbxInt /*pChildId*/, FbxInt /*pNewParentId*/ )
  514. {
  515. // Not implemented.
  516. /*
  517. if( GetParent(pChildId) != pNewParentId && pChildId < mEntries.GetCount() )
  518. {
  519. FbxPropertyEntry* lChildEntry = mEntries[pChildId];
  520. lChildEntry->mParentId = pNewParentId;
  521. //@@@@@ TODO: propagate to instances
  522. return true;
  523. }
  524. */
  525. return false;
  526. }
  527. inline bool IsChildOf(FbxInt pId,FbxInt pParentId) const
  528. {
  529. return GetParent(pId)==pParentId;
  530. }
  531. inline bool IsDescendentOf(FbxInt pId,FbxInt pAncestorId) const
  532. {
  533. if (pAncestorId>0) {
  534. FbxInt lParentId = GetParent(pId);
  535. while (lParentId != FBXSDK_PROPERTY_ID_NULL ) {
  536. if (lParentId==pAncestorId) {
  537. return true;
  538. }
  539. lParentId = GetParent(lParentId);
  540. }
  541. return false;
  542. } else {
  543. return true;
  544. }
  545. }
  546. //#define PROPERTY_PAGE_SANITY_CHECK // Debug purpose only. Never enable it in a production release.
  547. /** Retrieves the first child property id of a specified property id.
  548. * \param pParentId The specified property id
  549. * \return the first child property id
  550. */
  551. FbxInt GetChild(FbxInt pParentId=FBXSDK_PROPERTY_ID_ROOT) const
  552. {
  553. #ifdef PROPERTY_PAGE_SANITY_CHECK
  554. FbxInt ret0 = FBXSDK_PROPERTY_ID_NULL;
  555. if (pParentId!=FBXSDK_PROPERTY_ID_NULL) {
  556. FbxInt lId = GetMinimumPropertyId(pParentId);
  557. FbxInt lParentId = GetParent(lId);
  558. const FbxInt lLastId = GetPropertyEntryCount();
  559. while (lId<lLastId && lParentId!=pParentId) lParentId=GetParent(++lId);
  560. ret0 = lId<lLastId ? lId : FBXSDK_PROPERTY_ID_NULL;
  561. } else {
  562. ret0 = FBXSDK_PROPERTY_ID_NULL;
  563. }
  564. #endif
  565. FbxInt ret1 = FBXSDK_PROPERTY_ID_NULL;
  566. if (pParentId != FBXSDK_PROPERTY_ID_NULL)
  567. {
  568. FbxPropertyEntry* lEntry;
  569. FbxInt lId = pParentId;
  570. do
  571. {
  572. lId = GetMinimumPropertyIdAndEntry(lId, &lEntry);
  573. } while (lId != FBXSDK_PROPERTY_ID_NULL && lEntry->GetParentId() != pParentId);
  574. ret1 = lId;
  575. }
  576. #ifdef PROPERTY_PAGE_SANITY_CHECK
  577. FBX_ASSERT(ret0==ret1);
  578. #endif
  579. return ret1;
  580. }
  581. /** Retrieves the next sibling property id of a specified property id.
  582. * \param pId The specified property id
  583. * \return the next sibling property id
  584. */
  585. FbxInt GetSibling(FbxInt pId) const
  586. {
  587. #ifdef PROPERTY_PAGE_SANITY_CHECK
  588. FbxInt pIdBackup = pId;
  589. FbxInt ret0 = FBXSDK_PROPERTY_ID_NULL;
  590. if (pId!=FBXSDK_PROPERTY_ID_NULL) {
  591. FbxInt lReferenceParentId = GetParent(pId);
  592. FbxInt lParentId = GetParent(++pId);
  593. const FbxInt lLastId = GetPropertyEntryCount();
  594. while (pId<lLastId && lReferenceParentId!=FBXSDK_PROPERTY_ID_NULL && lParentId!=lReferenceParentId)
  595. lParentId=GetParent(++pId);
  596. ret0 = pId<lLastId ? pId : FBXSDK_PROPERTY_ID_NULL;
  597. } else {
  598. ret0 = FBXSDK_PROPERTY_ID_NULL;
  599. }
  600. pId = pIdBackup;
  601. #endif
  602. FbxInt ret1 = FBXSDK_PROPERTY_ID_NULL;
  603. if (pId != FBXSDK_PROPERTY_ID_NULL)
  604. {
  605. FbxInt lReferenceParentId = GetParent(pId);
  606. if (lReferenceParentId != FBXSDK_PROPERTY_ID_NULL)
  607. {
  608. FbxPropertyEntry *lEntry;
  609. do
  610. {
  611. pId = GetMinimumPropertyIdAndEntry(pId, &lEntry);
  612. } while (pId != FBXSDK_PROPERTY_ID_NULL && lEntry->GetParentId() != lReferenceParentId);
  613. ret1 = pId;
  614. }
  615. }
  616. #ifdef PROPERTY_PAGE_SANITY_CHECK
  617. FBX_ASSERT(ret0==ret1);
  618. #endif
  619. return ret1;
  620. }
  621. /** Retrieves the first descendent property id of a specified property id.
  622. * \param pAnscestorId The specified property id
  623. * \return the first descendent property id
  624. */
  625. FbxInt GetFirstDescendent(FbxInt pAnscestorId=FBXSDK_PROPERTY_ID_ROOT) const
  626. {
  627. #ifdef PROPERTY_PAGE_SANITY_CHECK
  628. FbxInt ret0 = FBXSDK_PROPERTY_ID_NULL;
  629. if (pAnscestorId!=FBXSDK_PROPERTY_ID_NULL) {
  630. FbxInt lId = GetMinimumPropertyId(pAnscestorId);
  631. FbxInt lParentId = GetParent(lId);
  632. const FbxInt lLastId = GetPropertyEntryCount();
  633. while (lId<lLastId) {
  634. if( lParentId!=FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(lId,pAnscestorId) )
  635. {
  636. ret0 = lId;
  637. break;
  638. }
  639. lParentId = GetParent(++lId);
  640. }
  641. }
  642. #endif
  643. FbxInt ret1 = FBXSDK_PROPERTY_ID_NULL;
  644. FbxInt lId = pAnscestorId;
  645. FbxPropertyEntry* lEntry;
  646. if (pAnscestorId != FBXSDK_PROPERTY_ID_NULL)
  647. {
  648. for(;;)
  649. {
  650. lId = GetMinimumPropertyIdAndEntry(lId, &lEntry);
  651. if (lId == FBXSDK_PROPERTY_ID_NULL)
  652. break;
  653. if(lEntry->GetParentId() != FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(lId, pAnscestorId))
  654. {
  655. ret1 = lId;
  656. break;
  657. }
  658. }
  659. }
  660. #ifdef PROPERTY_PAGE_SANITY_CHECK
  661. FBX_ASSERT(ret0==ret1);
  662. #endif
  663. return ret1;
  664. }
  665. /** Retrieves the next descendent property id of a specified property id, with given a descendent property id.
  666. * \param pAnscestorId The specified property id
  667. * \param pId The descendent property id
  668. * \return the next descendent property id
  669. */
  670. FbxInt GetNextDescendent(FbxInt pAnscestorId, FbxInt pId) const
  671. {
  672. #ifdef PROPERTY_PAGE_SANITY_CHECK
  673. FbxInt pIdBackup = pId;
  674. FbxInt ret0 = FBXSDK_PROPERTY_ID_NULL;
  675. if (pId!=FBXSDK_PROPERTY_ID_NULL) {
  676. FbxInt lParentId = GetParent(++pId);
  677. const FbxInt lLastId = GetPropertyEntryCount();
  678. while (pId<lLastId) {
  679. // GetParent returns null when the given id isn't in our page,
  680. // or our ancestor's page.
  681. if( lParentId != FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(pId, pAnscestorId) )
  682. {
  683. ret0 = pId;
  684. break;
  685. }
  686. lParentId = GetParent(++pId);
  687. }
  688. }
  689. pId = pIdBackup;
  690. #endif
  691. FbxInt ret1 = FBXSDK_PROPERTY_ID_NULL;
  692. if (pId != FBXSDK_PROPERTY_ID_NULL)
  693. {
  694. FbxPropertyEntry* lEntry;
  695. for(;;)
  696. {
  697. pId = GetMinimumPropertyIdAndEntry(pId, &lEntry);
  698. if (pId == FBXSDK_PROPERTY_ID_NULL)
  699. break;
  700. if(lEntry->GetParentId() != FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(pId, pAnscestorId) )
  701. {
  702. ret1 = pId;
  703. break;
  704. }
  705. }
  706. }
  707. #ifdef PROPERTY_PAGE_SANITY_CHECK
  708. FBX_ASSERT(ret0==ret1);
  709. #endif
  710. return ret1;
  711. }
  712. FbxInt FastFind (FbxInt pId, const char* pName, FbxPropertyPage* pTypeInfo, bool pCaseSensitive)
  713. {
  714. FbxInt lId = FBXSDK_PROPERTY_ID_NULL;
  715. bool lSlowQuery = true;
  716. if( mNameMap.mSecond.GetSize() > 0 )
  717. {
  718. lSlowQuery = false;
  719. // try to use the map if we've got it
  720. NameMap::RecordType* lIterator = mNameMap.mSecond.Find( FbxNameMapKey( pId, pName ) );
  721. if( !lIterator )
  722. {
  723. lId = FBXSDK_PROPERTY_ID_NULL;
  724. }
  725. else
  726. {
  727. lId = lIterator->GetValue();
  728. if (lId != FBXSDK_PROPERTY_ID_NULL && pTypeInfo)
  729. {
  730. lSlowQuery = true;
  731. // Try to match types.
  732. // If they are mismatched, fall back to the slow query,
  733. // since we might have multiple property with the same name but different types
  734. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo), lId );
  735. if (lPropertyInfo)
  736. {
  737. FbxPropertyPage* lTypeInfo2 = lPropertyInfo->GetTypeInfo();
  738. if ( lTypeInfo2 && lTypeInfo2->Is(pTypeInfo) )
  739. {
  740. lSlowQuery = false;
  741. }
  742. }
  743. }
  744. }
  745. }
  746. if (!lSlowQuery)
  747. return lId;
  748. // fall back if there's no map or we got one with a different type
  749. lId = GetChild(pId);
  750. FbxStringSymbol lSearchSymbol( pName );
  751. while( lId != FBXSDK_PROPERTY_ID_NULL ) {
  752. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo), lId );
  753. if ( (!pTypeInfo || lPropertyInfo->GetTypeInfo()->Is(pTypeInfo)) &&
  754. ((!pCaseSensitive && FBXSDK_stricmp(lPropertyInfo->GetName(),pName)==0) ||
  755. (pCaseSensitive && lPropertyInfo->GetName() == lSearchSymbol)) ) {
  756. return lId;
  757. }
  758. lId = GetSibling(lId);
  759. }
  760. return FBXSDK_PROPERTY_ID_NULL;
  761. }
  762. FbxInt Find (FbxInt pId, const char* pName, FbxPropertyPage* pTypeInfo, bool pCaseSensitive, const char* pChildrenSeparators )
  763. {
  764. if (pChildrenSeparators)
  765. {
  766. FbxInt lId;
  767. size_t lFoundIndex = strcspn(pName,pChildrenSeparators);
  768. // Strip the first part of the name and search
  769. if (lFoundIndex<strlen(pName))
  770. {
  771. FbxString pRootName;
  772. pRootName.Append(pName,lFoundIndex);
  773. lId = FastFind(pId,pRootName.Buffer(),NULL,pCaseSensitive);
  774. return lId != FBXSDK_PROPERTY_ID_NULL ? Find(lId,pName+lFoundIndex+1,pTypeInfo,pCaseSensitive,pChildrenSeparators) : lId;
  775. } else {
  776. return FastFind(pId,pName,pTypeInfo,pCaseSensitive);
  777. }
  778. } else {
  779. return FastFind(pId,pName,pTypeInfo,pCaseSensitive);
  780. }
  781. }
  782. // Enum list
  783. int AddEnumValue(FbxInt pId, const char* pStringValue)
  784. {
  785. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  786. // Don't make it writeable (Keep it shared)
  787. return lPropertyInfo ? lPropertyInfo->AddEnumValue(pStringValue) : - 1;
  788. }
  789. void InsertEnumValue(FbxInt pId, int pIndex, const char* pStringValue)
  790. {
  791. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  792. // Don't make it writeable (Keep it shared)
  793. if (lPropertyInfo) lPropertyInfo->InsertEnumValue(pIndex,pStringValue);
  794. }
  795. int GetEnumCount(FbxInt pId)
  796. {
  797. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  798. // Don't make it writeable (Keep it shared)
  799. return lPropertyInfo ? lPropertyInfo->GetEnumCount() : 0;
  800. }
  801. void SetEnumValue(FbxInt pId, int pIndex, const char* pStringValue)
  802. {
  803. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  804. // Don't make it writeable (Keep it shared)
  805. if (lPropertyInfo) lPropertyInfo->SetEnumValue(pIndex,pStringValue);
  806. }
  807. void RemoveEnumValue(FbxInt pId, int pIndex)
  808. {
  809. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  810. // Don't make it writeable (Keep it shared)
  811. if (lPropertyInfo) lPropertyInfo->RemoveEnumValue(pIndex);
  812. }
  813. char* GetEnumValue(FbxInt pId,int pIndex)
  814. {
  815. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  816. return lPropertyInfo ? lPropertyInfo->GetEnumValue(pIndex) : (char*)"";
  817. }
  818. // Connection
  819. // ---------------------------------
  820. void ClearConnectCache(FbxInt pId)
  821. {
  822. FbxPropertyPage* lReferencePage = 0;
  823. FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
  824. // Connections are not considered propagated so
  825. // make sure that we own the FbxPropertyConnect objects
  826. if (lPropertyConnect) {
  827. lPropertyConnect->ClearConnectCache();
  828. }
  829. }
  830. void WipeAllConnections(FbxInt pId)
  831. {
  832. FbxPropertyPage* lReferencePage = 0;
  833. FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
  834. if (lPropertyConnect) {
  835. lPropertyConnect->WipeAllConnections();
  836. }
  837. }
  838. bool ConnectSrc(FbxInt pDstId, FbxPropertyPage* pSrcPage, FbxInt pSrcId, FbxConnection::EType pType)
  839. {
  840. FbxPropertyEntry* lDstEntry = ChangePropertyEntryState(pDstId,FbxPropertyFlags::eOverride);
  841. FbxPropertyEntry* lSrcEntry = pSrcPage->ChangePropertyEntryState(pSrcId,FbxPropertyFlags::eOverride);
  842. FbxPropertyConnect* lDstConnect= lDstEntry->Get( FBX_TYPE(FbxPropertyConnect) );
  843. FbxPropertyConnect* lSrcConnect= lSrcEntry->Get( FBX_TYPE(FbxPropertyConnect) );
  844. // Make sure we have a connection point on both sides of the connection
  845. if (!lDstConnect) {
  846. lDstConnect = FbxPropertyConnect::Create( this,pDstId );
  847. lDstEntry->Set( lDstConnect );
  848. }
  849. if (!lSrcConnect) {
  850. lSrcConnect = FbxPropertyConnect::Create( pSrcPage,pSrcId );
  851. lSrcEntry->Set( lSrcConnect );
  852. }
  853. // Must @@@@@@@ Propagate to inherited children
  854. return lDstConnect->ConnectSrc(lSrcConnect,pType);
  855. }
  856. bool DisconnectSrc(FbxInt pDstId,FbxPropertyPage* pSrcPage,FbxInt pSrcId)
  857. {
  858. FbxPropertyPage* lDstReferencePage = 0;
  859. FbxPropertyConnect* lDstConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pDstId,&lDstReferencePage );
  860. FbxPropertyPage* lSrcReferencePage = 0;
  861. FbxPropertyConnect* lSrcConnect = pSrcPage->GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pSrcId,&lSrcReferencePage );
  862. // Make sure we have a connection point on both sides of the connection
  863. if (lDstConnect && lSrcConnect && lDstReferencePage==this && lSrcReferencePage==pSrcPage) {
  864. // Must @@@@@@@ Remove unused connections
  865. return lDstConnect->DisconnectSrc(lSrcConnect);
  866. }
  867. return false;
  868. }
  869. bool IsConnectedSrc(FbxInt pDstId, FbxPropertyPage* pSrcPage, FbxInt pSrcId)
  870. {
  871. FbxPropertyPage* lDstReferencePage = 0;
  872. FbxPropertyConnect* lDstConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pDstId,&lDstReferencePage );
  873. FbxPropertyPage* lSrcReferencePage = 0;
  874. FbxPropertyConnect* lSrcConnect = pSrcPage->GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pSrcId,&lSrcReferencePage );
  875. // Make sure we have a connection point on both sides of the connection
  876. if (lDstConnect && lSrcConnect && lDstReferencePage==this && lSrcReferencePage==pSrcPage) {
  877. // Must @@@@@@@ Remove unused connections
  878. return lDstConnect->IsConnectedSrc(lSrcConnect);
  879. }
  880. return false;
  881. }
  882. int GetSrcCount(FbxInt pId, FbxConnectionPointFilter* pFilter)
  883. {
  884. FbxPropertyPage* lReferencePage = 0;
  885. FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
  886. // Connections are not considered propagated so
  887. // make sure that we own the FbxPropertyConnect objects
  888. return (lPropertyConnect && lReferencePage==this) ? lPropertyConnect->GetSrcCount(pFilter) : 0;
  889. }
  890. bool GetSrc(FbxInt pId, int pIndex, FbxConnectionPointFilter* pFilter, FbxPropertyPage** pSrcPage, FbxInt* pSrcId)
  891. {
  892. FbxPropertyPage* lReferencePage = 0;
  893. FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
  894. // Connections are always overridden
  895. // make sure that we own the FbxPropertyConnect Item
  896. if (lPropertyConnect && lReferencePage==this)
  897. {
  898. FbxPropertyConnect* lSrc = lPropertyConnect->GetSrc(pFilter,pIndex);
  899. if (lSrc)
  900. {
  901. if (pSrcPage) *pSrcPage = lSrc->GetPage();
  902. if (pSrcId) *pSrcId = lSrc->GetPropertyId();
  903. return true;
  904. }
  905. }
  906. return false;
  907. }
  908. bool ConnectDst(FbxInt pSrcId, FbxPropertyPage* pDstPage, FbxInt pDstId, FbxConnection::EType pType)
  909. {
  910. return pDstPage->ConnectSrc(pDstId,this,pSrcId,pType);
  911. }
  912. bool DisconnectDst(FbxInt pSrcId, FbxPropertyPage* pDstPage, FbxInt pDstId)
  913. {
  914. return pDstPage->DisconnectSrc(pDstId,this,pSrcId);
  915. }
  916. bool IsConnectedDst(FbxInt pSrcId, FbxPropertyPage* pDstPage, FbxInt pDstId)
  917. {
  918. return pDstPage->IsConnectedSrc(pDstId,this,pSrcId);
  919. }
  920. int GetDstCount(FbxInt pId, FbxConnectionPointFilter* pFilter)
  921. {
  922. FbxPropertyPage* lReferencePage = 0;
  923. FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
  924. // Connections are not considered propagated so
  925. // make sure that we own the FbxPropertyConnect objects
  926. return (lPropertyConnect && lReferencePage==this) ? lPropertyConnect->GetDstCount(pFilter) : 0;
  927. }
  928. bool GetDst(FbxInt pId, int pIndex, FbxConnectionPointFilter* pFilter, FbxPropertyPage** pDstPage, FbxInt* pDstId)
  929. {
  930. FbxPropertyPage* lReferencePage = 0;
  931. FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
  932. // Connections are always overridden
  933. // make sure that we own the FbxPropertyConnect Item
  934. if (lPropertyConnect && lReferencePage==this)
  935. {
  936. FbxPropertyConnect* lDst = lPropertyConnect->GetDst(pFilter,pIndex);
  937. if (lDst)
  938. {
  939. if (pDstPage) *pDstPage = lDst->GetPage();
  940. if (pDstId) *pDstId = lDst->GetPropertyId();
  941. return true;
  942. }
  943. }
  944. return false;
  945. }
  946. // Min and Max
  947. // ---------------------------------
  948. enum EValueIndex { eValueMin,eValueSoftMin,eValueMax,eValueSoftMax,eValueCount };
  949. bool HasMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId) const
  950. {
  951. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  952. return lPropertyInfo ? lPropertyInfo->HasMinMax(pValueId) : false;
  953. }
  954. bool GetMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId, void* pValue, EFbxType pValueType)
  955. {
  956. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  957. // Don't make it writeable (Keep it shared)
  958. return lPropertyInfo ? lPropertyInfo->GetMinMax(pValueId,pValue,pValueType) : false;
  959. }
  960. bool SetMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId, const void* pValue, EFbxType pValueType)
  961. {
  962. FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
  963. // Don't make it writeable (Keep it shared)
  964. return lPropertyInfo ? lPropertyInfo->SetMinMax(pValueId,pValue,pValueType) : false;
  965. }
  966. // Value
  967. // ---------------------------------
  968. bool Get(FbxInt pId, void* pValue, EFbxType pValueType)
  969. {
  970. FbxPropertyValue* lPropertyValue = GetPropertyItem( FBX_TYPE(FbxPropertyValue),pId );
  971. return lPropertyValue ? lPropertyValue->Get(pValue,pValueType) : 0;
  972. }
  973. bool Set(FbxInt pId, const void* pValue, EFbxType pValueType, bool pCheckValueEquality)
  974. {
  975. if( pCheckValueEquality )
  976. {
  977. FbxPropertyPage* lReferencePage = NULL;
  978. FbxPropertyValue* lPropertyValue = GetPropertyItem( FBX_TYPE(FbxPropertyValue),pId,&lReferencePage );
  979. void* lCurrentValue = FbxTypeAllocate( pValueType );
  980. bool lValuesEqual = false;
  981. bool lValueChanged = false;
  982. if( lReferencePage && lReferencePage != this )
  983. {
  984. // this page inherits, so check if we have to override the value.
  985. if( lPropertyValue )
  986. {
  987. lPropertyValue->Get( lCurrentValue, pValueType );
  988. lValuesEqual = FbxTypeCompare( pValue, lCurrentValue, pValueType );
  989. }
  990. }
  991. else
  992. {
  993. FbxPropertyPage* lReferencePage2 = NULL;
  994. FbxPropertyValue* lPropertyValue2 = mInstanceOf ? mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyValue),pId,&lReferencePage2 ) : NULL;
  995. if( lReferencePage2 && lPropertyValue2 )
  996. {
  997. // this page is an override, but there is another page before us that overrides the value
  998. lPropertyValue2->Get( lCurrentValue, pValueType );
  999. lValuesEqual = FbxTypeCompare( pValue, lCurrentValue, pValueType );
  1000. if( lValuesEqual )
  1001. {
  1002. ChangePropertyItemState( FBX_TYPE(FbxPropertyValue), pId, FbxPropertyFlags::eInherit );
  1003. lValueChanged = true;
  1004. }
  1005. }
  1006. // else this page is the originator of the property, so no need to check,
  1007. }
  1008. FbxTypeDeallocate(pValueType, lCurrentValue);
  1009. lCurrentValue = NULL;
  1010. if( lValuesEqual )
  1011. return lValueChanged;
  1012. }
  1013. FbxPropertyValue* lPropertyValue = ChangePropertyItemState( FBX_TYPE(FbxPropertyValue),pId,FbxPropertyFlags::eOverride );
  1014. return lPropertyValue ? lPropertyValue->Set(pValue,pValueType) : false;
  1015. }
  1016. inline FbxPropertyFlags::EInheritType GetValueInherit(FbxInt pId, bool pCheckInstanceOf) const
  1017. {
  1018. FbxPropertyPage* lReferencePage = NULL;
  1019. GetPropertyItem(FBX_TYPE(FbxPropertyValue), pId, &lReferencePage);
  1020. // check one level
  1021. if( !pCheckInstanceOf )
  1022. {
  1023. return lReferencePage == this ? FbxPropertyFlags::eOverride : FbxPropertyFlags::eInherit;
  1024. }
  1025. else
  1026. {
  1027. if( lReferencePage == this ) return FbxPropertyFlags::eOverride; // this page is either an override, or the originator
  1028. else if( !lReferencePage->mInstanceOf ) return FbxPropertyFlags::eInherit; // the reference is the class root, so we must be inheriting
  1029. // The reference page is not the class root, might be another override, or the originator.
  1030. FbxPropertyValue* lPropertyValue = lReferencePage->mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyValue), pId );
  1031. // if lReferencePage->mInstanceOf has the property value,
  1032. // lReferencePage is an override
  1033. // else
  1034. // its the originator, so this page inherits from it.
  1035. return lPropertyValue ? FbxPropertyFlags::eOverride : FbxPropertyFlags::eInherit;
  1036. }
  1037. }
  1038. inline bool SetValueInherit(FbxInt pId, FbxPropertyFlags::EInheritType pType)
  1039. {
  1040. // no support for this mode yet
  1041. if( FbxPropertyFlags::eDeleted == pType )
  1042. return false;
  1043. ChangePropertyItemState( FBX_TYPE(FbxPropertyValue), pId, pType );
  1044. // Above call doesn't return error codes, so just check that we match types.
  1045. return GetValueInherit(pId, false) == pType;
  1046. }
  1047. inline bool GetDefaultValue(FbxInt pId, void* pValue, EFbxType pValueType) const
  1048. {
  1049. FbxPropertyPage* lReferencePage = GetFirstPropertyItem( pId, FBX_TYPE(FbxPropertyValue) );
  1050. FbxPropertyValue* lPropertyValue = lReferencePage ? lReferencePage->GetPropertyItem( FBX_TYPE(FbxPropertyValue), pId ) : NULL;
  1051. return lPropertyValue ? lPropertyValue->Get( pValue, pValueType ) : false;
  1052. }
  1053. // useful set and get functions
  1054. template <class T> inline bool Set( FbxInt pId, const T& pValue ) { return Set( pId,&pValue,FbxTypeOf(pValue),true ); }
  1055. template <class T> inline T Get( FbxInt pId, const T* pFBX_TYPE) { T lValue; Get( pId,&lValue,FbxTypeOf(lValue) ); return lValue; }
  1056. void SetDataPtr(void* pDataPtr) { mDataPtr = pDataPtr; }
  1057. void* GetDataPtr() const { return mDataPtr; }
  1058. // Instance and override management
  1059. // ------------------------------------------
  1060. void PushPropertiesToParentInstance()
  1061. {
  1062. if (mInstanceOf) {
  1063. const int lCount = GetPropertyEntryCount();
  1064. // push the existing properties into the parent
  1065. // ----------------------------------------------
  1066. for( int i = 0; i < lCount; ++i )
  1067. {
  1068. FbxPropertyEntry* lParentEntry = mInstanceOf->ChangePropertyEntryState( (FbxInt)i,FbxPropertyFlags::eOverride );
  1069. FbxPropertyEntry* lEntry = GetPropertyEntry( (FbxInt)i );
  1070. if( !lParentEntry )
  1071. {
  1072. lParentEntry = FbxPropertyEntry::Create( lEntry->GetParentId(), 0, 0, 0 );
  1073. mInstanceOf->mEntryMap.Insert( i, lParentEntry );
  1074. //mInstanceOf->AddChild(i);
  1075. }
  1076. FBX_ASSERT( lParentEntry );
  1077. // Add it to the parent
  1078. // Don't touch the connections
  1079. // -----------------------------------------
  1080. if (lParentEntry) {
  1081. lParentEntry->Set( lEntry->Get(FBX_TYPE(FbxPropertyInfo)) );
  1082. lParentEntry->Set( lEntry->Get(FBX_TYPE(FbxPropertyValue)) );
  1083. lParentEntry->Set( lEntry->Get(FBX_TYPE(FbxPropertyFlags)) );
  1084. }
  1085. /*
  1086. else {
  1087. mInstanceOf->Add(
  1088. lEntry->GetParentId(),
  1089. lEntry->Get(FBX_TYPE(FbxPropertyInfo)), // The info
  1090. lEntry->Get(FBX_TYPE(FbxPropertyValue)), // The Value
  1091. 0, // The connections
  1092. false,
  1093. false
  1094. );
  1095. }
  1096. */
  1097. // Empty the current entry
  1098. // Don't touch the connections
  1099. // -----------------------------------------
  1100. ChangePropertyItemState(FBX_TYPE(FbxPropertyInfo), i,FbxPropertyFlags::eInherit);
  1101. ChangePropertyItemState(FBX_TYPE(FbxPropertyValue), i,FbxPropertyFlags::eInherit);
  1102. ChangePropertyItemState(FBX_TYPE(FbxPropertyFlags), i,FbxPropertyFlags::eInherit);
  1103. }
  1104. }
  1105. }
  1106. inline const FbxPropertyPage* GetInstanceOf() const { return mInstanceOf; }
  1107. inline FbxPropertyPage* GetInstanceOf() { return mInstanceOf; }
  1108. inline const FbxArray<FbxPropertyPage*>& GetInstances() const { return mInstances; }
  1109. inline FbxArray<FbxPropertyPage*>& GetInstances() { return mInstances; }
  1110. // Flags
  1111. // ------------------------------------------
  1112. FbxPropertyFlags::EFlags GetFlags(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT) const
  1113. {
  1114. FbxPropertyPage* lFoundIn = NULL;
  1115. FbxPropertyFlags* lPropertyFlags = GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn );
  1116. FbxPropertyFlags::EFlags lFlags = FbxPropertyFlags::eNone;
  1117. if( lPropertyFlags )
  1118. {
  1119. if( !mInstanceOf ) // no inheritance.
  1120. lFlags = lPropertyFlags->GetFlags();
  1121. else
  1122. {
  1123. lFlags = mInstanceOf->GetFlags(pId);
  1124. lFlags = lPropertyFlags->GetMergedFlags(lFlags);
  1125. }
  1126. }
  1127. return lFlags;
  1128. }
  1129. bool ModifyFlags(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT,FbxPropertyFlags::EFlags pFlags=FbxPropertyFlags::eNone,bool pValue=true,bool pCheckFlagEquality=true)
  1130. {
  1131. if( pCheckFlagEquality )
  1132. {
  1133. FbxPropertyPage* lFoundIn = NULL;
  1134. FbxPropertyFlags* lFlag = GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn );
  1135. if( lFlag )
  1136. {
  1137. if( lFoundIn == this )
  1138. {
  1139. // set them in us.
  1140. lFlag->ModifyFlags( pFlags, pValue );
  1141. // we override this entry, check if we need to revert
  1142. FbxPropertyFlags* lInheritedFlags = mInstanceOf ? mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId ) : NULL;
  1143. if( lInheritedFlags && lInheritedFlags->Equal( *lFlag, pFlags ) )
  1144. {
  1145. lFlag->UnsetMask( pFlags );
  1146. if( lFlag->GetMask() == 0 )
  1147. ChangePropertyItemState( FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eInherit );
  1148. return true;
  1149. }
  1150. }
  1151. else
  1152. {
  1153. // its not us. Just check if we need to set.
  1154. FbxPropertyFlags lNewValues( pFlags );
  1155. if( lFlag->Equal( lNewValues, pFlags ) )
  1156. return true;
  1157. }
  1158. }
  1159. }
  1160. FbxPropertyFlags* lPropertyFlags = ChangePropertyItemState(FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eOverride);
  1161. return lPropertyFlags ? lPropertyFlags->ModifyFlags( pFlags, pValue ) : false;
  1162. }
  1163. FbxPropertyFlags::EInheritType GetFlagsInheritType(FbxPropertyFlags::EFlags pFlags, bool pCheckInstanceOf, FbxInt pId=FBXSDK_PROPERTY_ID_ROOT) const
  1164. {
  1165. FbxPropertyPage* lFoundIn = NULL;
  1166. FbxPropertyFlags* lPropertyFlags = GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn );
  1167. if( !pCheckInstanceOf )
  1168. return lFoundIn != this ? FbxPropertyFlags::eInherit : ( lPropertyFlags ? lPropertyFlags->GetFlagsInheritType(pFlags) : FbxPropertyFlags::eInherit );
  1169. else
  1170. {
  1171. // This code basically counts the number of overrides for the
  1172. // given flags. The original entry is always considered an override.
  1173. // so if we see more than one, something overrode the original.
  1174. // and thus we are an override.
  1175. FbxPropertyPage* lRefPage = lFoundIn;
  1176. bool lFoundOverride = false;
  1177. while( lRefPage )
  1178. {
  1179. lPropertyFlags = lRefPage->GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId );
  1180. if( !lPropertyFlags )
  1181. break; // gone too far, break.
  1182. if( lPropertyFlags->GetFlagsInheritType( pFlags ) == FbxPropertyFlags::eOverride )
  1183. {
  1184. if( this == lRefPage || lFoundOverride )
  1185. return FbxPropertyFlags::eOverride; // found two overrides or this page is the override.
  1186. else
  1187. lFoundOverride = true; // signal that we found the first override.
  1188. }
  1189. lRefPage = lRefPage->mInstanceOf;
  1190. }
  1191. return FbxPropertyFlags::eInherit;
  1192. }
  1193. }
  1194. bool SetFlagsInheritType(FbxPropertyFlags::EInheritType pInheritType, FbxPropertyFlags::EFlags pFlags, FbxInt pId=FBXSDK_PROPERTY_ID_ROOT)
  1195. {
  1196. FbxPropertyPage* lFoundIn = NULL;
  1197. FbxPropertyFlags* lPropertyFlags = NULL;
  1198. if( FbxPropertyFlags::eOverride == pInheritType )
  1199. {
  1200. lPropertyFlags = ChangePropertyItemState( FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eOverride );
  1201. // we should initialize our flag to the inherited value, if any.
  1202. FbxPropertyFlags* lParentFlags = mInstanceOf ? mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId ) : NULL;
  1203. if( lParentFlags && lPropertyFlags )
  1204. {
  1205. FbxPropertyFlags::EFlags lParentValues = lParentFlags->GetFlags();
  1206. lPropertyFlags->SetFlags( pFlags, lParentValues );
  1207. return lPropertyFlags->SetMask( pFlags );
  1208. }
  1209. return false;
  1210. }
  1211. else if( FbxPropertyFlags::eInherit == pInheritType )
  1212. {
  1213. lPropertyFlags = GetPropertyItem(FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn);
  1214. if( !lPropertyFlags ) return false;
  1215. if( lFoundIn != this ) return true; // not us
  1216. lPropertyFlags->UnsetMask( pFlags );
  1217. if( lPropertyFlags->GetMask() == 0 ) // revert
  1218. ChangePropertyItemState( FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eInherit );
  1219. return true;
  1220. }
  1221. return false;
  1222. }
  1223. inline void BeginCreateOrFindProperty()
  1224. {
  1225. if( 0 == mNameMap.mFirst )
  1226. {
  1227. mNameMap.mSecond.Reserve(20);
  1228. // push the existing properties into the map. Note: this includes the root property!
  1229. FbxInt lFoundId = FBXSDK_PROPERTY_ID_ROOT;
  1230. FbxPropertyEntry* lEntry = GetPropertyEntry(lFoundId);
  1231. while(lFoundId != FBXSDK_PROPERTY_ID_NULL)
  1232. {
  1233. FbxPropertyInfo* lInfo = lEntry->Get(FBX_TYPE(FbxPropertyInfo));
  1234. //FBX_ASSERT( lInfo );
  1235. if (lInfo)
  1236. {
  1237. mNameMap.mSecond.Insert(FbxNameMapKey(lEntry->GetParentId(), lInfo->GetName()), lFoundId);
  1238. }
  1239. lFoundId = GetMinimumPropertyIdAndEntry(lFoundId, &lEntry);
  1240. }
  1241. mNameMap.mFirst++;
  1242. }
  1243. }
  1244. inline void EndCreateOrFindProperty()
  1245. {
  1246. if( mNameMap.mFirst > 0 )
  1247. {
  1248. if( --(mNameMap.mFirst) == 0 )
  1249. mNameMap.mSecond.Clear();
  1250. }
  1251. }
  1252. protected:
  1253. FbxPropertyPage(FbxPropertyPage* pInstanceOf=0)
  1254. : mInstanceOf(0)
  1255. , mDataPtr(0)
  1256. , mPropNextId(0)
  1257. {
  1258. mEntryMap.Reserve(32);
  1259. mNameMap.mFirst = 0;
  1260. // instances don't need to create a root property
  1261. if( !pInstanceOf )
  1262. {
  1263. mPropNextId = FbxNew< FbxPropertyIdGenerator >();
  1264. mPropNextId->IncRef();
  1265. // First item is the root information
  1266. Add(FBXSDK_PROPERTY_ID_NULL,"",eFbxUndefined);
  1267. }
  1268. // Hook the instances
  1269. // ------------------------
  1270. mInstanceOf = pInstanceOf;
  1271. if (mInstanceOf) {
  1272. mInstanceOf->mInstances.Add(this);
  1273. mPropNextId = mInstanceOf->mPropNextId;
  1274. mPropNextId->IncRef();
  1275. }
  1276. }
  1277. FbxPropertyPage(const char* pName, EFbxType pType)
  1278. : mInstanceOf(0)
  1279. , mDataPtr(0)
  1280. , mPropNextId(0)
  1281. {
  1282. mEntryMap.Reserve(32);
  1283. mNameMap.mFirst = 0;
  1284. mPropNextId = FbxNew< FbxPropertyIdGenerator >();
  1285. mPropNextId->IncRef();
  1286. // First item is the root information
  1287. Add(FBXSDK_PROPERTY_ID_NULL,pName,pType);
  1288. }
  1289. FbxPropertyPage(const char* pName, FbxPropertyPage* pTypeInfo)
  1290. : mInstanceOf(0)
  1291. , mDataPtr(0)
  1292. , mPropNextId(0)
  1293. {
  1294. mEntryMap.Reserve(32);
  1295. mNameMap.mFirst = 0;
  1296. mPropNextId = FbxNew< FbxPropertyIdGenerator >();
  1297. mPropNextId->IncRef();
  1298. // First item is the root information
  1299. Add(FBXSDK_PROPERTY_ID_NULL,pName,pTypeInfo);
  1300. }
  1301. ~FbxPropertyPage()
  1302. {
  1303. // Propagate our property entries.
  1304. int i = 0, j = 0;
  1305. for( i = 0; i < mInstances.GetCount(); ++i )
  1306. {
  1307. for( j = 0; j < GetPropertyEntryCount(); ++j )
  1308. {
  1309. if( mInstances[i]->ChangePropertyEntryState((FbxInt)j, FbxPropertyFlags::eOverride) )
  1310. {
  1311. // Clone the info and values. Don't clone the connections,
  1312. // since they aren't propagated.
  1313. mInstances[i]->ChangePropertyItemState( FBX_TYPE(FbxPropertyInfo), (FbxInt)j, FbxPropertyFlags::eOverride );
  1314. mInstances[i]->ChangePropertyItemState( FBX_TYPE(FbxPropertyValue), (FbxInt)j, FbxPropertyFlags::eOverride );
  1315. // Since all entries have their own flags, just override the ones in the instance.
  1316. mInstances[i]->SetFlagsInheritType(FbxPropertyFlags::eOverride, FbxPropertyFlags::eAllFlags, (FbxInt)j );
  1317. }
  1318. }
  1319. // Instances become their own copies.
  1320. mInstances[i]->mInstanceOf = NULL;
  1321. }
  1322. FbxMapDestroy(mEntryMap);
  1323. if (mInstanceOf) {
  1324. int lIndex = mInstanceOf->mInstances.Find(this);
  1325. mInstanceOf->mInstances.SetAt(lIndex, mInstanceOf->mInstances[mInstanceOf->mInstances.GetCount()-1]);
  1326. mInstanceOf->mInstances.RemoveAt(mInstanceOf->mInstances.GetCount()-1);
  1327. //mInstanceOf->mInstances.RemoveIt(this);
  1328. }
  1329. mPropNextId->DecRef();
  1330. mPropNextId = NULL;
  1331. mInstanceOf = NULL;
  1332. mInstances.Clear();
  1333. }
  1334. inline bool Is(FbxPropertyPage* pPage)
  1335. {
  1336. // @@@@@@@@@@@@@@@ Must complete for sub types
  1337. return this==pPage;
  1338. }
  1339. // Internal entry management
  1340. private:
  1341. /** Retrieves the smallest property id of which are larger than a specified one.
  1342. * \param pId The specified property id
  1343. * \param pIncrementIfNone Whether it returns FBXSDK_PROPERTY_ID_NULL or pId+1, if not found.
  1344. * \return The property id described above.
  1345. */
  1346. FbxInt GetMinimumPropertyId(FbxInt pId, bool pIncrementIfNone = true) const
  1347. {
  1348. if( pId == FBXSDK_PROPERTY_ID_NULL )
  1349. pId = FBXSDK_PROPERTY_ID_ROOT;
  1350. FbxInt lMin = FBXSDK_PROPERTY_ID_NULL;
  1351. const EntryMap::RecordType* lElement = mEntryMap.UpperBound(pId);
  1352. if (NULL != lElement)
  1353. {
  1354. lMin = lElement->GetKey();
  1355. }
  1356. FbxInt lParentMin = mInstanceOf ? mInstanceOf->GetMinimumPropertyId(pId,false) : FBXSDK_PROPERTY_ID_NULL;
  1357. bool lParentNull = lParentMin == FBXSDK_PROPERTY_ID_NULL;
  1358. bool lMinNull = lMin == FBXSDK_PROPERTY_ID_NULL;
  1359. if( lParentNull && lMinNull ) return pIncrementIfNone ? pId+1 : FBXSDK_PROPERTY_ID_NULL;
  1360. else if( lMinNull ) lMin = lParentMin;
  1361. else if( !lParentNull ) lMin = lMin < lParentMin ? lMin : lParentMin;
  1362. return lMin;
  1363. }
  1364. /** Retrieves the smallest property id of which are larger than a specified one, and retrieve its entry.
  1365. * \param pId The specified property id
  1366. * \param pEntry The returned property entry
  1367. * \return The property id described above.
  1368. */
  1369. FbxInt GetMinimumPropertyIdAndEntry(FbxInt pId, FbxPropertyEntry** pEntry) const
  1370. {
  1371. FbxInt lFoundId = FBXSDK_PROPERTY_ID_NULL;
  1372. FbxPropertyEntry* lFoundEntry = NULL;
  1373. if( pId == FBXSDK_PROPERTY_ID_NULL )
  1374. pId = FBXSDK_PROPERTY_ID_ROOT;
  1375. const EntryMap::RecordType* lElement = mEntryMap.UpperBound(pId);
  1376. if (NULL != lElement)
  1377. {
  1378. lFoundId = lElement->GetKey();
  1379. lFoundEntry = lElement->GetValue();
  1380. }
  1381. FbxPropertyEntry* lParentEntry = NULL;
  1382. FbxInt lParentMin = mInstanceOf ? mInstanceOf->GetMinimumPropertyIdAndEntry(pId, &lParentEntry) : FBXSDK_PROPERTY_ID_NULL;
  1383. bool lParentNull = lParentMin == FBXSDK_PROPERTY_ID_NULL;
  1384. bool lMinNull = lFoundId == FBXSDK_PROPERTY_ID_NULL;
  1385. if( lMinNull && !lParentNull )
  1386. {
  1387. lFoundId = lParentMin;
  1388. lFoundEntry = lParentEntry;
  1389. }
  1390. else if( !lMinNull && !lParentNull )
  1391. {
  1392. lFoundId = lFoundId < lParentMin ? lFoundId : lParentMin;
  1393. lFoundEntry = lFoundId < lParentMin ? lFoundEntry : lParentEntry;
  1394. }
  1395. if (pEntry)
  1396. *pEntry = lFoundEntry;
  1397. return lFoundId;
  1398. }
  1399. int GetPropertyEntryCount() const
  1400. {
  1401. int lCount = 0;
  1402. const EntryMap::RecordType* lElement = mEntryMap.Maximum();
  1403. if (NULL != lElement)
  1404. {
  1405. lCount = lElement->GetKey() + 1;
  1406. }
  1407. int lParentCount = mInstanceOf ? mInstanceOf->GetPropertyEntryCount() : 0;
  1408. return lParentCount > lCount ? lParentCount : lCount;
  1409. }
  1410. FbxPropertyEntry* GetPropertyEntry(FbxInt pIndex,FbxPropertyPage **pFoundIn=0) const
  1411. {
  1412. const EntryMap::RecordType* lElement = mEntryMap.Find(pIndex);
  1413. if (NULL != lElement)
  1414. {
  1415. if( pFoundIn )
  1416. {
  1417. *pFoundIn = const_cast<FbxPropertyPage*>(this);
  1418. }
  1419. return lElement->GetValue();
  1420. }
  1421. if( pFoundIn )
  1422. {
  1423. *pFoundIn = 0;
  1424. }
  1425. return mInstanceOf ? mInstanceOf->GetPropertyEntry(pIndex,pFoundIn) : 0;
  1426. }
  1427. FbxPropertyEntry* ChangePropertyEntryState(FbxInt pIndex,FbxPropertyFlags::EInheritType pInheritType)
  1428. {
  1429. FbxPropertyPage* lReferencePage = 0;
  1430. FbxPropertyEntry* lReferenceEntry = GetPropertyEntry(pIndex,&lReferencePage);
  1431. if (pInheritType==FbxPropertyFlags::eOverride) {
  1432. if (lReferencePage==this) {
  1433. return lReferenceEntry;
  1434. } else if (lReferenceEntry) {
  1435. // must create an entry
  1436. FbxPropertyEntry* lEntry = FbxPropertyEntry::Create(lReferenceEntry->GetParentId(),0,0,0);
  1437. mEntryMap.Insert( pIndex, lEntry );
  1438. return lEntry;
  1439. }
  1440. } else {
  1441. if (lReferenceEntry && (lReferencePage==this)) {
  1442. mEntryMap.Remove(pIndex);
  1443. lReferenceEntry->Destroy();
  1444. }
  1445. }
  1446. return 0;
  1447. }
  1448. FbxInt Add(FbxInt pParentId,FbxPropertyInfo* pInfo,FbxPropertyValue* pValue,FbxPropertyConnect* pConnect,bool pRecursive=true)
  1449. {
  1450. FbxInt lId = mPropNextId->GetNextIdAndInc();
  1451. FbxPropertyEntry* lEntry = FbxPropertyEntry::Create(pParentId,pInfo,pValue,pConnect);
  1452. // entries created through Add() are not overrides of another entry.
  1453. // Thus, set all of their flags by default.
  1454. FbxPropertyFlags* lFlags = lEntry->Get( FBX_TYPE(FbxPropertyFlags) );
  1455. if( lFlags ) lFlags->ModifyFlags( FbxPropertyFlags::eAllFlags, false );
  1456. mEntryMap.Insert( lId, lEntry );
  1457. // We only add to the map if this Add is called after BeginCreateOrFindProperty()
  1458. // in which case the size is always > 0 because it includes the root property
  1459. if( mNameMap.mSecond.GetSize() > 0 )
  1460. mNameMap.mSecond.Insert( FbxNameMapKey( pParentId, pInfo->GetName()), lId );
  1461. // If the entry has multiple children(Struct Datatype)
  1462. // Recurse for the entries and create an entry in this structure
  1463. if (pRecursive) {
  1464. FbxPropertyPage* lTypeInfo = pInfo->GetTypeInfo();
  1465. if (lTypeInfo) {
  1466. FbxInt lChildId;
  1467. lChildId = lTypeInfo->GetChild();
  1468. while (lChildId!=FBXSDK_PROPERTY_ID_NULL) {
  1469. FbxPropertyInfo* lPropertyInfo = lTypeInfo->GetPropertyItem( FBX_TYPE(FbxPropertyInfo),lChildId );
  1470. FbxPropertyValue* lPropertyValue = lTypeInfo->GetPropertyItem( FBX_TYPE(FbxPropertyValue),lChildId );
  1471. FbxPropertyConnect* lPropertyConnect = lTypeInfo->GetPropertyItem( FBX_TYPE(FbxPropertyConnect),lChildId );
  1472. Add ( lId, lPropertyInfo ? lPropertyInfo->Clone(this) : 0 , lPropertyValue ? lPropertyValue->Clone(this) : 0,
  1473. lPropertyConnect ? lPropertyConnect->Clone(this) : 0 );
  1474. lChildId = lTypeInfo->GetSibling(lChildId );
  1475. }
  1476. }
  1477. }
  1478. return lId;
  1479. }
  1480. // Property management
  1481. typedef FbxMap<FbxInt, FbxPropertyEntry*, FbxLessCompare<FbxInt>, FbxHungryAllocator> EntryMap;
  1482. EntryMap mEntryMap;
  1483. // instance management
  1484. FbxPropertyPage* mInstanceOf;
  1485. FbxArray<FbxPropertyPage*> mInstances;
  1486. void* mDataPtr;
  1487. // speed up structure
  1488. typedef FbxMap<FbxNameMapKey, FbxInt, FbxNameMapCompare > NameMap;
  1489. typedef FbxPair<unsigned int, NameMap > NameLookupPair;
  1490. NameLookupPair mNameMap;
  1491. FbxPropertyIdGenerator* mPropNextId;
  1492. friend class FbxPropertyHandle;
  1493. };
  1494. #include <fbxsdk/fbxsdk_nsend.h>
  1495. #endif /* _FBXSDK_CORE_PROPERTY_PAGE_H_ */