Exemplo n.º 1
1
CC_FILE_ERROR FBXFilter::saveToFile(ccHObject* entity, QString filename, SaveParameters& parameters)
{
	if (!entity)
		return CC_FERR_BAD_ARGUMENT;
	
	std::vector<ccGenericMesh*> meshes;
	if (entity->isKindOf(CC_TYPES::MESH))
	{
		meshes.push_back(static_cast<ccGenericMesh*>(entity));
	}
	else if (entity->isA(CC_TYPES::HIERARCHY_OBJECT))
	{
		for (unsigned i=0; i<entity->getChildrenNumber(); ++i)
		{
			ccHObject* child = entity->getChild(i);
			if (child->isKindOf(CC_TYPES::MESH))
				meshes.push_back(static_cast<ccGenericMesh*>(child));
		}
	}

	if (meshes.empty())
	{
		return CC_FERR_NO_SAVE;
	}

	//The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK
	FbxManager* lSdkManager = FbxManager::Create();
	if( !lSdkManager )
	{
		ccLog::Warning("[FBX] Error: Unable to create FBX Manager!");
		return CC_FERR_CONSOLE_ERROR;
	}
	else
	{
		ccLog::Print("[FBX] Autodesk FBX SDK version %s", lSdkManager->GetVersion());
	}

	try
	{
		//Create an IOSettings object. This object holds all import/export settings.
		FbxIOSettings* ios = FbxIOSettings::Create(lSdkManager, IOSROOT);
		lSdkManager->SetIOSettings(ios);

		//Load plugins from the executable directory (optional)
		//FbxString lPath = FbxGetApplicationDirectory();
		//lSdkManager->LoadPluginsDirectory(lPath.Buffer());

		//Create an FBX scene. This object holds most objects imported/exported from/to files.
		FbxScene* lScene = FbxScene::Create(lSdkManager, "My Scene");
		if( !lScene )
		{
			ccLog::Warning("[FBX] Error: Unable to create FBX scene!");
			return CC_FERR_CONSOLE_ERROR;
		}

		// create scene info
		{
			FbxDocumentInfo* sceneInfo = FbxDocumentInfo::Create(lSdkManager,"SceneInfo");
			sceneInfo->mTitle = qPrintable(QString("Mesh: ") + (meshes.size() == 1 ? meshes[0]->getName() : QString("Multiple meshes")));
			sceneInfo->mAuthor = "CloudCompare";
			sceneInfo->mRevision = "rev. 1.0";
			sceneInfo->mKeywords = "cloudcompare mesh";

			// we need to add the sceneInfo before calling AddThumbNailToScene because
			// that function is asking the scene for the sceneInfo.
			lScene->SetSceneInfo(sceneInfo);
		}

		//create thumbnail
		//{
		//	FbxThumbnail* lThumbnail = FbxThumbnail::Create(lScene,"");

		//	lThumbnail->SetDataFormat(FbxThumbnail::eRGB_24);
		//	lThumbnail->SetSize(FbxThumbnail::e64x64);
		//	lThumbnail->SetThumbnailImage(cSceneThumbnail);

		//	if (lScene->GetSceneInfo())
		//	{
		//		lScene->GetSceneInfo()->SetSceneThumbnail(lThumbnail);
		//	}
		//}

		// Build the node tree.
		FbxNode* lRootNode = lScene->GetRootNode();
		{
			for (size_t i=0; i<meshes.size(); ++i)
			{
				FbxNode* meshNode = ToFbxMesh(meshes[i],lScene,filename,i);
				if (meshNode)
					lRootNode->AddChild(meshNode);
				else
					ccLog::Warning(QString("[FBX] Failed to convert mesh '%1' to FBX mesh/node!").arg(meshes[i]->getName()));
			}
		}

		int fileFormat = -1;

		//Display a combox box to let the user choose the export file format
		{
			FbxManager* pSdkManager = FbxManager::GetDefaultManager();
			int lFormatCount = pSdkManager ? pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount() : 0;

			if (lFormatCount > 0)
			{
				if (s_defaultOutputFormat.isEmpty())
				{
					try
					{
						QMessageBox msgBox(QMessageBox::Question,"FBX format","Choose output format:");
						QMap<QAbstractButton*,int> buttons;
						for (int lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
						{
							if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
							{
								FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
								QPushButton *button = msgBox.addButton(lDesc.Buffer(), QMessageBox::AcceptRole);
								buttons[button] = lFormatIndex;
							}
						}
						msgBox.exec();
						//get the right format
						fileFormat = buttons[msgBox.clickedButton()];
					}
					catch(...)
					{
					}
				}
				else
				{
					//try to find the default output format as set by the user
					for (int lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
					{
						if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
						{
							FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
							QString sanitizedDesc = SanitizeFBXFormatString(lDesc.Buffer());
							if (s_defaultOutputFormat == sanitizedDesc)
							{
								ccLog::Print(QString("[FBX] Default output file format: %1").arg(sanitizedDesc));
								fileFormat = lFormatIndex;
								break;
							}
						}
					}

					//if we failed to find the specified file format, warn the user and display the list of supported formats
					if (fileFormat < 0)
					{
						ccLog::Warning(QString("[FBX] File format '%1' not supported").arg(s_defaultOutputFormat));
						ccLog::Print("[FBX] Supported output formats:");
						for (int lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
						{
							if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
							{
								FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
								ccLog::Print(QString("\t- %1").arg(SanitizeFBXFormatString(lDesc.Buffer())));
							}
						}
					}

				}
			}
		}

		// Save the scene.
		bool lResult = SaveScene(lSdkManager, lScene, qPrintable(filename),fileFormat);

		// Destroy all objects created by the FBX SDK.
		if( lSdkManager )
			lSdkManager->Destroy();

		return lResult ? CC_FERR_NO_ERROR : CC_FERR_CONSOLE_ERROR;
	}
	catch(...)
	{
		ccLog::Warning("[FBX] FBX SDK has thrown an unknown exception!");
		return CC_FERR_THIRD_PARTY_LIB_EXCEPTION;
	}
}