PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Dependencies/OgreCollada/FCollada/ColladaMaya/CReferenceManager.cpp

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C++ | 676 lines | 497 code | 91 blank | 88 comment | 142 complexity | 10adf2be7510c8dea22a28de01fbbb05 MD5 | raw file
  1. /*
  2. Copyright (C) 2005-2007 Feeling Software Inc.
  3. Portions of the code are:
  4. Copyright (C) 2005-2007 Sony Computer Entertainment America
  5. MIT License: http://www.opensource.org/licenses/mit-license.php
  6. */
  7. #include "StdAfx.h"
  8. #include <maya/MFileIO.h>
  9. #include <maya/MCommandResult.h>
  10. #include <maya/MStringArray.h>
  11. #include "CExportOptions.h"
  12. #include "CReferenceManager.h"
  13. #include "TranslatorHelpers/CDagHelper.h"
  14. #include "FUtils/FUFileManager.h"
  15. #include "FCDocument/FCDocument.h"
  16. #include "FCDocument/FCDExternalReferenceManager.h"
  17. // Singleton variable
  18. //
  19. CReferenceManager* CReferenceManager::singleton = NULL;
  20. // Singleton constructor / destructor
  21. //
  22. CReferenceManager::CReferenceManager()
  23. {
  24. }
  25. CReferenceManager::~CReferenceManager()
  26. {
  27. CLEAR_POINTER_VECTOR(references);
  28. CLEAR_POINTER_VECTOR(files);
  29. }
  30. // Synchronize the reference manager with the Maya references
  31. //
  32. void CReferenceManager::Synchronize()
  33. {
  34. CLEAR_POINTER_VECTOR(references);
  35. CLEAR_POINTER_VECTOR(files);
  36. if (!CExportOptions::ExportXRefs() || CExportOptions::DereferenceXRefs()) return;
  37. #if MAYA_API_VERSION >= 600
  38. MStatus status;
  39. MStringArray referenceFilenames;
  40. MFileIO::getReferences(referenceFilenames);
  41. uint referenceCount = referenceFilenames.length();
  42. references.reserve(referenceCount);
  43. for (uint i = 0; i < referenceCount; ++i)
  44. {
  45. MString& filename = referenceFilenames[i];
  46. MObject referenceNode = GetReferenceNode(filename);
  47. if (referenceNode != MObject::kNullObj) ProcessReference(referenceNode);
  48. }
  49. #endif
  50. }
  51. void CReferenceManager::ProcessReference(const MObject& referenceNode)
  52. {
  53. MStatus status;
  54. MFnDependencyNode referenceNodeFn(referenceNode, &status);
  55. if (status != MStatus::kSuccess) return;
  56. #if MAYA_API_VERSION >= 600
  57. CReference* reference = new CReference();
  58. references.push_back(reference);
  59. reference->referenceNode = referenceNode;
  60. MString referenceNodeName = MFnDependencyNode(reference->referenceNode).name();
  61. // Get the paths of the root transforms included in this reference
  62. MObjectArray subReferences;
  63. GetRootObjects(referenceNode, reference->paths, subReferences);
  64. uint pathCount = reference->paths.length();
  65. // Process the sub-references first
  66. uint subReferenceCount = subReferences.length();
  67. for (uint i = 0; i < subReferenceCount; ++i)
  68. {
  69. MObject& subReference = subReferences[i];
  70. if (subReference != MObject::kNullObj) ProcessReference(subReference);
  71. }
  72. // Retrieve the reference node's filename
  73. MString command = MString("reference -rfn \"") + referenceNodeFn.name() + MString("\" -q -filename;");
  74. MString filename;
  75. status = MGlobal::executeCommand(command, filename);
  76. if (status != MStatus::kSuccess || filename.length() == 0) return;
  77. // Strip the filename of the multiple file token
  78. int stripIndex = filename.index('{');
  79. if (stripIndex != -1) filename = filename.substring(0, stripIndex - 1);
  80. // Avoid transform look-ups on COLLADA references.
  81. int extLocation = filename.rindex('.');
  82. if (extLocation > 0)
  83. {
  84. MString ext = filename.substring(extLocation + 1, filename.length() - 1).toLowerCase();
  85. if (ext == "dae" || ext == "xml") return;
  86. }
  87. // Check for already existing file information
  88. // Otherwise create a new file information sheet with current node names
  89. for (CReferenceFileList::iterator it = files.begin(); it != files.end(); ++it)
  90. {
  91. if ((*it)->filename == filename) { reference->file = (*it); break; }
  92. }
  93. if (reference->file == NULL) reference->file = ProcessReferenceFile(filename);
  94. // Get the list of the root transform's first child's unreferenced parents.
  95. // This is a list of the imported nodes!
  96. for (uint j = 0; j < pathCount; ++j)
  97. {
  98. MDagPath path = reference->paths[j];
  99. if (path.childCount() > 0)
  100. {
  101. path.push(path.child(0));
  102. MFnDagNode childNode(path);
  103. if (!childNode.object().hasFn(MFn::kTransform)) continue;
  104. uint parentCount = childNode.parentCount();
  105. for (uint k = 0; k < parentCount; ++k)
  106. {
  107. MFnDagNode parentNode(childNode.parent(k));
  108. if (parentNode.object() == MObject::kNullObj || parentNode.isFromReferencedFile()) continue;
  109. MDagPath parentPath = MDagPath::getAPathTo(parentNode.object());
  110. if (parentPath.length() > 0)
  111. {
  112. CReferenceRootList::iterator it = reference->reroots.insert(reference->reroots.end(), CReferenceRoot());
  113. (*it).index = j;
  114. (*it).reroot = parentPath;
  115. }
  116. }
  117. }
  118. }
  119. #endif
  120. }
  121. CReferenceFile* CReferenceManager::ProcessReferenceFile(const MString& filename)
  122. {
  123. CReferenceFile* file = new CReferenceFile();
  124. file->filename = filename;
  125. files.push_back(file);
  126. #if MAYA_API_VERSION >= 800
  127. return file; // Versions 8.00 and 8.50 of Maya don't allow us to create references inside a plug-in.
  128. #elif MAYA_API_VERSION >= 600
  129. // Get the original transformations for this file.
  130. // 1. Create a new reference
  131. MString tempFilename;
  132. MObject tempReferenceNode;
  133. {
  134. MString command = MString("file -r -type \"COLLADA importer\" -namespace \"_TEMP_EXP_NAMESPACE\" \"") + filename + "\";";
  135. MGlobal::executeCommand(command, tempFilename);
  136. tempFilename = GetLastReferenceFilename(tempFilename);
  137. MObject tempReferenceNode = GetReferenceNode(tempFilename);
  138. MString tempNodeName = MFnDependencyNode(tempReferenceNode).name();
  139. command = MString("file -loadReference \"") + tempNodeName + "\" \"" + tempFilename + "\";";
  140. MGlobal::executeCommand(command);
  141. }
  142. // 2. Get the original transformations for the root transforms of the temporary reference object
  143. MDagPathArray tempRoots;
  144. MObjectArray subReferences;
  145. GetRootObjects(tempReferenceNode, tempRoots, subReferences);
  146. uint tempRootCount = tempRoots.length();
  147. for (uint j = 0; j < tempRootCount; ++j)
  148. {
  149. MFnTransform tempT(tempRoots[j]);
  150. file->originalTransformations.push_back(tempT.transformation());
  151. }
  152. // 3. Get the original node names. This will be used as the URL for export
  153. file->rootNames.setLength(tempRootCount);
  154. for (uint j = 0; j < tempRootCount; ++j)
  155. {
  156. MString& originalName = file->rootNames[j];
  157. originalName = tempRoots[j].partialPathName();
  158. originalName = originalName.substring(originalName.index(':') + 1, originalName.length());
  159. }
  160. // 4. Cleanup: remove this reference
  161. MString command = MString("file -rr \"") + tempFilename + "\";";
  162. MGlobal::executeCommand(command);
  163. #endif // MAYA >= 600
  164. return file;
  165. }
  166. // Find the reference information for a given dag path
  167. CReference* CReferenceManager::FindReference(const MDagPath& path, uint* referenceIndex)
  168. {
  169. for (CReferenceList::iterator it = references.begin(); it != references.end(); ++it)
  170. {
  171. uint pathCount = (*it)->paths.length();
  172. for (uint j = 0; j < pathCount; ++j)
  173. {
  174. if (path.node() == (*it)->paths[j].node())
  175. {
  176. if (referenceIndex != NULL) *referenceIndex = j;
  177. return (*it);
  178. }
  179. }
  180. }
  181. *referenceIndex = UINT_MAX;
  182. return NULL;
  183. }
  184. CReference* CReferenceManager::FindReference(CReferenceFile* file)
  185. {
  186. for (CReferenceList::iterator it = references.begin(); it != references.end(); ++it)
  187. {
  188. if ((*it)->file == file) return (*it);
  189. }
  190. return NULL;
  191. }
  192. CReference* CReferenceManager::FindRerootedReference(const MDagPath& path, uint* referenceIndex)
  193. {
  194. for (CReferenceList::iterator itR = references.begin(); itR != references.end(); ++itR)
  195. {
  196. for (CReferenceRootList::iterator it = (*itR)->reroots.begin(); it != (*itR)->reroots.end(); ++it)
  197. {
  198. if ((*it).reroot.node() == path.node())
  199. {
  200. if (referenceIndex != NULL) *referenceIndex = (*it).index;
  201. return (*itR);
  202. }
  203. }
  204. }
  205. if (referenceIndex != NULL) *referenceIndex = UINT_MAX;
  206. return NULL;
  207. }
  208. // remove the prefix of a reference name
  209. MString CReferenceManager::GetReferencePrefix(const MString& filename)
  210. {
  211. MString prefix = filename;
  212. int index = prefix.rindex('/');
  213. if (index != -1) prefix = prefix.substring(index + 1, prefix.length());
  214. index = prefix.rindex('\\');
  215. if (index != -1) prefix = prefix.substring(index + 1, prefix.length());
  216. index = prefix.index('.');
  217. if (index != -1) prefix = prefix.substring(0, index - 1);
  218. return prefix;
  219. }
  220. void CReferenceManager::RemoveReferencePrefix(MString& name, CReference* reference)
  221. {
  222. int index = name.index(':');
  223. if (index >= 0)
  224. {
  225. // Namespace prefix
  226. name = name.substring(index + 1, name.length());
  227. }
  228. else
  229. {
  230. // Filename prefix
  231. MString prefix = GetReferencePrefix(reference->file->filename);
  232. name = name.substring(prefix.length() + 1, name.length());
  233. }
  234. }
  235. // For import, create a new reference, given a URL
  236. CReference* CReferenceManager::CreateReference(const FUUri& url)
  237. {
  238. CReference* reference = NULL;
  239. #if MAYA_API_VERSION >= 600
  240. MString prefix = GetReferencePrefix(url.GetAbsoluteUri().c_str());
  241. CReferenceFile* file = NULL;
  242. for (CReferenceFileList::iterator it = files.begin(); it != files.end(); ++it)
  243. {
  244. if ((*it)->prefix == prefix) { file = (*it); break; }
  245. }
  246. // If this is a new file, create a structure for it.
  247. // Otherwise, look for an unused entry
  248. if (file == NULL)
  249. {
  250. file = new CReferenceFile();
  251. file->filename = url.GetAbsolutePath().c_str();
  252. file->prefix = prefix;
  253. files.push_back(file);
  254. reference = CreateReference(file);
  255. }
  256. else
  257. {
  258. reference = FindReference(file);
  259. }
  260. #endif
  261. return reference;
  262. }
  263. // For import, create a new reference, given a URL
  264. CReference* CReferenceManager::CreateReference(const MDagPath& transform, const FUUri& url)
  265. {
  266. CReference* reference = CreateReference(url);
  267. #if MAYA_API_VERSION >= 600
  268. // Use the correct reference(s) for non-COLLADA documents
  269. fstring _ext = FUFileManager::GetFileExtension(url.GetAbsoluteUri());
  270. MString extension = _ext.c_str();
  271. extension.toLowerCase();
  272. if (reference != NULL && extension != "dae" && extension != "xml")
  273. {
  274. if (url.GetFragment().length() == 0)
  275. {
  276. uint pathCount = reference->paths.length();
  277. for (uint i = 0; i < pathCount; ++i)
  278. {
  279. UseReference(reference, i, transform);
  280. }
  281. }
  282. else
  283. {
  284. int index = FindRootName(reference->file, url.GetFragment().c_str());
  285. if (index == -1) return NULL;
  286. UseReference(reference, (uint) index, transform);
  287. }
  288. }
  289. #endif
  290. return reference;
  291. }
  292. MString CReferenceManager::GetMayaFriendlyFilename(MString filename)
  293. {
  294. MString fixedFilename("");
  295. // replace "\" with "/"
  296. int slashIndex = filename.index('\\');
  297. while (slashIndex != -1)
  298. {
  299. if (slashIndex > 0)
  300. {
  301. fixedFilename += filename.substring(0, slashIndex - 1);
  302. }
  303. fixedFilename += "/";
  304. if ((slashIndex + 1) == filename.length())
  305. {
  306. filename.clear();
  307. break;
  308. }
  309. filename = filename.substring(slashIndex + 1, filename.length() - 1);
  310. slashIndex = filename.index('\\');
  311. }
  312. fixedFilename += filename;
  313. return fixedFilename;
  314. }
  315. CReference* CReferenceManager::CreateReference(CReferenceFile* file)
  316. {
  317. if (file == NULL) return NULL;
  318. #if MAYA_API_VERSION < 650
  319. if (!CImportOptions::IsOpenMode())
  320. {
  321. MGlobal::displayError("Use File->Open instead. Maya versions 6.0 and below don't accept references during import!");
  322. CImportOptions::SetErrorFlag();
  323. return NULL;
  324. }
  325. #endif
  326. if (CImportOptions::FileLoadDeferReferencesOption())
  327. {
  328. MGlobal::displayError("Load All References option interferes with the actual loading of the references. set this option to false: File->Open (Options)->Load All References.");
  329. CImportOptions::SetErrorFlag();
  330. return NULL;
  331. }
  332. MStatus status;
  333. // Generate a unique namespace for this reference
  334. MString prefix = file->prefix + ++(file->usageCount);
  335. // Create a new reference for the given filename
  336. CReference* reference = new CReference();
  337. reference->file = file;
  338. references.push_back(reference);
  339. #if MAYA_API_VERSION >= 800
  340. {
  341. MString filename = GetMayaFriendlyFilename(file->filename);
  342. status = MFileIO::reference(filename, true);
  343. if (status != MStatus::kSuccess) { MGlobal::displayError(MString("Unable to create reference for file: ") + filename + ".\nMStatus:" + status.error()); return NULL; }
  344. MStringArray referenceNodeNames;
  345. MFileIO::getReferenceNodes(filename, referenceNodeNames);
  346. if (referenceNodeNames.length() == 0)
  347. {
  348. MGlobal::displayWarning(MString("Maya refused the reference for file. Attempting alternative path. ") + file->filename + ".");
  349. MString finalReferenceFilename = MFileIO::loadReference(filename, &status);
  350. if (status != MStatus::kSuccess) { MGlobal::displayError(MString("Maya refused to load the reference for file: ") + file->filename + ".\nMStatus:" + status.error()); return NULL; }
  351. reference->referenceNode = GetReferenceNode(finalReferenceFilename);
  352. }
  353. else
  354. {
  355. MString referenceNodeName = referenceNodeNames[referenceNodeNames.length() - 1];
  356. MFileIO::loadReferenceByNode(referenceNodeName, &status);
  357. if (status != MStatus::kSuccess) { MGlobal::displayError(MString("Maya refused to load the reference for file: ") + file->filename + ".\nMStatus:" + status.error()); return NULL; }
  358. reference->referenceNode = CDagHelper::GetNode(referenceNodeName);
  359. }
  360. if (reference->referenceNode == MObject::kNullObj) return NULL;
  361. }
  362. #else
  363. {
  364. MString referenceFilename;
  365. MString command = MString("file -r -dr true -namespace \"") + prefix + "\" \"" + file->filename + "\";";
  366. status = MGlobal::executeCommand(command, referenceFilename);
  367. referenceFilename = GetLastReferenceFilename(referenceFilename);
  368. if (status != MStatus::kSuccess) { MGlobal::displayError(MString("Unable to create reference for file: ") + file->filename + ".\nMStatus:" + status.error()); return NULL; }
  369. command = MString("file -loadReference \"") + prefix + "\" \"" + referenceFilename + "\";";
  370. status = MGlobal::executeCommand(command);
  371. reference->referenceNode = GetReferenceNode(referenceFilename);
  372. if (reference->referenceNode == MObject::kNullObj) return NULL;
  373. }
  374. #endif // MAYA 6.0, 6.5 and 7.0
  375. // Get the root transforms for the new reference object
  376. MObjectArray subReferences;
  377. GetRootObjects(reference->referenceNode, reference->paths, subReferences);
  378. uint rootPathCount = reference->paths.length();
  379. if (rootPathCount == 0) return NULL;
  380. // Fill in the file information's root names, if empty.
  381. if (file->rootNames.length() == 0)
  382. {
  383. for (uint i = 0; i < rootPathCount; ++i)
  384. {
  385. MString rootName = reference->paths[i].partialPathName();
  386. RemoveReferencePrefix(rootName, reference);
  387. file->rootNames.append(rootName);
  388. }
  389. }
  390. // set all the root paths invisible, reparenting will occur for each instantiation
  391. for (uint i = 0; i < rootPathCount; ++i)
  392. {
  393. // Hide every root transform and add them to the unused list
  394. CDagHelper::SetPlugValue(reference->paths[i].transform(), "visibility", false);
  395. }
  396. return reference;
  397. }
  398. // Returns whether the given path is a root transform in the given list of paths
  399. bool CReferenceManager::IsRootTransform(const MDagPathArray& allPaths, const MDagPath& testPath)
  400. {
  401. MStatus status;
  402. MFnTransform transform(testPath, &status);
  403. if (status != MStatus::kSuccess) return false;
  404. uint pathCount = allPaths.length();
  405. uint parentCount = transform.parentCount();
  406. for (uint k = 0; k < parentCount; ++k)
  407. {
  408. MFnDependencyNode parentNode(transform.parent(k));
  409. if (!parentNode.isFromReferencedFile()) continue;
  410. for (uint m = 0; m < pathCount; ++m)
  411. {
  412. if (allPaths[m].node() == parentNode.object()) return false;
  413. }
  414. }
  415. return true;
  416. }
  417. void CReferenceManager::GetRootObjects(const MObject& referenceNode, MDagPathArray& rootPaths, MObjectArray& subReferences)
  418. {
  419. rootPaths.clear();
  420. subReferences.clear();
  421. MFnDependencyNode referenceNodeFn(referenceNode);
  422. // Get the paths of all the dag nodes included in this reference
  423. MStringArray nodeNames;
  424. MString command = MString("reference -rfn \"") + referenceNodeFn.name() + "\" -q -node -dp;";
  425. MGlobal::executeCommand(command, nodeNames);
  426. uint nodeNameCount = nodeNames.length();
  427. MDagPathArray nodePaths;
  428. for (uint j = 0; j < nodeNameCount; ++j)
  429. {
  430. MObject o = CDagHelper::GetNode(nodeNames[j]);
  431. MDagPath p = CDagHelper::GetShortestDagPath(o);
  432. if (p.length() > 0)
  433. {
  434. nodePaths.append(p);
  435. }
  436. else
  437. {
  438. if (o != MObject::kNullObj && o.apiType() == MFn::kReference
  439. && strstr(nodeNames[j].asChar(), "_UNKNOWN_REF_NODE") == NULL)
  440. {
  441. subReferences.append(o);
  442. }
  443. }
  444. }
  445. // Keep only the root transform for the reference in our path arrays
  446. uint nodePathCount = nodePaths.length();
  447. for (uint j = 0; j < nodePathCount; ++j)
  448. {
  449. const MDagPath& p = nodePaths[j];
  450. if (!IsRootTransform(nodePaths, p)) continue;
  451. rootPaths.append(p);
  452. }
  453. }
  454. MObject CReferenceManager::GetReferenceNode(const MString& filename)
  455. {
  456. MString referenceNodeName;
  457. MString command = MString("file -q -rfn \"") + filename + "\"";
  458. MGlobal::executeCommand(command, referenceNodeName);
  459. return CDagHelper::GetNode(referenceNodeName);
  460. }
  461. uint CReferenceManager::GetEndIndex(const MString& name)
  462. {
  463. if (name.length() == 0) return 0;
  464. const char* c = name.asChar(), * p;
  465. for (p = c + name.length() - 1; p != c; --p)
  466. {
  467. if (*p < '0' || *p > '9') break;
  468. }
  469. return (uint) atoi(p);
  470. }
  471. void CReferenceManager::UseReference(CReference* reference, uint index, const MDagPath& transform)
  472. {
  473. const MDagPath& root = reference->paths[index];
  474. MFnTransform t(root);
  475. uint tChildCount = t.childCount();
  476. for (uint i = 0; i < tChildCount; ++i)
  477. {
  478. MObject o = t.child(i);
  479. if (o.hasFn(MFn::kDagNode))
  480. {
  481. // Multi-parent the root transform of the reference to be a child of the given transform.
  482. bool isTransform = o.hasFn(MFn::kTransform);
  483. MDagPath path = root; path.push(o);
  484. MString command = MString("parent -add ") + ((!isTransform) ? "-shape " : "") + path.fullPathName() + " " + transform.fullPathName() + ";";
  485. MGlobal::executeCommand(command);
  486. }
  487. }
  488. ApplyTransformation(transform, t.transformation());
  489. }
  490. void CReferenceManager::ApplyTransformation(const MDagPath& transform, const MTransformationMatrix& rootTransformation)
  491. {
  492. // Order doesn't matter, as long as we apply all the differences
  493. MFnTransform t(transform.transform());
  494. MTransformationMatrix curMx = MFnTransform(transform.transform()).transformation();
  495. MTransformationMatrix newMx(rootTransformation.asMatrix() * curMx.asMatrix());
  496. t.set(newMx);
  497. /* // Do the commands TWICE.
  498. // Once right away so that we can export the data correctly.
  499. // Once deferred so that the reference node can register it.
  500. #define INEQ_SETATTR(newFloat, curFloat, attrName) \
  501. if (!IsEquivalent((float)newFloat, (float)curFloat)) { \
  502. MString command = MString("setAttr ") + transform.fullPathName() + attrName + " " + newFloat + ";"; \
  503. MGlobal::executeCommand(command); \
  504. command = MString("evalDeferred (\"") + command + "\");"; \
  505. MGlobal::executeCommand(command); \
  506. }
  507. MVector newT = newMx.translation(MSpace::kTransform);
  508. MVector curT = curMx.translation(MSpace::kTransform);
  509. INEQ_SETATTR(newT.x, curT.x, ".tx");
  510. INEQ_SETATTR(newT.y, curT.y, ".ty");
  511. INEQ_SETATTR(newT.z, curT.z, ".tz");
  512. MTransformationMatrix::RotationOrder dummy;
  513. double newR[3], curR[3];
  514. newMx.getRotation(newR, dummy);
  515. curMx.getRotation(curR, dummy);
  516. INEQ_SETATTR(RadToDeg((float)newR[0]), RadToDeg((float)curR[0]), ".rx");
  517. INEQ_SETATTR(RadToDeg((float)newR[1]), RadToDeg((float)curR[1]), ".ry");
  518. INEQ_SETATTR(RadToDeg((float)newR[2]), RadToDeg((float)curR[2]), ".rz");
  519. double newS[3], curS[3];
  520. newMx.getScale(newS, MSpace::kTransform);
  521. curMx.getScale(curS, MSpace::kTransform);
  522. INEQ_SETATTR(newS[0], curS[0], ".sx");
  523. INEQ_SETATTR(newS[1], curS[1], ".sy");
  524. INEQ_SETATTR(newS[2], curS[2], ".sz");
  525. double newSH[3], curSH[3];
  526. newMx.getShear(newSH, MSpace::kTransform);
  527. curMx.getShear(curSH, MSpace::kTransform);
  528. INEQ_SETATTR(newSH[0], curSH[0], ".shxy");
  529. INEQ_SETATTR(newSH[1], curSH[1], ".shxz");
  530. INEQ_SETATTR(newSH[2], curSH[2], ".shyz");
  531. #undef INEQ_SETATTR*/
  532. }
  533. int CReferenceManager::FindRootName(CReferenceFile* file, const MString& rootName)
  534. {
  535. uint rootNameCount = file->rootNames.length();
  536. for (uint i = 0; i < rootNameCount; ++i)
  537. {
  538. if (rootName == file->rootNames[i]) return (int) i;
  539. }
  540. return -1;
  541. }
  542. MString CReferenceManager::GetLastReferenceFilename(const MString& referenceResult)
  543. {
  544. #if MAYA_API_VERSION >= 650
  545. return referenceResult;
  546. #else
  547. MStringArray filenames;
  548. MGlobal::executeCommand("file -q -r;", filenames);
  549. if (CImportOptions::IsOpenMode())
  550. {
  551. return (filenames.length() > 0) ? filenames[filenames.length() - 1] : "";
  552. }
  553. else
  554. {
  555. return referenceResult;
  556. }
  557. #endif
  558. }
  559. MString CReferenceManager::GetReferenceFilename(const MDagPath& path)
  560. {
  561. MString command = MString("reference -q -f ") + path.fullPathName();
  562. MString filename;
  563. MGlobal::executeCommand(command, filename);
  564. return filename;
  565. }
  566. MString CReferenceManager::GetReferenceFilename(const MObject& dgNode)
  567. {
  568. MString command = MString("reference -q -f ") + MFnDependencyNode(dgNode).name();
  569. MString filename;
  570. MGlobal::executeCommand(command, filename);
  571. return filename;
  572. }
  573. FCDPlaceHolder* CReferenceManager::GetPlaceHolder(FCDocument* colladaDocument, const MString& filename)
  574. {
  575. const fchar* _filename = MConvert::ToFChar(filename);
  576. FCDPlaceHolder* ph = colladaDocument->GetExternalReferenceManager()->FindPlaceHolder(_filename);
  577. if (ph == NULL) ph = colladaDocument->GetExternalReferenceManager()->AddPlaceHolder(_filename);
  578. return ph;
  579. }