FBX C++ API Reference
fbxpropertypage.h
Go to the documentation of this file.
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 
13 #ifndef _FBXSDK_CORE_PROPERTY_PAGE_H_
14 #define _FBXSDK_CORE_PROPERTY_PAGE_H_
15 
16 #include <fbxsdk/fbxsdk_def.h>
17 
20 #include <fbxsdk/core/fbxobject.h>
21 #include <fbxsdk/core/fbxsymbol.h>
23 
24 #include <fbxsdk/fbxsdk_nsbegin.h>
25 
27 
29 {
30  inline int operator()(const FbxNameMapKey& pKeyA, const FbxNameMapKey& pKeyB) const
31  {
32  if( pKeyA.mFirst < pKeyB.mFirst ) return -1;
33  else if( pKeyA.mFirst > pKeyB.mFirst ) return 1;
34  return strcmp(pKeyA.mSecond, pKeyB.mSecond);
35  }
36 };
37 
39 {
40 public:
42  static FbxPropertyInfo* Create(const char* pName, FbxPropertyPage* pTypeInfo) { return FbxNew< FbxPropertyInfo >(pName,pTypeInfo); }
43  static FbxPropertyInfo* Create(const char* pName, EFbxType pType=eFbxUndefined) { return FbxNew< FbxPropertyInfo >(pName,pType); }
44  void Destroy() { FbxDelete(this); }
46  {
47  // @@@@@ Filter is missing
48  // @@@@@ Clone is incomplete
49  if (mTypeInfo)
50  {
51  return FbxNew< FbxPropertyInfo >(mName,mTypeInfo);
52  }
53  else
54  {
55  return FbxNew< FbxPropertyInfo >(mName,mType);
56  }
57  }
58 
59  inline void IncRef() { mRef++; }
60  inline void DecRef() { mRef--; if (mRef==0) FbxDelete(this); }
61  inline int GetRef() { return mRef; }
62 
63  // Labels and Types
64 
65  inline FbxStringSymbol GetName() const { return mName; }
66  EFbxType GetType() const;
67  FbxPropertyPage* GetTypeInfo() const { return mTypeInfo; }
68 
69  inline void SetLabel(const char* pLabel) { mLabel=pLabel; }
70  inline const char* GetLabel() const { return mLabel.IsEmpty() ? "" : ((const char*)mLabel); }
71 
72  inline void SetUserTag(int pUserTag) { mUserTag=pUserTag; }
73  inline int GetUserTag() const { return mUserTag; }
74 
75  inline void SetUserData(const void* pUserData) { mUserData=(void*)pUserData; }
76  inline void* GetUserData() const { return mUserData; }
77 
78  // Enum list
79  int AddEnumValue(const char* pStringValue)
80  {
81  EFbxType lType = GetType();
82  if (lType == eFbxEnum || lType == eFbxEnumM)
83  {
84  if (!mEnumList)
85  mEnumList.Reset(FbxNew< FbxStringList >());
86 
87  bool lCanAdd = (lType == eFbxEnumM || mEnumList->FindIndex( pStringValue ) == -1);
88  if( lCanAdd )
89  return mEnumList->Add((char*)pStringValue);
90  }
91  return -1;
92  }
93 
94  void InsertEnumValue(int pIndex, const char* pStringValue)
95  {
96  EFbxType lType = GetType();
97  if (lType == eFbxEnum || lType == eFbxEnumM)
98  {
99  if (!mEnumList)
100  mEnumList.Reset(FbxNew< FbxStringList >());
101 
102  bool lCanAdd = (lType == eFbxEnumM || mEnumList->FindIndex( pStringValue ) == -1);
103  if( lCanAdd )
104  mEnumList->InsertAt(pIndex,(char*)pStringValue);
105  }
106  }
107 
109  {
110  return mEnumList ? mEnumList->GetCount() : 0;
111  }
112 
113  void SetEnumValue(int pIndex, const char* pStringValue)
114  {
115  EFbxType lType = GetType();
116  if (lType == eFbxEnum || lType == eFbxEnumM)
117  {
118  if (!mEnumList)
119  mEnumList.Reset(FbxNew< FbxStringList >());
120 
121  bool lCanAdd = (lType == eFbxEnumM || mEnumList->FindIndex( pStringValue ) == -1);
122  if (lCanAdd)
123  mEnumList->SetStringAt(pIndex,(char*)pStringValue);
124  }
125  }
126 
127  void RemoveEnumValue(int pIndex)
128  {
129  EFbxType lType = GetType();
130  if (lType == eFbxEnum || lType == eFbxEnumM)
131  {
132  if (!mEnumList)
133  mEnumList.Reset(FbxNew< FbxStringList >());
134 
135  mEnumList->RemoveAt(pIndex);
136  }
137  }
138 
139  char* GetEnumValue(int pIndex)
140  {
141  char* lValue = NULL;
142  EFbxType lType = GetType();
143  if (lType == eFbxEnum || lType == eFbxEnumM)
144  {
145  lValue = mEnumList ? mEnumList->GetStringAt(pIndex) : 0;
146  }
147  return lValue;
148  }
149 
150 
151  // Min and Max values
152  enum EValueIndex {eValueMin, eValueSoftMin, eValueMax, eValueSoftMax, eValueCount};
153 
154  bool HasMinMax(EValueIndex pId) const
155  {
156  return mMinMaxValue[pId] != NULL;
157  }
158 
159  bool GetMinMax(EValueIndex pId, void* pValue, EFbxType pValueType) const
160  {
161  if (mMinMaxValue[pId]) {
162  return FbxTypeCopy(pValue, pValueType, mMinMaxValue[pId], GetType());
163  }
164  return false;
165  }
166 
167  bool SetMinMax(EValueIndex pId, const void* pValue, EFbxType pValueType)
168  {
169  if (!mMinMaxValue[pId]) {
170  size_t lSize = FbxTypeSizeOf(GetType());
171  if (lSize) {
172  mMinMaxValue[pId] = FbxMalloc(lSize);
173  }
174  }
175  if (mMinMaxValue[pId]) {
176  return FbxTypeCopy(mMinMaxValue[pId], GetType(), pValue, pValueType);
177  }
178  return false;
179  }
180 
181 private:
182  FbxPropertyInfo(const char* pName, FbxPropertyPage* pTypeInfo)
183  : mRef(0)
184  , mName(pName)
185  , mType(eFbxUndefined)
186  , mTypeInfo(pTypeInfo)
187  , mUserTag(0)
188  , mUserData(0)
189  , mFilter(0)
190  {
191  for (int i=0; i<eValueCount; i++) {
192  mMinMaxValue[i] = 0;
193  }
194  }
195 
197  : mRef(0)
198  , mName(pName)
199  , mType(eFbxUndefined)
200  , mTypeInfo(pTypeInfo)
201  , mUserTag(0)
202  , mUserData(0)
203  , mFilter(0)
204  {
205  for (int i=0; i<eValueCount; i++) {
206  mMinMaxValue[i] = 0;
207  }
208  }
209 
210  FbxPropertyInfo(const char* pName, EFbxType pType)
211  : mRef(0)
212  , mName(pName)
213  , mType(pType)
214  , mTypeInfo(0)
215  , mUserTag(0)
216  , mUserData(0)
217  , mFilter(0)
218  {
219  for (int i=0; i<eValueCount; i++) {
220  mMinMaxValue[i] = 0;
221  }
222  }
223  ~FbxPropertyInfo()
224  {
225  for (int i=eValueMin; i<eValueCount; i++) {
226  FbxFree(mMinMaxValue[i]);
227  }
228  }
229 
230  int mRef;
231  FbxStringSymbol mName;
232  FbxStringSymbol mLabel;
233  EFbxType mType;
234  FbxPropertyPage* mTypeInfo;
235  int mUserTag;
236  void* mMinMaxValue[eValueCount];
237  void* mUserData;
238  FbxConnectionPointFilter* mFilter;
240 };
241 
242 #if defined(FBXSDK_COMPILER_MSC)
243  #pragma warning (push)
244  #pragma warning (disable: 4355)
245 #endif
246 
248 {
249 public:
251  static FbxPropertyConnect* Create(FbxPropertyPage* pPage,FbxInt pId) { return FbxNew< FbxPropertyConnect >(pPage,pId); }
252  void Destroy() { FbxDelete(this); }
254  {
255  return FbxNew< FbxPropertyConnect >(pPage,mId);
256  }
257 
258  inline void IncRef() { mRef++; }
259  inline void DecRef() { mRef--; if (mRef==0) FbxDelete(this); }
260  inline int GetRef() { return mRef; }
261 
262 // Properties
263  FbxPropertyPage* GetPage() { return mPage; }
264  FbxInt GetPropertyId() { return mId; }
265 
266 // ClearConnectCache()
267 // ------------------------------------------------------
268  inline void ClearConnectCache()
269  {
270  mConnectionPoint.SubConnectRemoveAll();
271  }
272 
274  inline void WipeAllConnections()
275  {
276  mConnectionPoint.WipeConnectionList();
277  }
278 
279 // Properties
281  {
282  return mConnectionPoint.ConnectSrc(&pSrc->mConnectionPoint,pType);
283  }
285  {
286  return mConnectionPoint.DisconnectSrc(&pSrc->mConnectionPoint);
287  }
289  {
290  return mConnectionPoint.IsConnectedSrc(&pSrc->mConnectionPoint);
291  }
293  {
294  return mConnectionPoint.GetSrcCount(pFilter);
295  }
296  inline FbxPropertyConnect* GetSrc(FbxConnectionPointFilter* pFilter, int pIndex)
297  {
298  FbxConnectionPoint *lCP = mConnectionPoint.GetSrc(pIndex,pFilter);
299  return lCP ? (FbxPropertyConnect * )lCP->GetData() : 0;
300  }
302  {
303  return mConnectionPoint.ConnectDst(&pDst->mConnectionPoint,pType);
304  }
306  {
307  return mConnectionPoint.IsConnectedSrc(&pSrc->mConnectionPoint);
308  }
310  {
311  return mConnectionPoint.DisconnectDst(&pDst->mConnectionPoint);
312  }
314  {
315  return mConnectionPoint.GetDstCount(pFilter);
316  }
317  inline FbxPropertyConnect* GetDst(FbxConnectionPointFilter* pFilter, int pIndex)
318  {
319  FbxConnectionPoint *lCP = mConnectionPoint.GetDst(pIndex,pFilter);
320  return lCP ? (FbxPropertyConnect * )lCP->GetData() : 0;
321  }
322 
323  int mRef;
327 
328 private:
330  mRef(0),
331  mConnectionPoint(this),
332  mPage(pPage),
333  mId(pId)
334  {
335  }
336 
337  ~FbxPropertyConnect(){ if( FbxObject::GetWipeMode() ) mConnectionPoint.WipeConnectionList(); }
338 };
339 
340 #if defined(FBXSDK_COMPILER_MSC)
341  #pragma warning (pop)
342 #endif
343 
345 {
346 public:
347  static FbxPropertyEntry* Create(FbxInt pParentId, FbxPropertyInfo* pInfo, FbxPropertyValue* pValue, FbxPropertyConnect* pConnect){ return FbxNew<FbxPropertyEntry>(pParentId, pInfo, pValue, pConnect); }
348 
349  void Destroy() { FbxDelete(this); }
350 
351  inline FbxInt GetParentId(){ return mParentId; }
352  inline bool IsEmpty(){ return (mInfo || mValue || mConnect || mFlags.GetMask() != 0) ? false : true; }
353 
354  inline FbxPropertyInfo* Get(const FbxPropertyInfo* /*pType*/){ return mInfo; }
355 
356  void Set(FbxPropertyInfo* pInfo)
357  {
358  FbxPropertyInfo* lInfo = mInfo;
359  if( pInfo ) pInfo->IncRef();
360  mInfo = pInfo;
361  if( lInfo ) lInfo->DecRef();
362  }
363 
364  inline FbxPropertyValue* Get(const FbxPropertyValue* /*pType*/){ return mValue; }
365 
366  void Set(FbxPropertyValue* pValue)
367  {
368  FbxPropertyValue* lValue = mValue;
369  if( pValue ) pValue->IncRef();
370  mValue = pValue;
371  if( lValue ) lValue->DecRef();
372  }
373 
374  inline FbxPropertyConnect* Get(const FbxPropertyConnect* /*pType*/){ return mConnect; }
375 
376  void Set(FbxPropertyConnect* pConnect)
377  {
378  FbxPropertyConnect* lConnect = mConnect;
379  if( pConnect ) pConnect->IncRef();
380  mConnect = pConnect;
381  if( lConnect ) lConnect->DecRef();
382  }
383 
384  inline FbxPropertyFlags* Get(const FbxPropertyFlags* /*pType*/){ return &mFlags; }
385  inline void Set(FbxPropertyFlags pType){ mFlags = pType; }
386  inline void Set(FbxPropertyFlags* pType){ mFlags = pType ? *pType : FbxPropertyFlags(FbxPropertyFlags::eNone); }
387 
388 private:
389  FbxPropertyEntry(FbxInt pParentId,FbxPropertyInfo *pInfo,FbxPropertyValue *pValue,FbxPropertyConnect *pConnect) :
390  mInfo(pInfo),
391  mValue(pValue),
392  mConnect(pConnect),
393  mParentId(pParentId),
394  mFlags(FbxPropertyFlags::eNone)
395  {
396  if( mInfo ) mInfo->IncRef();
397  if( mValue ) mValue->IncRef();
398  if( mConnect ) mConnect->IncRef();
399  }
400 
402  {
403  if( mInfo ) mInfo->DecRef();
404  if( mValue ) mValue->DecRef();
405  if( mConnect ) mConnect->DecRef();
406  }
407 
408  FbxPropertyInfo* mInfo;
409  FbxPropertyValue* mValue;
410  FbxPropertyConnect* mConnect;
411  FbxInt mParentId;
412  FbxPropertyFlags mFlags;
413 
415  friend class FbxPropertyPage;
416 };
417 
419 {
420 public:
421  FbxPropertyIdGenerator() : mRef(0), mNextId(0) {}
422 
423  inline FbxInt GetNextId() const { return mNextId; }
424  inline FbxInt GetNextIdAndInc() { return mNextId++; }
425 
426  inline void IncRef() { mRef++; }
427  inline void DecRef() { mRef--; if( mRef == 0 ) FbxDelete(this); }
428 
429 private:
430  FbxInt mRef, mNextId;
431 };
432 
434 {
435 
436 public:
438  static FbxPropertyPage* Create (FbxPropertyPage* pInstanceOf=0) { return FbxNew< FbxPropertyPage >(pInstanceOf); }
439  static FbxPropertyPage* Create (const char* pName, FbxPropertyPage* pTypeInfo) { return FbxNew< FbxPropertyPage >(pName,pTypeInfo); }
440  static FbxPropertyPage* Create (const char* pName, EFbxType pType=eFbxUndefined) { return FbxNew< FbxPropertyPage >(pName,pType); }
441  void Destroy() { FbxDelete(this); }
442 
443  template<class T> inline T* GetPropertyItem(const T* pItemType,FbxInt pIndex,FbxPropertyPage **pFoundIn=0) const
444  {
445  FbxPropertyPage* lReferencePage = 0;
446  FbxPropertyEntry* lReferenceEntry = GetPropertyEntry(pIndex,&lReferencePage);
447  if (pFoundIn) *pFoundIn = 0;
448  if (lReferenceEntry) {
449  T* lItem = lReferenceEntry->Get( FBX_TYPE(T) );
450  if (lItem) {
451  if (pFoundIn) *pFoundIn = lReferencePage;
452  return lItem;
453  } else {
454  return lReferencePage->mInstanceOf ? lReferencePage->mInstanceOf->GetPropertyItem(pItemType,pIndex,pFoundIn) : 0 ;
455  }
456  }
457  return 0;
458  }
459 
460  template<class T> inline T* ChangePropertyItemState(const T* pItemType, FbxInt pIndex, FbxPropertyFlags::EInheritType pInheritType)
461  {
462  FbxPropertyPage* lReferencePage = NULL;
463  T* lItem = GetPropertyItem(pItemType, pIndex, &lReferencePage);
464  if( pInheritType == FbxPropertyFlags::eOverride )
465  {
466  if( lReferencePage == this )
467  {
468  return lItem;
469  }
470  else if( lItem )
471  {
472  FbxPropertyEntry* lEntry = ChangePropertyEntryState(pIndex, FbxPropertyFlags::eOverride);
473  lEntry->Set(lItem->Clone(this));
474  return lEntry->Get(FBX_TYPE(T));
475  }
476  }
477  else
478  {
479  // can't inherit entries that were created on our page.
480  bool lOwnEntry = !mInstanceOf || (mInstanceOf->GetPropertyItem(pItemType, pIndex) == NULL);
481  if( lOwnEntry && FbxPropertyFlags::eInherit == pInheritType) return 0;
482 
483  if( lItem && (lReferencePage == this) )
484  {
485  FbxPropertyEntry* lEntry = GetPropertyEntry(pIndex);
486  lEntry->Set((T*)0);
487  if( lEntry->IsEmpty() )
488  {
489  ChangePropertyEntryState(pIndex, FbxPropertyFlags::eInherit);
490  }
491  }
492  return 0;
493  }
494  return 0;
495  }
496 
497  template<class T> FbxPropertyPage* GetFirstPropertyItem(FbxInt pId, const T* pItem) const
498  {
499  FbxPropertyPage* lReferencePage = NULL;
500  GetPropertyItem(FBX_TYPE(T), pId, &lReferencePage);
501  if( lReferencePage && lReferencePage->mInstanceOf )
502  {
503  FbxPropertyPage* lReferencePage2 = lReferencePage->mInstanceOf->GetFirstPropertyItem(pId, pItem);
504  return lReferencePage2 ? lReferencePage2 : lReferencePage;
505  }
506  return lReferencePage;
507  }
508 
510  {
511  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
512  return lPropertyInfo ? ((const char*)lPropertyInfo->GetName()) : "";
513  }
514 
516  {
517  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
518  return lPropertyInfo ? ((const char*)lPropertyInfo->GetLabel()) : "";
519  }
520 
521  bool SetLabel(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT, const char* pLabel="")
522  {
523  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
524  // Don't make it writeable (Keep it shared)
525  if (lPropertyInfo) {
526  lPropertyInfo->SetLabel(pLabel);
527  return true;
528  } else {
529  return false;
530  }
531  }
532 
534  {
535  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
536  return lPropertyInfo ? lPropertyInfo->GetUserData() : 0;
537  }
538 
539  bool SetUserData(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT, const void* pUserData=0)
540  {
541  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
542  // Don't make it writeable (Keep it shared)
543  if (lPropertyInfo) {
544  lPropertyInfo->SetUserData(pUserData);
545  return true;
546  } else {
547  return false;
548  }
549  }
550 
552  {
553  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
554  return lPropertyInfo ? lPropertyInfo->GetUserTag() : 0;
555  }
556 
557  bool SetUserTag(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT,int pUserTag=0)
558  {
559  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
560  // Don't make it writeable (Keep it shared)
561  if (lPropertyInfo) {
562  lPropertyInfo->SetUserTag(pUserTag);
563  return true;
564  } else {
565  return false;
566  }
567  }
568 
570  {
571  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
572  return lPropertyInfo ? lPropertyInfo->GetType() : eFbxUndefined;
573  }
574 
576  {
577  FbxPropertyEntry* lPropertyEntry = GetPropertyEntry( pId );
578  return lPropertyEntry ? lPropertyEntry->GetParentId() : FBXSDK_PROPERTY_ID_NULL;
579  }
580 
582  {
583  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
584  return lPropertyInfo ? lPropertyInfo->GetTypeInfo() : 0;
585  }
586  FbxInt Add(FbxInt pParentId, const char* pName, EFbxType pType)
587  {
588  return Add(pParentId,FbxPropertyInfo::Create(pName,pType),FbxPropertyValue::Create(0,pType),0);
589  }
590  FbxInt Add(FbxInt pParentId, const char* pName, FbxPropertyPage* pTypeInfo)
591  {
592  return Add(pParentId,FbxPropertyInfo::Create(pName,pTypeInfo),FbxPropertyValue::Create(0,pTypeInfo->GetType()),0);
593  }
594 
595  inline bool Reparent( FbxInt /*pChildId*/, FbxInt /*pNewParentId*/ )
596  {
597  // Not implemented.
598  /*
599  if( GetParent(pChildId) != pNewParentId && pChildId < mEntries.GetCount() )
600  {
601  FbxPropertyEntry* lChildEntry = mEntries[pChildId];
602  lChildEntry->mParentId = pNewParentId;
603 
604  //@@@@@ TODO: propagate to instances
605 
606  return true;
607  }
608  */
609  return false;
610  }
611 
612  inline bool IsChildOf(FbxInt pId,FbxInt pParentId) const
613  {
614  return GetParent(pId)==pParentId;
615 
616  }
617 
618  inline bool IsDescendentOf(FbxInt pId,FbxInt pAncestorId) const
619  {
620  if (pAncestorId>0) {
621  FbxInt lParentId = GetParent(pId);
622  while (lParentId != FBXSDK_PROPERTY_ID_NULL ) {
623  if (lParentId==pAncestorId) {
624  return true;
625  }
626  lParentId = GetParent(lParentId);
627  }
628  return false;
629  } else {
630  return true;
631  }
632 
633  }
634 
635  //#define PROPERTY_PAGE_SANITY_CHECK // Debug purpose only. Never enable it in a production release.
636 
642  {
643  #ifdef PROPERTY_PAGE_SANITY_CHECK
645  if (pParentId!=FBXSDK_PROPERTY_ID_NULL) {
646  FbxInt lId = GetMinimumPropertyId(pParentId);
647  FbxInt lParentId = GetParent(lId);
648  const FbxInt lLastId = GetPropertyEntryCount();
649 
650  while (lId<lLastId && lParentId!=pParentId) lParentId=GetParent(++lId);
651  ret0 = lId<lLastId ? lId : FBXSDK_PROPERTY_ID_NULL;
652  } else {
654  }
655  #endif
657  if (pParentId != FBXSDK_PROPERTY_ID_NULL)
658  {
659  FbxPropertyEntry* lEntry;
660  FbxInt lId = pParentId;
661  do
662  {
663  lId = GetMinimumPropertyIdAndEntry(lId, &lEntry);
664  } while (lId != FBXSDK_PROPERTY_ID_NULL && lEntry->GetParentId() != pParentId);
665  ret1 = lId;
666  }
667  #ifdef PROPERTY_PAGE_SANITY_CHECK
668  FBX_ASSERT(ret0==ret1);
669  #endif
670  return ret1;
671  }
672 
678  {
679  #ifdef PROPERTY_PAGE_SANITY_CHECK
680  FbxInt pIdBackup = pId;
682  if (pId!=FBXSDK_PROPERTY_ID_NULL) {
683  FbxInt lReferenceParentId = GetParent(pId);
684  FbxInt lParentId = GetParent(++pId);
685  const FbxInt lLastId = GetPropertyEntryCount();
686 
687  while (pId<lLastId && lReferenceParentId!=FBXSDK_PROPERTY_ID_NULL && lParentId!=lReferenceParentId)
688  lParentId=GetParent(++pId);
689  ret0 = pId<lLastId ? pId : FBXSDK_PROPERTY_ID_NULL;
690  } else {
692  }
693  pId = pIdBackup;
694  #endif
696  if (pId != FBXSDK_PROPERTY_ID_NULL)
697  {
698  FbxInt lReferenceParentId = GetParent(pId);
699 
700  if (lReferenceParentId != FBXSDK_PROPERTY_ID_NULL)
701  {
702  FbxPropertyEntry *lEntry;
703  do
704  {
705  pId = GetMinimumPropertyIdAndEntry(pId, &lEntry);
706  } while (pId != FBXSDK_PROPERTY_ID_NULL && lEntry->GetParentId() != lReferenceParentId);
707 
708  ret1 = pId;
709  }
710  }
711 
712  #ifdef PROPERTY_PAGE_SANITY_CHECK
713  FBX_ASSERT(ret0==ret1);
714  #endif
715  return ret1;
716  }
717 
723  {
724  #ifdef PROPERTY_PAGE_SANITY_CHECK
726  if (pAnscestorId!=FBXSDK_PROPERTY_ID_NULL) {
727  FbxInt lId = GetMinimumPropertyId(pAnscestorId);
728  FbxInt lParentId = GetParent(lId);
729  const FbxInt lLastId = GetPropertyEntryCount();
730 
731  while (lId<lLastId) {
732  if( lParentId!=FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(lId,pAnscestorId) )
733  {
734  ret0 = lId;
735  break;
736  }
737  lParentId = GetParent(++lId);
738  }
739  }
740  #endif
742  FbxInt lId = pAnscestorId;
743  FbxPropertyEntry* lEntry;
744  if (pAnscestorId != FBXSDK_PROPERTY_ID_NULL)
745  {
746  for(;;)
747  {
748  lId = GetMinimumPropertyIdAndEntry(lId, &lEntry);
749  if (lId == FBXSDK_PROPERTY_ID_NULL)
750  break;
751  if(lEntry->GetParentId() != FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(lId, pAnscestorId))
752  {
753  ret1 = lId;
754  break;
755  }
756  }
757  }
758 
759  #ifdef PROPERTY_PAGE_SANITY_CHECK
760  FBX_ASSERT(ret0==ret1);
761  #endif
762  return ret1;
763  }
764 
770  FbxInt GetNextDescendent(FbxInt pAnscestorId, FbxInt pId) const
771  {
772  #ifdef PROPERTY_PAGE_SANITY_CHECK
773  FbxInt pIdBackup = pId;
775  if (pId!=FBXSDK_PROPERTY_ID_NULL) {
776  FbxInt lParentId = GetParent(++pId);
777  const FbxInt lLastId = GetPropertyEntryCount();
778 
779  while (pId<lLastId) {
780  // GetParent returns null when the given id isn't in our page,
781  // or our ancestor's page.
782  if( lParentId != FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(pId, pAnscestorId) )
783  {
784  ret0 = pId;
785  break;
786  }
787 
788  lParentId = GetParent(++pId);
789  }
790  }
791 
792  pId = pIdBackup;
793  #endif
795  if (pId != FBXSDK_PROPERTY_ID_NULL)
796  {
797  FbxPropertyEntry* lEntry;
798  for(;;)
799  {
800  pId = GetMinimumPropertyIdAndEntry(pId, &lEntry);
801  if (pId == FBXSDK_PROPERTY_ID_NULL)
802  break;
803  if(lEntry->GetParentId() != FBXSDK_PROPERTY_ID_NULL && IsDescendentOf(pId, pAnscestorId) )
804  {
805  ret1 = pId;
806  break;
807  }
808  }
809 
810  }
811  #ifdef PROPERTY_PAGE_SANITY_CHECK
812  FBX_ASSERT(ret0==ret1);
813  #endif
814  return ret1;
815 
816  }
817 
818  FbxInt FastFind (FbxInt pId, const char* pName, FbxPropertyPage* pTypeInfo, bool pCaseSensitive)
819  {
821 
822  bool lSlowQuery = true;
823  if( mNameMap.mSecond.GetSize() > 0 )
824  {
825  lSlowQuery = false;
826  // try to use the map if we've got it
827  NameMap::RecordType* lIterator = mNameMap.mSecond.Find( FbxNameMapKey( pId, pName ) );
828  if( !lIterator )
829  {
831  }
832  else
833  {
834  lId = lIterator->GetValue();
835  if (lId != FBXSDK_PROPERTY_ID_NULL && pTypeInfo)
836  {
837  lSlowQuery = true;
838 
839  // Try to match types.
840  // If they are mismatched, fall back to the slow query,
841  // since we might have multiple property with the same name but different types
842  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo), lId );
843  if (lPropertyInfo)
844  {
845  FbxPropertyPage* lTypeInfo2 = lPropertyInfo->GetTypeInfo();
846  if ( lTypeInfo2 && lTypeInfo2->Is(pTypeInfo) )
847  {
848  lSlowQuery = false;
849  }
850  }
851  }
852  }
853  }
854 
855  if (!lSlowQuery)
856  return lId;
857 
858  // fall back if there's no map or we got one with a different type
859 
860  lId = GetChild(pId);
861  FbxStringSymbol lSearchSymbol( pName );
862  while( lId != FBXSDK_PROPERTY_ID_NULL ) {
863  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo), lId );
864  if ( (!pTypeInfo || lPropertyInfo->GetTypeInfo()->Is(pTypeInfo)) &&
865  ((!pCaseSensitive && FBXSDK_stricmp(lPropertyInfo->GetName(),pName)==0) ||
866  (pCaseSensitive && lPropertyInfo->GetName() == lSearchSymbol)) ) {
867  return lId;
868  }
869  lId = GetSibling(lId);
870  }
871 
873  }
874 
875  FbxInt Find (FbxInt pId, const char* pName, FbxPropertyPage* pTypeInfo, bool pCaseSensitive, const char* pChildrenSeparators )
876  {
877  if (pChildrenSeparators)
878  {
879  FbxInt lId;
880  size_t lFoundIndex = strcspn(pName,pChildrenSeparators);
881 
882  // Strip the first part of the name and search
883  if (lFoundIndex<strlen(pName))
884  {
885  FbxString pRootName;
886  pRootName.Append(pName,lFoundIndex);
887  lId = FastFind(pId,pRootName.Buffer(),NULL,pCaseSensitive);
888  return lId != FBXSDK_PROPERTY_ID_NULL ? Find(lId,pName+lFoundIndex+1,pTypeInfo,pCaseSensitive,pChildrenSeparators) : lId;
889  } else {
890  return FastFind(pId,pName,pTypeInfo,pCaseSensitive);
891  }
892  } else {
893  return FastFind(pId,pName,pTypeInfo,pCaseSensitive);
894  }
895  }
896 
897 // Enum list
898  int AddEnumValue(FbxInt pId, const char* pStringValue)
899  {
900  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
901  // Don't make it writeable (Keep it shared)
902  return lPropertyInfo ? lPropertyInfo->AddEnumValue(pStringValue) : - 1;
903  }
904 
905  void InsertEnumValue(FbxInt pId, int pIndex, const char* pStringValue)
906  {
907  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
908  // Don't make it writeable (Keep it shared)
909  if (lPropertyInfo) lPropertyInfo->InsertEnumValue(pIndex,pStringValue);
910  }
911 
913  {
914  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
915  // Don't make it writeable (Keep it shared)
916  return lPropertyInfo ? lPropertyInfo->GetEnumCount() : 0;
917  }
918 
919  void SetEnumValue(FbxInt pId, int pIndex, const char* pStringValue)
920  {
921  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
922  // Don't make it writeable (Keep it shared)
923  if (lPropertyInfo) lPropertyInfo->SetEnumValue(pIndex,pStringValue);
924  }
925 
926  void RemoveEnumValue(FbxInt pId, int pIndex)
927  {
928  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
929  // Don't make it writeable (Keep it shared)
930  if (lPropertyInfo) lPropertyInfo->RemoveEnumValue(pIndex);
931  }
932 
933  char* GetEnumValue(FbxInt pId,int pIndex)
934  {
935  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
936  return lPropertyInfo ? lPropertyInfo->GetEnumValue(pIndex) : (char*)"";
937  }
938 
939  // Connection
940  // ---------------------------------
942  {
943  FbxPropertyPage* lReferencePage = 0;
944  FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
945 
946  // Connections are not considered propagated so
947  // make sure that we own the FbxPropertyConnect objects
948  if (lPropertyConnect) {
949  lPropertyConnect->ClearConnectCache();
950  }
951  }
952 
954  {
955  FbxPropertyPage* lReferencePage = 0;
956  FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
957 
958  if (lPropertyConnect) {
959  lPropertyConnect->WipeAllConnections();
960  }
961  }
962 
963  bool ConnectSrc(FbxInt pDstId, FbxPropertyPage* pSrcPage, FbxInt pSrcId, FbxConnection::EType pType)
964  {
965  FbxPropertyEntry* lDstEntry = ChangePropertyEntryState(pDstId,FbxPropertyFlags::eOverride);
966  FbxPropertyEntry* lSrcEntry = pSrcPage->ChangePropertyEntryState(pSrcId,FbxPropertyFlags::eOverride);
967 
968  // Make sure we have a connection point on both sides of the connection.
969  //
970  // In the case lDstEntry == lSrcEntry, we don't want to create different
971  // connection points (FbxPropertyConnect) since the call to lSrcEntry->Set(...)
972  // would delete the lDstConnect and we can't test for the validity of lDstConnect
973  // because the pointer is != nullptr but its content have already been destroyed.
974  //
975  // Having lDstEntry == lSrcEntry is not a valid operation anyway and is "trapped"
976  // by the call lDstConnect->ConnectSrc(lSrcConnect, pType); so we just need to
977  // make sure we can call it!
978 
979  FbxPropertyConnect* lDstConnect= lDstEntry->Get( FBX_TYPE(FbxPropertyConnect) );
980  if (!lDstConnect) {
981  lDstConnect = FbxPropertyConnect::Create( this,pDstId );
982  lDstEntry->Set( lDstConnect );
983  }
984 
985  FbxPropertyConnect* lSrcConnect = lSrcEntry->Get(FBX_TYPE(FbxPropertyConnect));
986  if (!lSrcConnect) {
987  lSrcConnect = FbxPropertyConnect::Create( pSrcPage,pSrcId );
988  lSrcEntry->Set( lSrcConnect );
989  }
990 
991  // Must @@@@@@@ Propagate to inherited children
992  return (lDstConnect) ? lDstConnect->ConnectSrc(lSrcConnect, pType) : false;
993 
994  }
995 
996  bool DisconnectSrc(FbxInt pDstId,FbxPropertyPage* pSrcPage,FbxInt pSrcId)
997  {
998  FbxPropertyPage* lDstReferencePage = 0;
999  FbxPropertyConnect* lDstConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pDstId,&lDstReferencePage );
1000  FbxPropertyPage* lSrcReferencePage = 0;
1001  FbxPropertyConnect* lSrcConnect = pSrcPage->GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pSrcId,&lSrcReferencePage );
1002 
1003  // Make sure we have a connection point on both sides of the connection
1004  if (lDstConnect && lSrcConnect && lDstReferencePage==this && lSrcReferencePage==pSrcPage) {
1005  // Must @@@@@@@ Remove unused connections
1006  return lDstConnect->DisconnectSrc(lSrcConnect);
1007  }
1008  return false;
1009  }
1010 
1011  bool IsConnectedSrc(FbxInt pDstId, FbxPropertyPage* pSrcPage, FbxInt pSrcId)
1012  {
1013  FbxPropertyPage* lDstReferencePage = 0;
1014  FbxPropertyConnect* lDstConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pDstId,&lDstReferencePage );
1015  FbxPropertyPage* lSrcReferencePage = 0;
1016  FbxPropertyConnect* lSrcConnect = pSrcPage->GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pSrcId,&lSrcReferencePage );
1017 
1018  // Make sure we have a connection point on both sides of the connection
1019  if (lDstConnect && lSrcConnect && lDstReferencePage==this && lSrcReferencePage==pSrcPage) {
1020  // Must @@@@@@@ Remove unused connections
1021  return lDstConnect->IsConnectedSrc(lSrcConnect);
1022  }
1023  return false;
1024  }
1025 
1027  {
1028  FbxPropertyPage* lReferencePage = 0;
1029  FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
1030 
1031  // Connections are not considered propagated so
1032  // make sure that we own the FbxPropertyConnect objects
1033  return (lPropertyConnect && lReferencePage==this) ? lPropertyConnect->GetSrcCount(pFilter) : 0;
1034  }
1035 
1036  bool GetSrc(FbxInt pId, int pIndex, FbxConnectionPointFilter* pFilter, FbxPropertyPage** pSrcPage, FbxInt* pSrcId)
1037  {
1038  FbxPropertyPage* lReferencePage = 0;
1039  FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
1040 
1041  // Connections are always overridden
1042  // make sure that we own the FbxPropertyConnect Item
1043  if (lPropertyConnect && lReferencePage==this)
1044  {
1045  FbxPropertyConnect* lSrc = lPropertyConnect->GetSrc(pFilter,pIndex);
1046  if (lSrc)
1047  {
1048  if (pSrcPage) *pSrcPage = lSrc->GetPage();
1049  if (pSrcId) *pSrcId = lSrc->GetPropertyId();
1050  return true;
1051  }
1052  }
1053  return false;
1054  }
1055 
1056  bool ConnectDst(FbxInt pSrcId, FbxPropertyPage* pDstPage, FbxInt pDstId, FbxConnection::EType pType)
1057  {
1058  return pDstPage->ConnectSrc(pDstId,this,pSrcId,pType);
1059  }
1060 
1061  bool DisconnectDst(FbxInt pSrcId, FbxPropertyPage* pDstPage, FbxInt pDstId)
1062  {
1063  return pDstPage->DisconnectSrc(pDstId,this,pSrcId);
1064  }
1065 
1066  bool IsConnectedDst(FbxInt pSrcId, FbxPropertyPage* pDstPage, FbxInt pDstId)
1067  {
1068  return pDstPage->IsConnectedSrc(pDstId,this,pSrcId);
1069  }
1070 
1072  {
1073  FbxPropertyPage* lReferencePage = 0;
1074  FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
1075 
1076  // Connections are not considered propagated so
1077  // make sure that we own the FbxPropertyConnect objects
1078  return (lPropertyConnect && lReferencePage==this) ? lPropertyConnect->GetDstCount(pFilter) : 0;
1079  }
1080 
1081  bool GetDst(FbxInt pId, int pIndex, FbxConnectionPointFilter* pFilter, FbxPropertyPage** pDstPage, FbxInt* pDstId)
1082  {
1083  FbxPropertyPage* lReferencePage = 0;
1084  FbxPropertyConnect* lPropertyConnect = GetPropertyItem( FBX_TYPE(FbxPropertyConnect),pId,&lReferencePage );
1085 
1086  // Connections are always overridden
1087  // make sure that we own the FbxPropertyConnect Item
1088  if (lPropertyConnect && lReferencePage==this)
1089  {
1090  FbxPropertyConnect* lDst = lPropertyConnect->GetDst(pFilter,pIndex);
1091  if (lDst)
1092  {
1093  if (pDstPage) *pDstPage = lDst->GetPage();
1094  if (pDstId) *pDstId = lDst->GetPropertyId();
1095  return true;
1096  }
1097  }
1098  return false;
1099  }
1100 
1101  // Min and Max
1102  // ---------------------------------
1103  enum EValueIndex { eValueMin,eValueSoftMin,eValueMax,eValueSoftMax,eValueCount };
1104 
1106  {
1107  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
1108 
1109  return lPropertyInfo ? lPropertyInfo->HasMinMax(pValueId) : false;
1110  }
1111 
1112  bool GetMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId, void* pValue, EFbxType pValueType)
1113  {
1114  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
1115  // Don't make it writeable (Keep it shared)
1116  return lPropertyInfo ? lPropertyInfo->GetMinMax(pValueId,pValue,pValueType) : false;
1117  }
1118 
1119  bool SetMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId, const void* pValue, EFbxType pValueType)
1120  {
1121  FbxPropertyInfo* lPropertyInfo = GetPropertyItem( FBX_TYPE(FbxPropertyInfo),pId );
1122  // Don't make it writeable (Keep it shared)
1123  return lPropertyInfo ? lPropertyInfo->SetMinMax(pValueId,pValue,pValueType) : false;
1124  }
1125 
1126  // Value
1127  // ---------------------------------
1128  bool Get(FbxInt pId, void* pValue, EFbxType pValueType)
1129  {
1130  FbxPropertyValue* lPropertyValue = GetPropertyItem( FBX_TYPE(FbxPropertyValue),pId );
1131  return lPropertyValue ? lPropertyValue->Get(pValue,pValueType) : 0;
1132  }
1133 
1134  bool Set(FbxInt pId, const void* pValue, EFbxType pValueType, bool pCheckValueEquality)
1135  {
1136  if( pCheckValueEquality )
1137  {
1138  FbxPropertyPage* lReferencePage = NULL;
1139  FbxPropertyValue* lPropertyValue = GetPropertyItem( FBX_TYPE(FbxPropertyValue),pId,&lReferencePage );
1140  union {
1141  void* lCurrentValue;
1142  char buffer[sizeof(FbxDouble4x4)];
1143  };
1144  FBX_ASSERT(sizeof(buffer) >= FbxTypeSizeOf(pValueType));
1145  bool lValuesEqual = false;
1146  bool lValueChanged = false;
1147  if( lReferencePage && lReferencePage != this )
1148  {
1149  // this page inherits, so check if we have to override the value.
1150  if( lPropertyValue )
1151  {
1152  FbxTypeAllocate(pValueType, lCurrentValue, sizeof(buffer));
1153  lPropertyValue->Get( &lCurrentValue, pValueType );
1154  lValuesEqual = FbxTypeCompare( pValue, &lCurrentValue, pValueType );
1155  FbxTypeDeallocate(pValueType, lCurrentValue, sizeof(buffer));
1156  }
1157  }
1158  else
1159  {
1160  FbxPropertyPage* lReferencePage2 = NULL;
1161  FbxPropertyValue* lPropertyValue2 = mInstanceOf ? mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyValue),pId,&lReferencePage2 ) : NULL;
1162  if( lReferencePage2 && lPropertyValue2 )
1163  {
1164  FbxTypeAllocate(pValueType, lCurrentValue, sizeof(buffer));
1165  // this page is an override, but there is another page before us that overrides the value
1166  lPropertyValue2->Get( &lCurrentValue, pValueType );
1167  lValuesEqual = FbxTypeCompare( pValue, &lCurrentValue, pValueType );
1168  FbxTypeDeallocate(pValueType, lCurrentValue, sizeof(buffer));
1169 
1170  if( lValuesEqual )
1171  {
1172  ChangePropertyItemState( FBX_TYPE(FbxPropertyValue), pId, FbxPropertyFlags::eInherit );
1173  lValueChanged = true;
1174  }
1175 
1176  }
1177  // else this page is the originator of the property, so no need to check,
1178  }
1179 
1180  if( lValuesEqual )
1181  return lValueChanged;
1182  }
1183 
1184  FbxPropertyValue* lPropertyValue = ChangePropertyItemState( FBX_TYPE(FbxPropertyValue),pId,FbxPropertyFlags::eOverride );
1185  return lPropertyValue ? lPropertyValue->Set(pValue,pValueType) : false;
1186  }
1187 
1188  inline FbxPropertyFlags::EInheritType GetValueInherit(FbxInt pId, bool pCheckInstanceOf) const
1189  {
1190  FbxPropertyPage* lReferencePage = NULL;
1191  GetPropertyItem(FBX_TYPE(FbxPropertyValue), pId, &lReferencePage);
1192 
1193  // check one level
1194  if( !pCheckInstanceOf )
1195  {
1196  return lReferencePage == this ? FbxPropertyFlags::eOverride : FbxPropertyFlags::eInherit;
1197  }
1198  else
1199  {
1200  if( lReferencePage == this ) return FbxPropertyFlags::eOverride; // this page is either an override, or the originator
1201  else if( !lReferencePage->mInstanceOf ) return FbxPropertyFlags::eInherit; // the reference is the class root, so we must be inheriting
1202 
1203  // The reference page is not the class root, might be another override, or the originator.
1204  FbxPropertyValue* lPropertyValue = lReferencePage->mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyValue), pId );
1205 
1206  // if lReferencePage->mInstanceOf has the property value,
1207  // lReferencePage is an override
1208  // else
1209  // its the originator, so this page inherits from it.
1210  return lPropertyValue ? FbxPropertyFlags::eOverride : FbxPropertyFlags::eInherit;
1211  }
1212  }
1213 
1215  {
1216  // no support for this mode yet
1217  if( FbxPropertyFlags::eDeleted == pType )
1218  return false;
1219 
1220  ChangePropertyItemState( FBX_TYPE(FbxPropertyValue), pId, pType );
1221 
1222  // Above call doesn't return error codes, so just check that we match types.
1223  return GetValueInherit(pId, false) == pType;
1224  }
1225 
1226  inline bool GetDefaultValue(FbxInt pId, void* pValue, EFbxType pValueType) const
1227  {
1228  FbxPropertyPage* lReferencePage = GetFirstPropertyItem( pId, FBX_TYPE(FbxPropertyValue) );
1229  FbxPropertyValue* lPropertyValue = lReferencePage ? lReferencePage->GetPropertyItem( FBX_TYPE(FbxPropertyValue), pId ) : NULL;
1230 
1231  return lPropertyValue ? lPropertyValue->Get( pValue, pValueType ) : false;
1232  }
1233 
1234 
1235  // useful set and get functions
1236  template <class T> inline bool Set( FbxInt pId, const T& pValue ) { return Set( pId,&pValue,FbxTypeOf(pValue),true ); }
1237  template <class T> inline T Get( FbxInt pId, const T* pFBX_TYPE) { T lValue; Get( pId,&lValue,FbxTypeOf(lValue) ); return lValue; }
1238 
1239 
1240  void SetDataPtr(void* pDataPtr) { mDataPtr = pDataPtr; }
1241  void* GetDataPtr() const { return mDataPtr; }
1242 
1243  // Instance and override management
1244  // ------------------------------------------
1246  {
1247  if (mInstanceOf) {
1248  const int lCount = GetPropertyEntryCount();
1249  // push the existing properties into the parent
1250  // ----------------------------------------------
1251  for( int i = 0; i < lCount; ++i )
1252  {
1253  FbxPropertyEntry* lParentEntry = mInstanceOf->ChangePropertyEntryState( (FbxInt)i,FbxPropertyFlags::eOverride );
1254  FbxPropertyEntry* lEntry = GetPropertyEntry( (FbxInt)i );
1255 
1256  if( !lParentEntry )
1257  {
1258  lParentEntry = FbxPropertyEntry::Create( lEntry->GetParentId(), 0, 0, 0 );
1259  mInstanceOf->mEntryMap.Insert( i, lParentEntry );
1260 
1261  //mInstanceOf->AddChild(i);
1262 
1263  }
1264 
1265  FBX_ASSERT( lParentEntry );
1266 
1267  // Add it to the parent
1268  // Don't touch the connections
1269  // -----------------------------------------
1270  if (lParentEntry) {
1271  lParentEntry->Set( lEntry->Get(FBX_TYPE(FbxPropertyInfo)) );
1272  lParentEntry->Set( lEntry->Get(FBX_TYPE(FbxPropertyValue)) );
1273  lParentEntry->Set( lEntry->Get(FBX_TYPE(FbxPropertyFlags)) );
1274  }
1275 
1276  /*
1277  else {
1278  mInstanceOf->Add(
1279  lEntry->GetParentId(),
1280  lEntry->Get(FBX_TYPE(FbxPropertyInfo)), // The info
1281  lEntry->Get(FBX_TYPE(FbxPropertyValue)), // The Value
1282  0, // The connections
1283  false,
1284  false
1285  );
1286  }
1287  */
1288 
1289  // Empty the current entry
1290  // Don't touch the connections
1291  // -----------------------------------------
1292  ChangePropertyItemState(FBX_TYPE(FbxPropertyInfo), i,FbxPropertyFlags::eInherit);
1293  ChangePropertyItemState(FBX_TYPE(FbxPropertyValue), i,FbxPropertyFlags::eInherit);
1294  ChangePropertyItemState(FBX_TYPE(FbxPropertyFlags), i,FbxPropertyFlags::eInherit);
1295  }
1296  }
1297  }
1298 
1299  inline const FbxPropertyPage* GetInstanceOf() const { return mInstanceOf; }
1300  inline FbxPropertyPage* GetInstanceOf() { return mInstanceOf; }
1301 
1302  inline const FbxSet<FbxPropertyPage*>& GetInstances() const { return mInstances; }
1303 
1304  // Flags
1305  // ------------------------------------------
1307  {
1308  FbxPropertyPage* lFoundIn = NULL;
1309  FbxPropertyFlags* lPropertyFlags = GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn );
1311 
1312  if( lPropertyFlags )
1313  {
1314  if( !mInstanceOf ) // no inheritance.
1315  lFlags = lPropertyFlags->GetFlags();
1316  else
1317  {
1318  lFlags = mInstanceOf->GetFlags(pId);
1319  lFlags = lPropertyFlags->GetMergedFlags(lFlags);
1320  }
1321  }
1322  return lFlags;
1323  }
1324 
1325  bool ModifyFlags(FbxInt pId=FBXSDK_PROPERTY_ID_ROOT,FbxPropertyFlags::EFlags pFlags=FbxPropertyFlags::eNone,bool pValue=true,bool pCheckFlagEquality=true)
1326  {
1327  if( pCheckFlagEquality )
1328  {
1329  FbxPropertyPage* lFoundIn = NULL;
1330  FbxPropertyFlags* lFlag = GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn );
1331 
1332  if( lFlag )
1333  {
1334  if( lFoundIn == this )
1335  {
1336  // set them in us.
1337  lFlag->ModifyFlags( pFlags, pValue );
1338 
1339  // we override this entry, check if we need to revert
1340  FbxPropertyFlags* lInheritedFlags = mInstanceOf ? mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId ) : NULL;
1341  if( lInheritedFlags && lInheritedFlags->Equal( *lFlag, pFlags ) )
1342  {
1343  lFlag->UnsetMask( pFlags );
1344 
1345  if( lFlag->GetMask() == 0 )
1346  ChangePropertyItemState( FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eInherit );
1347 
1348  return true;
1349  }
1350  }
1351  else
1352  {
1353  // its not us. Just check if we need to set.
1354  FbxPropertyFlags lNewValues( pFlags );
1355  if( lFlag->Equal( lNewValues, pFlags ) )
1356  return true;
1357  }
1358  }
1359  }
1360 
1361  FbxPropertyFlags* lPropertyFlags = ChangePropertyItemState(FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eOverride);
1362  return lPropertyFlags ? lPropertyFlags->ModifyFlags( pFlags, pValue ) : false;
1363  }
1364 
1366  {
1367  FbxPropertyPage* lFoundIn = NULL;
1368  FbxPropertyFlags* lPropertyFlags = GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn );
1369 
1370  if( !pCheckInstanceOf )
1371  return lFoundIn != this ? FbxPropertyFlags::eInherit : ( lPropertyFlags ? lPropertyFlags->GetFlagsInheritType(pFlags) : FbxPropertyFlags::eInherit );
1372  else
1373  {
1374  // This code basically counts the number of overrides for the
1375  // given flags. The original entry is always considered an override.
1376  // so if we see more than one, something overrode the original.
1377  // and thus we are an override.
1378  FbxPropertyPage* lRefPage = lFoundIn;
1379  bool lFoundOverride = false;
1380  while( lRefPage )
1381  {
1382  lPropertyFlags = lRefPage->GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId );
1383 
1384  if( !lPropertyFlags )
1385  break; // gone too far, break.
1386 
1387  if( lPropertyFlags->GetFlagsInheritType( pFlags ) == FbxPropertyFlags::eOverride )
1388  {
1389  if( this == lRefPage || lFoundOverride )
1390  return FbxPropertyFlags::eOverride; // found two overrides or this page is the override.
1391  else
1392  lFoundOverride = true; // signal that we found the first override.
1393  }
1394  lRefPage = lRefPage->mInstanceOf;
1395  }
1396 
1398  }
1399  }
1400 
1402  {
1403  FbxPropertyPage* lFoundIn = NULL;
1404  FbxPropertyFlags* lPropertyFlags = NULL;
1405 
1406  if( FbxPropertyFlags::eOverride == pInheritType )
1407  {
1408  lPropertyFlags = ChangePropertyItemState( FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eOverride );
1409 
1410  // we should initialize our flag to the inherited value, if any.
1411  FbxPropertyFlags* lParentFlags = mInstanceOf ? mInstanceOf->GetPropertyItem( FBX_TYPE(FbxPropertyFlags), pId ) : NULL;
1412  if( lParentFlags && lPropertyFlags )
1413  {
1414  FbxPropertyFlags::EFlags lParentValues = lParentFlags->GetFlags();
1415  lPropertyFlags->SetFlags( pFlags, lParentValues );
1416  return lPropertyFlags->SetMask( pFlags );
1417  }
1418 
1419  return false;
1420  }
1421  else if( FbxPropertyFlags::eInherit == pInheritType )
1422  {
1423  lPropertyFlags = GetPropertyItem(FBX_TYPE(FbxPropertyFlags), pId, &lFoundIn);
1424  if( !lPropertyFlags ) return false;
1425  if( lFoundIn != this ) return true; // not us
1426  lPropertyFlags->UnsetMask( pFlags );
1427  if( lPropertyFlags->GetMask() == 0 ) // revert
1428  ChangePropertyItemState( FBX_TYPE(FbxPropertyFlags), pId, FbxPropertyFlags::eInherit );
1429 
1430  return true;
1431  }
1432  return false;
1433  }
1434 
1436  {
1437  if( 0 == mNameMap.mFirst )
1438  {
1439  mNameMap.mSecond.Reserve(20);
1440 
1441  // push the existing properties into the map. Note: this includes the root property!
1442  FbxInt lFoundId = FBXSDK_PROPERTY_ID_ROOT;
1443  FbxPropertyEntry* lEntry = GetPropertyEntry(lFoundId);
1444  while(lFoundId != FBXSDK_PROPERTY_ID_NULL)
1445  {
1446  FbxPropertyInfo* lInfo = lEntry->Get(FBX_TYPE(FbxPropertyInfo));
1447  //FBX_ASSERT( lInfo );
1448  if (lInfo)
1449  {
1450  mNameMap.mSecond.Insert(FbxNameMapKey(lEntry->GetParentId(), lInfo->GetName()), lFoundId);
1451  }
1452  lFoundId = GetMinimumPropertyIdAndEntry(lFoundId, &lEntry);
1453  }
1454  mNameMap.mFirst++;
1455  }
1456  }
1457 
1459  {
1460  if( mNameMap.mFirst > 0 )
1461  {
1462  if( --(mNameMap.mFirst) == 0 )
1463  mNameMap.mSecond.Clear();
1464  }
1465  }
1466 
1467 protected:
1469  : mInstanceOf(0)
1470  , mDataPtr(0)
1471  , mPropNextId(0)
1472  {
1473  mEntryMap.Reserve(32);
1474  mNameMap.mFirst = 0;
1475 
1476  // instances don't need to create a root property
1477  if( !pInstanceOf )
1478  {
1479  mPropNextId = FbxNew< FbxPropertyIdGenerator >();
1480  mPropNextId->IncRef();
1481 
1482  // First item is the root information
1484  }
1485 
1486  // Hook the instances
1487  // ------------------------
1488  mInstanceOf = pInstanceOf;
1489  if (mInstanceOf) {
1490  mInstanceOf->mInstances.Insert(this);
1491 
1492  mPropNextId = mInstanceOf->mPropNextId;
1493  mPropNextId->IncRef();
1494  }
1495  }
1496  FbxPropertyPage(const char* pName, EFbxType pType)
1497  : mInstanceOf(0)
1498  , mDataPtr(0)
1499  , mPropNextId(0)
1500  {
1501  mEntryMap.Reserve(32);
1502  mNameMap.mFirst = 0;
1503 
1504  mPropNextId = FbxNew< FbxPropertyIdGenerator >();
1505  mPropNextId->IncRef();
1506 
1507  // First item is the root information
1508  Add(FBXSDK_PROPERTY_ID_NULL,pName,pType);
1509  }
1510  FbxPropertyPage(const char* pName, FbxPropertyPage* pTypeInfo)
1511  : mInstanceOf(0)
1512  , mDataPtr(0)
1513  , mPropNextId(0)
1514  {
1515  mEntryMap.Reserve(32);
1516  mNameMap.mFirst = 0;
1517 
1518  mPropNextId = FbxNew< FbxPropertyIdGenerator >();
1519  mPropNextId->IncRef();
1520 
1521  // First item is the root information
1522  Add(FBXSDK_PROPERTY_ID_NULL,pName,pTypeInfo);
1523  }
1525  {
1526  // Propagate our property entries.
1527  for (FbxSet<FbxPropertyPage*>::Iterator iter = mInstances.Begin(); iter != mInstances.End(); ++iter)
1528  {
1529  FbxPropertyPage* lPage = iter->GetValue();
1530  for (int j = 0; j < GetPropertyEntryCount(); ++j)
1531  {
1532  if (lPage->ChangePropertyEntryState((FbxInt)j, FbxPropertyFlags::eOverride))
1533  {
1534  // Clone the info and values. Don't clone the connections,
1535  // since they aren't propagated.
1538 
1539  // Since all entries have their own flags, just override the ones in the instance.
1541  }
1542  }
1543 
1544  // Instances become their own copies.
1545  lPage->mInstanceOf = NULL;
1546  }
1547 
1548  FbxMapDestroy(mEntryMap);
1549 
1550  if (mInstanceOf)
1551  {
1552  mInstanceOf->mInstances.Remove(this);
1553  }
1554 
1555  mPropNextId->DecRef();
1556  mPropNextId = NULL;
1557 
1558  mInstanceOf = NULL;
1559  mInstances.Clear();
1560  }
1561 
1562  inline bool Is(FbxPropertyPage* pPage)
1563  {
1564  // @@@@@@@@@@@@@@@ Must complete for sub types
1565  return this==pPage;
1566  }
1567 
1568 // Internal entry management
1569 private:
1570 
1576  FbxInt GetMinimumPropertyId(FbxInt pId, bool pIncrementIfNone = true) const
1577  {
1578  if( pId == FBXSDK_PROPERTY_ID_NULL )
1580 
1582  const EntryMap::RecordType* lElement = mEntryMap.UpperBound(pId);
1583  if (NULL != lElement)
1584  {
1585  lMin = lElement->GetKey();
1586  }
1587 
1588  FbxInt lParentMin = mInstanceOf ? mInstanceOf->GetMinimumPropertyId(pId,false) : FBXSDK_PROPERTY_ID_NULL;
1589 
1590  bool lParentNull = lParentMin == FBXSDK_PROPERTY_ID_NULL;
1591  bool lMinNull = lMin == FBXSDK_PROPERTY_ID_NULL;
1592 
1593  if( lParentNull && lMinNull ) return pIncrementIfNone ? pId+1 : FBXSDK_PROPERTY_ID_NULL;
1594  else if( lMinNull ) lMin = lParentMin;
1595  else if( !lParentNull ) lMin = lMin < lParentMin ? lMin : lParentMin;
1596 
1597  return lMin;
1598  }
1599 
1605  FbxInt GetMinimumPropertyIdAndEntry(FbxInt pId, FbxPropertyEntry** pEntry) const
1606  {
1607  FbxInt lFoundId = FBXSDK_PROPERTY_ID_NULL;
1608  FbxPropertyEntry* lFoundEntry = NULL;
1609  if( pId == FBXSDK_PROPERTY_ID_NULL )
1611 
1612  const EntryMap::RecordType* lElement = mEntryMap.UpperBound(pId);
1613  if (NULL != lElement)
1614  {
1615  lFoundId = lElement->GetKey();
1616  lFoundEntry = lElement->GetValue();
1617  }
1618 
1619  FbxPropertyEntry* lParentEntry = NULL;
1620  FbxInt lParentMin = mInstanceOf ? mInstanceOf->GetMinimumPropertyIdAndEntry(pId, &lParentEntry) : FBXSDK_PROPERTY_ID_NULL;
1621 
1622  bool lParentNull = lParentMin == FBXSDK_PROPERTY_ID_NULL;
1623  bool lMinNull = lFoundId == FBXSDK_PROPERTY_ID_NULL;
1624 
1625  if( lMinNull && !lParentNull )
1626  {
1627  lFoundId = lParentMin;
1628  lFoundEntry = lParentEntry;
1629  }
1630  else if( !lMinNull && !lParentNull )
1631  {
1632  lFoundId = lFoundId < lParentMin ? lFoundId : lParentMin;
1633  lFoundEntry = lFoundId < lParentMin ? lFoundEntry : lParentEntry;
1634  }
1635 
1636  if (pEntry)
1637  *pEntry = lFoundEntry;
1638  return lFoundId;
1639  }
1640 
1641  int GetPropertyEntryCount() const
1642  {
1643  int lCount = 0;
1644  const EntryMap::RecordType* lElement = mEntryMap.Maximum();
1645 
1646  if (NULL != lElement)
1647  {
1648  lCount = lElement->GetKey() + 1;
1649  }
1650 
1651  int lParentCount = mInstanceOf ? mInstanceOf->GetPropertyEntryCount() : 0;
1652  return lParentCount > lCount ? lParentCount : lCount;
1653  }
1654 
1655  FbxPropertyEntry* GetPropertyEntry(FbxInt pIndex,FbxPropertyPage **pFoundIn=0) const
1656  {
1657  const EntryMap::RecordType* lElement = mEntryMap.Find(pIndex);
1658  if (NULL != lElement)
1659  {
1660  if( pFoundIn )
1661  {
1662  *pFoundIn = const_cast<FbxPropertyPage*>(this);
1663  }
1664  return lElement->GetValue();
1665  }
1666 
1667  if( pFoundIn )
1668  {
1669  *pFoundIn = 0;
1670  }
1671 
1672  return mInstanceOf ? mInstanceOf->GetPropertyEntry(pIndex,pFoundIn) : 0;
1673  }
1674 
1675  FbxPropertyEntry* ChangePropertyEntryState(FbxInt pIndex,FbxPropertyFlags::EInheritType pInheritType)
1676  {
1677  FbxPropertyPage* lReferencePage = 0;
1678  FbxPropertyEntry* lReferenceEntry = GetPropertyEntry(pIndex,&lReferencePage);
1679 
1680  if (pInheritType==FbxPropertyFlags::eOverride) {
1681  if (lReferencePage==this) {
1682  return lReferenceEntry;
1683  } else if (lReferenceEntry) {
1684  // must create an entry
1685  FbxPropertyEntry* lEntry = FbxPropertyEntry::Create(lReferenceEntry->GetParentId(),0,0,0);
1686  mEntryMap.Insert( pIndex, lEntry );
1687 
1688  return lEntry;
1689  }
1690  } else {
1691  if (lReferenceEntry && (lReferencePage==this)) {
1692  mEntryMap.Remove(pIndex);
1693  lReferenceEntry->Destroy();
1694  }
1695  }
1696  return 0;
1697  }
1698 
1699  FbxInt Add(FbxInt pParentId,FbxPropertyInfo* pInfo,FbxPropertyValue* pValue,FbxPropertyConnect* pConnect,bool pRecursive=true)
1700  {
1701  FbxInt lId = mPropNextId->GetNextIdAndInc();
1702  FbxPropertyEntry* lEntry = FbxPropertyEntry::Create(pParentId,pInfo,pValue,pConnect);
1703 
1704  // entries created through Add() are not overrides of another entry.
1705  // Thus, set all of their flags by default.
1706  FbxPropertyFlags* lFlags = lEntry->Get( FBX_TYPE(FbxPropertyFlags) );
1707  if( lFlags ) lFlags->ModifyFlags( FbxPropertyFlags::eAllFlags, false );
1708 
1709  mEntryMap.Insert( lId, lEntry );
1710 
1711  // We only add to the map if this Add is called after BeginCreateOrFindProperty()
1712  // in which case the size is always > 0 because it includes the root property
1713  if( mNameMap.mSecond.GetSize() > 0 )
1714  mNameMap.mSecond.Insert( FbxNameMapKey( pParentId, pInfo->GetName()), lId );
1715 
1716  // If the entry has multiple children(Struct Datatype)
1717  // Recurse for the entries and create an entry in this structure
1718  if (pRecursive) {
1719  FbxPropertyPage* lTypeInfo = pInfo->GetTypeInfo();
1720  if (lTypeInfo) {
1721  FbxInt lChildId;
1722  lChildId = lTypeInfo->GetChild();
1723  while (lChildId!=FBXSDK_PROPERTY_ID_NULL) {
1724  FbxPropertyInfo* lPropertyInfo = lTypeInfo->GetPropertyItem( FBX_TYPE(FbxPropertyInfo),lChildId );
1725  FbxPropertyValue* lPropertyValue = lTypeInfo->GetPropertyItem( FBX_TYPE(FbxPropertyValue),lChildId );
1726  FbxPropertyConnect* lPropertyConnect = lTypeInfo->GetPropertyItem( FBX_TYPE(FbxPropertyConnect),lChildId );
1727 
1728  Add ( lId, lPropertyInfo ? lPropertyInfo->Clone(this) : 0 , lPropertyValue ? lPropertyValue->Clone(this) : 0,
1729  lPropertyConnect ? lPropertyConnect->Clone(this) : 0 );
1730  lChildId = lTypeInfo->GetSibling(lChildId );
1731  }
1732  }
1733  }
1734  return lId;
1735  }
1736 
1737  // Property management
1739  EntryMap mEntryMap;
1740 
1741  // instance management
1742  FbxPropertyPage* mInstanceOf;
1743  FbxSet<FbxPropertyPage*> mInstances;
1744 
1745  void* mDataPtr;
1746 
1747  // speed up structure
1749  typedef FbxPair<unsigned int, NameMap > NameLookupPair;
1750  NameLookupPair mNameMap;
1751 
1752  FbxPropertyIdGenerator* mPropNextId;
1753 
1754  friend class FbxPropertyHandle;
1755 };
1756 
1757 #include <fbxsdk/fbxsdk_nsend.h>
1758 
1759 #endif /* _FBXSDK_CORE_PROPERTY_PAGE_H_ */
FbxInt Add(FbxInt pParentId, const char *pName, EFbxType pType)
int GetUserTag() const
FbxConnectionPoint mConnectionPoint
void PushPropertiesToParentInstance()
bool ConnectDst(FbxPropertyConnect *pDst, FbxConnection::EType pType)
FbxPropertyPage * GetInstanceOf()
Class to manage property handle.
bool UnsetMask(FbxPropertyFlags::EFlags pFlags)
FBX SDK environment definition.
bool Get(FbxInt pId, void *pValue, EFbxType pValueType)
int GetSrcCount(FbxInt pId, FbxConnectionPointFilter *pFilter)
#define FBXSDK_PROPERTY_ID_NULL
Iterator Begin()
Retrieve the begin iterator of the set.
Definition: fbxset.h:107
#define FBXSDK_FRIEND_NEW()
Definition: fbxnew.h:420
void SetLabel(const char *pLabel)
FbxPropertyConnect * GetSrc(FbxConnectionPointFilter *pFilter, int pIndex)
FbxPropertyPage * GetTypeInfo() const
bool ConnectSrc(FbxInt pDstId, FbxPropertyPage *pSrcPage, FbxInt pSrcId, FbxConnection::EType pType)
void FbxMapDestroy(FbxMap< K, V, C, A > &pMap)
Call Destroy on each element of the map, and then clear it.
Definition: fbxmap.h:394
size_t FbxTypeSizeOf(const EFbxType pType)
Retrieve a type enumeration memory footprint size.
void SetUserTag(int pUserTag)
Unidentified.
FbxPropertyFlags::EFlags GetFlags() const
FbxInt GetParent(FbxInt pId=0) const
FbxPropertyInfo * Get(const FbxPropertyInfo *)
FbxInt GetChild(FbxInt pParentId=0) const
Retrieves the first child property id of a specified property id.
const char * GetLabel(FbxInt pId=0)
EFlags
Property flags that affect their behaviors.
FbxStringSymbol GetName() const
bool HasMinMax(EValueIndex pId) const
FbxInt GetFirstDescendent(FbxInt pAnscestorId=0) const
Retrieves the first descendent property id of a specified property id.
bool Set(const void *pValue, EFbxType pValueType)
bool DisconnectSrc(FbxInt pDstId, FbxPropertyPage *pSrcPage, FbxInt pSrcId)
void InsertEnumValue(FbxInt pId, int pIndex, const char *pStringValue)
#define NULL
Definition: fbxarch.h:213
FbxPropertyPage * GetPage()
This class is to mark a string as symbol.
Definition: fbxsymbol.h:81
bool ModifyFlags(FbxPropertyFlags::EFlags pFlags, bool pValue)
Utility class to manipulate strings.
Definition: fbxstring.h:66
FbxConnectionPoint * GetSrc(int pIndex) const
FbxConnectionPoint * GetDst(int pIndex) const
FbxPropertyPage(const char *pName, EFbxType pType)
FbxPropertyFlags::EInheritType GetValueInherit(FbxInt pId, bool pCheckInstanceOf) const
FbxPropertyPage * mPage
void InsertEnumValue(int pIndex, const char *pStringValue)
bool SetUserData(FbxInt pId=0, const void *pUserData=0)
void WipeAllConnections()
Clear all connect without sending any notification (Internal use ONLY)
bool Set(FbxInt pId, const T &pValue)
T Get(FbxInt pId, const T *pFBX_TYPE)
char * GetEnumValue(FbxInt pId, int pIndex)
void Set(FbxPropertyInfo *pInfo)
void FbxDelete(T *p)
Deletion policy for pointer template classes that uses the FbxDelete() function.
Definition: fbxnew.h:341
FbxPropertyConnect * Get(const FbxPropertyConnect *)
bool SetMask(FbxPropertyFlags::EFlags pFlags)
FbxPropertyFlags * Get(const FbxPropertyFlags *)
FbxPair< FbxInt, const char * > FbxNameMapKey
FbxPropertyPage(const char *pName, FbxPropertyPage *pTypeInfo)
void SetEnumValue(FbxInt pId, int pIndex, const char *pStringValue)
This allocator only frees the allocated memory when it is deleted.
void Set(FbxPropertyConnect *pConnect)
int GetDstCount(FbxConnectionPointFilter *pFilter)
bool IsDescendentOf(FbxInt pId, FbxInt pAncestorId) const
bool IsConnectedSrc(FbxInt pDstId, FbxPropertyPage *pSrcPage, FbxInt pSrcId)
Property override this flag from its reference property.
static FbxPropertyConnect * Create(FbxPropertyPage *pPage, FbxInt pId)
static FbxPropertyEntry * Create(FbxInt pParentId, FbxPropertyInfo *pInfo, FbxPropertyValue *pValue, FbxPropertyConnect *pConnect)
int GetSrcCount(FbxConnectionPointFilter *pFilter)
bool Reparent(FbxInt, FbxInt)
Property inherit this flag from its reference property.
static FbxPropertyPage * Create(const char *pName, EFbxType pType=eFbxUndefined)
static FbxPropertyInfo * Create(const char *pName, FbxPropertyPage *pTypeInfo)
void Set(FbxPropertyFlags *pType)
void BeginCreateOrFindProperty()
bool GetMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId, void *pValue, EFbxType pValueType)
bool ConnectDst(FbxInt pSrcId, FbxPropertyPage *pDstPage, FbxInt pDstId, FbxConnection::EType pType)
This class implements an efficient map based on key comparison, which stores key-value pairs...
Definition: fbxmap.h:68
EFbxType GetType(FbxInt pId=0) const
bool GetMinMax(EValueIndex pId, void *pValue, EFbxType pValueType) const
EFbxType
Type identifier constants.
bool IsConnectedSrc(FbxPropertyConnect *pSrc)
FbxPropertyFlags::EInheritType GetFlagsInheritType(FbxPropertyFlags::EFlags pFlags) const
const char * GetName(FbxInt pId=0)
void EndCreateOrFindProperty()
bool IsEmpty()
FbxPropertyFlags::EFlags GetMergedFlags(FbxPropertyFlags::EFlags pFlags) const
bool SetUserTag(FbxInt pId=0, int pUserTag=0)
bool SetFlags(FbxPropertyFlags::EFlags pMask, FbxPropertyFlags::EFlags pFlags)
bool SetFlagsInheritType(FbxPropertyFlags::EInheritType pInheritType, FbxPropertyFlags::EFlags pFlags, FbxInt pId=0)
bool IsChildOf(FbxInt pId, FbxInt pParentId) const
void SetUserData(const void *pUserData)
FbxInt GetSibling(FbxInt pId) const
Retrieves the next sibling property id of a specified property id.
static FbxPropertyInfo * Create(const char *pName, EFbxType pType=eFbxUndefined)
const FbxPropertyPage * GetInstanceOf() const
T * GetPropertyItem(const T *pItemType, FbxInt pIndex, FbxPropertyPage **pFoundIn=0) const
FbxPropertyInfo * Clone(FbxPropertyPage *)
This class template holds a pair of objects.
Definition: fbxpair.h:22
T * ChangePropertyItemState(const T *pItemType, FbxInt pIndex, FbxPropertyFlags::EInheritType pInheritType)
bool IsConnectedDst(FbxInt pSrcId, FbxPropertyPage *pDstPage, FbxInt pDstId)
bool FbxTypeCompare(const void *pA, const void *pB, const EFbxType pType)
Compare two values of the same type.
void Set(FbxPropertyValue *pValue)
EFbxType FbxTypeOf(const FbxChar &)
Enumeration allowing duplicated items.
void * GetDataPtr() const
FbxPropertyValue * Get(const FbxPropertyValue *)
FbxPropertyConnect * Clone(FbxPropertyPage *pPage)
bool Set(FbxInt pId, const void *pValue, EFbxType pValueType, bool pCheckValueEquality)
FbxPropertyValue * Clone(FbxPropertyPage *)
FbxInt GetParentId()
void Set(FbxPropertyFlags pType)
char * Buffer()
Non-const buffer access.
bool SetMinMax(EValueIndex pId, const void *pValue, EFbxType pValueType)
#define FBX_TYPE(class)
Convert the class type parameter into a C class parameter for other function inputs.
Definition: fbxobject.h:1476
const FbxSet< FbxPropertyPage * > & GetInstances() const
Class to manage Connect Filter.
bool IsConnectedDst(FbxPropertyConnect *pSrc)
const FbxString & Append(const char *pString, size_t pLength)
Append as "C" strncat().
#define FBXSDK_PROPERTY_ID_ROOT
int operator()(const FbxNameMapKey &pKeyA, const FbxNameMapKey &pKeyB) const
FbxInt GetNextDescendent(FbxInt pAnscestorId, FbxInt pId) const
Retrieves the next descendent property id of a specified property id, with given a descendent propert...
Enumeration.
EFbxType GetType() const
void RemoveEnumValue(FbxInt pId, int pIndex)
Second mSecond
The second object in the pair.
Definition: fbxpair.h:57
FbxInt GetNextId() const
bool FbxTypeDeallocate(const EFbxType pType, void *pData)
Destroys an fbx primitive type.
void ClearConnectCache(FbxInt pId)
FbxPropertyConnect * GetDst(FbxConnectionPointFilter *pFilter, int pIndex)
bool FbxTypeCopy(T1 &, const T2 &)
FbxVectorTemplate4< FbxDouble4 > FbxDouble4x4
Definition: fbxtypes.h:260
void * GetUserData(FbxInt pId=0)
FbxPropertyPage(FbxPropertyPage *pInstanceOf=0)
FbxInt FastFind(FbxInt pId, const char *pName, FbxPropertyPage *pTypeInfo, bool pCaseSensitive)
FbxPropertyPage * GetTypeInfo(FbxInt pId=0)
bool HasMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId) const
#define FBXSDK_DLL
Definition: fbxarch.h:176
FbxPropertyFlags::EFlags GetMask() const
bool GetDst(FbxInt pId, int pIndex, FbxConnectionPointFilter *pFilter, FbxPropertyPage **pDstPage, FbxInt *pDstId)
const char * GetLabel() const
bool SetValueInherit(FbxInt pId, FbxPropertyFlags::EInheritType pType)
bool DisconnectDst(FbxInt pSrcId, FbxPropertyPage *pDstPage, FbxInt pDstId)
void * FbxTypeAllocate(const EFbxType pType)
Creates a fbx primitive type and initializes its memory.
signed int FbxInt
Definition: fbxtypes.h:39
bool DisconnectSrc(FbxPropertyConnect *pSrc)
int GetUserTag(FbxInt pId=0)
void * GetUserData() const
bool ModifyFlags(FbxInt pId=0, FbxPropertyFlags::EFlags pFlags=FbxPropertyFlags::eNone, bool pValue=true, bool pCheckFlagEquality=true)
void SetDataPtr(void *pDataPtr)
FbxPropertyFlags::EFlags GetFlags(FbxInt pId=0) const
First mFirst
The first object in the pair.
Definition: fbxpair.h:56
static FbxPropertyValue * Create(void *pData, EFbxType pType)
static FbxPropertyPage * Create(FbxPropertyPage *pInstanceOf=0)
int AddEnumValue(const char *pStringValue)
int AddEnumValue(FbxInt pId, const char *pStringValue)
char * GetEnumValue(int pIndex)
bool GetDefaultValue(FbxInt pId, void *pValue, EFbxType pValueType) const
FbxPropertyFlags::EInheritType GetFlagsInheritType(FbxPropertyFlags::EFlags pFlags, bool pCheckInstanceOf, FbxInt pId=0) const
bool ConnectSrc(FbxPropertyConnect *pSrc, FbxConnection::EType pType)
bool Equal(const FbxPropertyFlags &pOther, FbxPropertyFlags::EFlags pFlags) const
void WipeAllConnections(FbxInt pId)
bool GetSrc(FbxInt pId, int pIndex, FbxConnectionPointFilter *pFilter, FbxPropertyPage **pSrcPage, FbxInt *pSrcId)
void WipeConnectionList()
Clear the ConnectList without any regards to what is connected.
FbxInt Add(FbxInt pParentId, const char *pName, FbxPropertyPage *pTypeInfo)
bool SetMinMax(FbxInt pId, FbxPropertyInfo::EValueIndex pValueId, const void *pValue, EFbxType pValueType)
FbxPropertyPage * GetFirstPropertyItem(FbxInt pId, const T *pItem) const
void RemoveEnumValue(int pIndex)
Property has been deleted, so inheritance is invalid.
void SetEnumValue(int pIndex, const char *pStringValue)
EInheritType
Property inherit types.
int GetEnumCount(FbxInt pId)
static FbxPropertyPage * Create(const char *pName, FbxPropertyPage *pTypeInfo)
bool Is(FbxPropertyPage *pPage)
FbxInt Find(FbxInt pId, const char *pName, FbxPropertyPage *pTypeInfo, bool pCaseSensitive, const char *pChildrenSeparators)
bool DisconnectDst(FbxPropertyConnect *pDst)
StorageType::RecordType RecordType
Definition: fbxmap.h:98
bool Get(void *pValue, EFbxType pValueType)
void Destroy()
int GetDstCount(FbxInt pId, FbxConnectionPointFilter *pFilter)
bool SetLabel(FbxInt pId=0, const char *pLabel="")