bool CSkeletonCandidate::AddNode(CBaseNode *pNode, int parentId) { // check if the node is valid if(pNode == 0) { theExporter.SetLastError("Invalid handle!", __FILE__, __LINE__); return false; } // Don't add any nodes that have already been added. for (size_t i = 0; i < m_vectorBoneCandidate.size(); ++i) { if (*m_vectorBoneCandidate[i]->GetNode() == *pNode) { delete pNode; return true; } } // if the node does not get used, we have to delete it! bool bDeleteNode = true; // Check if the node is a candidate //We want to be able to export all type of nodes as bones... //if(theExporter.GetInterface()->IsBone(pNode) || theExporter.GetInterface()->IsDummy(pNode)) { // allocate a new bone candidate CBoneCandidate *pBoneCandidate = new CBoneCandidate; if(pBoneCandidate == 0) { delete pNode; theExporter.SetLastError("Memory allocation failed!", __FILE__, __LINE__); return false; } // create the bone candidate if(!pBoneCandidate->Create(m_vectorBoneCandidate.size(), parentId, pNode)) { delete pBoneCandidate; return false; } //when the node is a dummy, it's not selected, so select it anyway... pBoneCandidate->SetSelected(true); // insert node element into hierarchy m_vectorBoneCandidate.push_back(pBoneCandidate); // insert node element id into parent node element if(parentId == -1) { // no parent -> this is a root node m_listRootBoneCandidateId.push_back(pBoneCandidate->GetId()); } else { // valid parent -> this is a child node m_vectorBoneCandidate[parentId]->AddChildId(pBoneCandidate->GetId()); } // set parent id for the children parentId = pBoneCandidate->GetId(); bDeleteNode = false; } // handle all children of the node for(int childId = 0; childId < pNode->GetChildCount(); childId++) { if(!AddNode(pNode->GetChild(childId), parentId)) { // free the node of needed if(bDeleteNode) { delete pNode; } return false; } } // free the node of needed if(bDeleteNode) { delete pNode; } return true; }
bool CMaxInterface::ExportAnimationFromMaxscriptCall(const std::string& strFilename, void* _AnimExportParams) { if (!_AnimExportParams) { theExporter.SetLastError("_AnimExportParams pointer is null.", __FILE__, __LINE__); return false; } AnimExportParams* param = reinterpret_cast<AnimExportParams*>(_AnimExportParams); // build a skeleton candidate CSkeletonCandidate skeletonCandidate; //Remove user interface /*// show export wizard sheet CAnimationExportSheet sheet("Cal3D Animation Export", GetMainWnd()); sheet.SetSkeletonCandidate(&skeletonCandidate); sheet.SetAnimationTime(GetStartFrame(), GetEndFrame(), GetCurrentFrame(), GetFps()); sheet.SetWizardMode(); if(sheet.DoModal() != ID_WIZFINISH) return true; */ //Following block replaces the user interface interactions { // create the skeleton candidate from the skeleton file if(! skeletonCandidate.CreateFromSkeletonFile(param->m_skeletonfilepath)) { AfxMessageBox(theExporter.GetLastError().c_str(), MB_OK | MB_ICONEXCLAMATION); return false; } //Set all bones in our array of nodes selected std::vector<CBoneCandidate *>& vectorBoneCandidate = skeletonCandidate.GetVectorBoneCandidate(); int NumElemInTabMaxscript = param->m_tabbones.Count(); // Select bone candidates that are in our array int idx = 0; const int numelems = vectorBoneCandidate.size(); for (idx = 0;idx<numelems;idx++) { CBoneCandidate * bonecandidate = vectorBoneCandidate[idx]; if (! bonecandidate)return false; //Deselect it bonecandidate->SetSelected(false); int j; for (j=0;j<NumElemInTabMaxscript;j++) { std::string bcname = bonecandidate->GetNode()->GetName(); std::string bonename = param->m_tabbones[j]->GetName(); if (bcname == bonename) { //This bone candidate is in the array passed by maxscript, so select it. bonecandidate->SetSelected(true); break; } } } } CalCoreAnimationPtr coreAnimation = theExporter.ExtractAnimation( skeletonCandidate, param->m_startframe, param->m_endframe, param->m_frameoffset, GetFps(), param->m_framerate); if (!coreAnimation) { return false; } // save core animation to the file if(!CalSaver::saveCoreAnimation(strFilename, coreAnimation.get())) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); return false; } return true; }