void CMaxMaterialCollection::OnPreFileLinkEvent() { //stash all FileLinked materials int a tab. When the event is complete, //we need to update refcounts and notify any clients or removals //assert(mCacheLinkedMtls.size() == 0); if(mCacheLinkedMtls.size() != 0) return; //this can happen on PRE_NEW which spawns a PRE_BIND, no need to collect again IVizLinkTable* linktbl = static_cast<IVizLinkTable*>(GetCOREInterface(FILELINKMGR_INTERFACE_ID)); if(!linktbl) return; //Iterate through the linked materials. For any new material, create a COM wrapper. //Creating the wrapper will also fire and event to the palette system. int numlinks = linktbl->NumLinkedFiles(); IVizLinkTable::Iterator it; for(int i =0; i<numlinks; i++) { if(!linktbl->GetLinkID(i, it)) continue; LinkTableRecord *pLTR = linktbl->RecordAt(it); if((pLTR == NULL) || (pLTR->ClassID() != DWGTABLERECORD_CLASSID)) continue; ReferenceMaker* pMtls = pLTR->GetReference(DTR_MTLTABLE_REF); if((pMtls == NULL) || (pMtls->ClassID() != VZMATERIALTABLE_CLASSID)) continue; int numMtls = pMtls->NumRefs(); //enlarge our tab // mCacheLinkedMtls.Resize(mCacheLinkedMtls.Count() + numMtls); for(int i=0; i< numMtls; i++) { //get the max material to be wrapped ReferenceTarget *rtarg = pMtls->GetReference(i); if((rtarg == NULL) || (rtarg->SuperClassID() != MATERIAL_CLASS_ID)) continue; Mtl* pMtl = (Mtl*)rtarg; assert(pMtl); //find the wrapper, which we should have already ifxClxnType::iterator it = mMtlMap.find((DWORD_PTR)pMtl); if(it != mMtlMap.end()) mCacheLinkedMtls.insert(*it); else assert(0); //mCacheLinkedMtls.Append(1, &pMtl); }//next mtl }//next link }
void mrGeomShaderObject::UserDlgProc::SetThing(ReferenceTarget *m) { ReferenceMaker* owner = m; if((owner == NULL) || ((owner->SuperClassID() == GEOMOBJECT_CLASS_ID) && (owner->ClassID() == MRGEOMETRYOBJECT_CLASS_ID))) { m_theObject = static_cast<mrGeomShaderObject*>(owner); } else { DbgAssert(false); m_theObject = NULL; } }
static ICustAttribContainer * GetOwnerContainer(ReferenceTarget * owner) { if (NULL == owner) { return NULL; } //Lets find our Parent - which should be a custom Attribute Container DependentIterator di(owner); ReferenceMaker* maker = NULL; while ((maker = di.Next()) != NULL) { if (maker->SuperClassID() == REF_MAKER_CLASS_ID && maker->ClassID() == CUSTATTRIB_CONTAINER_CLASS_ID ) { return (ICustAttribContainer*)maker; } } return NULL; }
bool plAnimStealthNode::IsParentUsedInScene( void ) { if( GetParentMtl() == nil ) return false; // There are two possibilities: either a node uses us and thus has a ref to us, // or a multi-sub uses us that a node has a ref to us. // Note: we could do the loop as a helper function, but we only do it twice, // so it's not *really* worth the effort... //// NOTE: the following doesn't seem to work, but keeping here in case it ever does. //// What really actually finds something is the enum dependents loop below const char *mtlName = GetParentMtl()->GetName(); DependentIterator di(this); ReferenceMaker* item = di.Next(); while( item != nil ) { TSTR s; item->GetClassName( s ); if( item->SuperClassID() == BASENODE_CLASS_ID && !CanConvertToStealth( (INode *)( item ) ) ) return true; // Horray, a node has a ref to us! else if( item->ClassID() == Class_ID(MULTI_CLASS_ID,0) ) { // Multi-sub, run the refs on that guy (we only go one up) Mtl *multisub = (Mtl *)item; DependentIterator sub(multisub); ReferenceMaker* item2 = sub.Next(); while( item2 != nil ) { if( item2->SuperClassID() == BASENODE_CLASS_ID ) return true; // Horray, a node has a ref to us! item2 = sub.Next(); } // No go, keep trying } else if( item->SuperClassID() == MATERIAL_CLASS_ID ) { int q = 0; } item = di.Next(); } // Enum dependents plGetRefs callback; ENUMDEPENDENTS(GetParentMtl(), &callback); for(int i = 0; i < callback.fList.GetCount(); i++ ) { ReferenceMaker *maker = callback.fList[ i ]; TSTR s; maker->GetClassName( s ); if( maker->SuperClassID() == BASENODE_CLASS_ID && !CanConvertToStealth( (INode *)maker ) ) return true; // Horray, a node has a ref to us! } return false; }
void CMaxMaterialCollection::OnFileLinkMtlsChanged() { //look for any new materials (i.e unwrapped) and add them //existing ones should be updated IVizLinkTable* linktbl = static_cast<IVizLinkTable*>(GetCOREInterface(FILELINKMGR_INTERFACE_ID)); if(!linktbl) return; //Iterate through the linked materials. For any new material, create a COM wrapper. //Creating the wrapper will also fire and event to the palette system. int numlinks = linktbl->NumLinkedFiles(); IVizLinkTable::Iterator it; for(int j =0; j<numlinks; j++) { if(!linktbl->GetLinkID(j, it)) continue; LinkTableRecord *pLTR = linktbl->RecordAt(it); if((pLTR == NULL) || (pLTR->ClassID() != DWGTABLERECORD_CLASSID)) continue; ReferenceMaker* pMtls = pLTR->GetReference(DTR_MTLTABLE_REF); if((pMtls == NULL) || (pMtls->ClassID() != VZMATERIALTABLE_CLASSID)) continue; int numMtls = pMtls->NumRefs(); for(int i=0; i< numMtls; i++) { //get the max material to be wrapped ReferenceTarget *rtarg = pMtls->GetReference(i); if((rtarg == NULL) || (rtarg->SuperClassID() != MATERIAL_CLASS_ID)) continue; Mtl* pMtl = (Mtl*)rtarg; assert(pMtl); DWORD_PTR key = (DWORD_PTR) pMtl; CMaxMaterial* pWrapper = findItemKey(key); if (pWrapper != NULL) { pWrapper->CheckReference(false, true); #ifdef TP_SUSPEND_FOR_FILELINK //processed so remove it from the cache mCacheLinkedMtls.erase(key); #endif continue; } //Create the wrapper CComObject<CMaxMaterial> *pWrapperObject; HRESULT hr = CComObject<CMaxMaterial>::CreateInstance(&pWrapperObject); assert(SUCCEEDED(hr)); if(!SUCCEEDED(hr)) { s_PreventRecursion = false; return; } //Initalize the new wrapper pWrapperObject->setCollection(this); //TODO validate the downcast pWrapperObject->setMtl((Mtl *)pMtl); }//next mtl }//next link #ifdef TP_SUSPEND_FOR_FILELINK //Note that if a material is removed by filelink, we should really remove entirely //anything left in mCacheLinkedMtls at this point is a candidate for destructo //or at least an update ifxClxnType::iterator iter=mCacheLinkedMtls.begin(); while(iter!=mCacheLinkedMtls.end()) { MtlWrapper *pWrapper = (*iter).second; assert(pWrapper); OnMtlDeleted(pWrapper, (*iter).first); // pMtlWrapper->CheckReference(false, true); iter++; } mCacheLinkedMtls.clear(); #endif }