CC中有两个地方使用了文件保存,一个是MainWindow,另一个是ccCommandLineParser。

MainWindow的保存按钮关联的槽是doActionSaveFile()方法,实现了点云和Mesh的保存。

 void MainWindow::doActionSaveFile()
{
size_t selNum = m_selectedEntities.size();
if (selNum == )
return; ccHObject clouds("clouds");
ccHObject meshes("meshes");
ccHObject images("images");
ccHObject polylines("polylines");
ccHObject other("other");
ccHObject otherSerializable("serializable");
ccHObject::Container entitiesToDispatch;
entitiesToDispatch.insert(entitiesToDispatch.begin(),m_selectedEntities.begin(),m_selectedEntities.end());
ccHObject entitiesToSave;
while (!entitiesToDispatch.empty())
{
ccHObject* child = entitiesToDispatch.back();
entitiesToDispatch.pop_back(); if (child->isA(CC_TYPES::HIERARCHY_OBJECT))
{
for (unsigned j=; j<child->getChildrenNumber(); ++j)
entitiesToDispatch.push_back(child->getChild(j));
}
else
{
//we put the entity in the container corresponding to its type
ccHObject* dest = ;
if (child->isA(CC_TYPES::POINT_CLOUD))
dest = &clouds;
else if (child->isKindOf(CC_TYPES::MESH))
dest = &meshes;
else if (child->isKindOf(CC_TYPES::IMAGE))
dest = &images;
else if (child->isKindOf(CC_TYPES::POLY_LINE))
dest = &polylines;
else if (child->isSerializable())
dest = &otherSerializable;
else
dest = &other; assert(dest); //we don't want double insertions if the user has clicked both the father and child
if (!dest->find(child->getUniqueID()))
{
dest->addChild(child,ccHObject::DP_NONE);
entitiesToSave.addChild(child,ccHObject::DP_NONE);
}
}
} bool hasCloud = (clouds.getChildrenNumber() != );
bool hasMesh = (meshes.getChildrenNumber() != );
bool hasImages = (images.getChildrenNumber() != );
bool hasPolylines = (polylines.getChildrenNumber() != );
bool hasSerializable = (otherSerializable.getChildrenNumber() != );
bool hasOther = (other.getChildrenNumber() != ); int stdSaveTypes = static_cast<int>(hasCloud)
+ static_cast<int>(hasMesh)
+ static_cast<int>(hasImages)
+ static_cast<int>(hasPolylines)
+ static_cast<int>(hasSerializable);
if (stdSaveTypes == )
{
ccConsole::Error("Can't save selected entity(ies) this way!");
return;
} //we set up the right file filters, depending on the selected
//entities type (cloud, mesh, etc.).
QStringList fileFilters;
{
const FileIOFilter::FilterContainer& filters = FileIOFilter::GetFilters();
for (size_t i=; i<filters.size(); ++i)
{
bool atLeastOneExclusive = false; //current I/O filter
const FileIOFilter::Shared filter = filters[i]; //does this filter can export one or several clouds?
bool canExportClouds = true;
if (hasCloud)
{
bool isExclusive = true;
bool multiple = false;
canExportClouds = ( filter->canSave(CC_TYPES::POINT_CLOUD,multiple,isExclusive)
&& (multiple || clouds.getChildrenNumber() == ) );
atLeastOneExclusive |= isExclusive;
} //does this filter can export one or several meshes?
bool canExportMeshes = true;
if (hasMesh)
{
bool isExclusive = true;
bool multiple = false;
canExportMeshes = ( filter->canSave(CC_TYPES::MESH,multiple,isExclusive)
&& (multiple || meshes.getChildrenNumber() == ) );
atLeastOneExclusive |= isExclusive;
} //does this filter can export one or several polylines?
bool canExportPolylines = true;
if (hasPolylines)
{
bool isExclusive = true;
bool multiple = false;
canExportPolylines = ( filter->canSave(CC_TYPES::POLY_LINE,multiple,isExclusive)
&& (multiple || polylines.getChildrenNumber() == ) );
atLeastOneExclusive |= isExclusive;
} //does this filter can export one or several images?
bool canExportImages = true;
if (hasImages)
{
bool isExclusive = true;
bool multiple = false;
canExportImages = ( filter->canSave(CC_TYPES::IMAGE,multiple,isExclusive)
&& (multiple || images.getChildrenNumber() == ) );
atLeastOneExclusive |= isExclusive;
} //does this filter can export one or several other serializable entities?
bool canExportSerializables = true;
if (hasSerializable)
{
//check if all entities have the same type
{
CC_CLASS_ENUM firstClassID = otherSerializable.getChild()->getUniqueID();
for (unsigned j=; j<otherSerializable.getChildrenNumber(); ++j)
{
if (otherSerializable.getChild(j)->getUniqueID() != firstClassID)
{
//we add a virtual second 'stdSaveType' so as to properly handle exlusivity
++stdSaveTypes;
break;
}
}
} for (unsigned j=; j<otherSerializable.getChildrenNumber(); ++j)
{
ccHObject* child = otherSerializable.getChild(j);
bool isExclusive = true;
bool multiple = false;
canExportSerializables &= ( filter->canSave(child->getUniqueID(),multiple,isExclusive)
&& (multiple || otherSerializable.getChildrenNumber() == ) );
atLeastOneExclusive |= isExclusive;
}
} bool useThisFilter = canExportClouds
&& canExportMeshes
&& canExportImages
&& canExportPolylines
&& canExportSerializables
&& (!atLeastOneExclusive || stdSaveTypes == ); if (useThisFilter)
{
QStringList ff = filter->getFileFilters(false);
for (int j=; j<ff.size(); ++j)
fileFilters.append(ff[j]);
}
}
} //persistent settings
QSettings settings;
settings.beginGroup(ccPS::SaveFile()); //default filter
QString selectedFilter = fileFilters.first();
if (hasCloud)
selectedFilter = settings.value(ccPS::SelectedOutputFilterCloud(),selectedFilter).toString();
else if (hasMesh)
selectedFilter = settings.value(ccPS::SelectedOutputFilterMesh(), selectedFilter).toString();
else if (hasImages)
selectedFilter = settings.value(ccPS::SelectedOutputFilterImage(), selectedFilter).toString();
else if (hasPolylines)
selectedFilter = settings.value(ccPS::SelectedOutputFilterPoly(), selectedFilter).toString(); //default output path (+ filename)
QString currentPath = settings.value(ccPS::CurrentPath(),QApplication::applicationDirPath()).toString();
QString fullPathName = currentPath;
if (selNum == )
{
//hierarchy objects have generally as name: 'filename.ext (fullpath)'
//so we must only take the first part! (otherwise this type of name
//with a path inside perturbs the QFileDialog a lot ;))
QString defaultFileName(m_selectedEntities.front()->getName());
if (m_selectedEntities.front()->isA(CC_TYPES::HIERARCHY_OBJECT))
{
QStringList parts = defaultFileName.split(' ',QString::SkipEmptyParts);
if (parts.size() > )
defaultFileName = parts[];
} //we remove the extension
defaultFileName = QFileInfo(defaultFileName).baseName(); if (!IsValidFileName(defaultFileName))
{
ccLog::Warning("[I/O] First entity's name would make an invalid filename! Can't use it...");
defaultFileName = "project";
} fullPathName += QString("/") + defaultFileName;
} //ask the user for the output filename
QString selectedFilename = QFileDialog::getSaveFileName(this,
"Save file",
fullPathName,
fileFilters.join(s_fileFilterSeparator),
&selectedFilter); if (selectedFilename.isEmpty())
{
//process cancelled by the user
return;
} //ignored items
if (hasOther)
{
ccConsole::Warning("[I/O] The following selected entites won't be saved:");
for (unsigned i=; i<other.getChildrenNumber(); ++i)
ccConsole::Warning(QString("\t- %1s").arg(other.getChild(i)->getName()));
} CC_FILE_ERROR result = CC_FERR_NO_ERROR;
FileIOFilter::SaveParameters parameters;
{
parameters.alwaysDisplaySaveDialog = true;
parameters.parentWidget = this;
} //specific case: BIN format
if (selectedFilter == BinFilter::GetFileFilter())
{
if (selNum == )
{
result = FileIOFilter::SaveToFile(m_selectedEntities.front(),selectedFilename,parameters,selectedFilter);
}
else
{
//we'll regroup all selected entities in a temporary group
ccHObject tempContainer;
ConvertToGroup(m_selectedEntities,tempContainer,ccHObject::DP_NONE);
if (tempContainer.getChildrenNumber())
{
result = FileIOFilter::SaveToFile(&tempContainer,selectedFilename,parameters,selectedFilter);
}
else
{
ccLog::Warning("[I/O] None of the selected entities can be saved this way...");
result = CC_FERR_NO_SAVE;
}
}
}
else if (entitiesToSave.getChildrenNumber() != )
{
//ignored items
/*if (hasSerializable)
{
if (!hasOther)
ccConsole::Warning("[I/O] The following selected entites won't be saved:"); //display this warning only if not already done
for (unsigned i=0; i<otherSerializable.getChildrenNumber(); ++i)
ccConsole::Warning(QString("\t- %1").arg(otherSerializable.getChild(i)->getName()));
}
//*/ result = FileIOFilter::SaveToFile( entitiesToSave.getChildrenNumber() > ? &entitiesToSave : entitiesToSave.getChild(),
selectedFilename,
parameters,
selectedFilter);
} //update default filters
if (hasCloud)
settings.setValue(ccPS::SelectedOutputFilterCloud(),selectedFilter);
if (hasMesh)
settings.setValue(ccPS::SelectedOutputFilterMesh(), selectedFilter);
if (hasImages)
settings.setValue(ccPS::SelectedOutputFilterImage(),selectedFilter);
if (hasPolylines)
settings.setValue(ccPS::SelectedOutputFilterPoly(), selectedFilter); //we update current file path
currentPath = QFileInfo(selectedFilename).absolutePath();
settings.setValue(ccPS::CurrentPath(),currentPath);
settings.endGroup();
}

void MainWindow::doActionSaveFile()

再看看ccCommandLineParser的Parse方法:

 int ccCommandLineParser::Parse(int nargs, char** args)
{
if (!args || nargs < )
{
assert(false);
return EXIT_SUCCESS;
} //reset default behavior(s)
s_loadParameters.autoComputeNormals = false;
s_MeshExportFormat = s_CloudExportFormat = BinFilter::GetFileFilter();
s_MeshExportExt = s_CloudExportExt = BinFilter::GetDefaultExtension();
s_precision = ;
s_addTimestamp = true;
s_silentMode = false;
s_autoSaveMode = true; //load arguments
QStringList arguments;
{
for (int i=; i<nargs; ++i) //'i=1' because first argument is always program executable file!
arguments.push_back(QString(args[i]));
}
assert(!arguments.empty()); //specific command: silent mode (will prevent the console dialog from appearing!
if (IsCommand(arguments.front(),COMMAND_SILENT_MODE))
{
arguments.pop_front();
s_silentMode = true;
} QDialog consoleDlg;
if (!s_silentMode)
{
//show console
Ui_commandLineDlg commandLineDlg;
commandLineDlg.setupUi(&consoleDlg);
consoleDlg.show();
ccConsole::Init(commandLineDlg.consoleWidget, &consoleDlg);
s_loadParameters.parentWidget = &consoleDlg;
} //parse input
int result = ccCommandLineParser().parse(arguments,&consoleDlg); if (!s_silentMode)
{
if (result == EXIT_SUCCESS)
QMessageBox::information(&consoleDlg,"Processed finished","Job done");
else
QMessageBox::warning(&consoleDlg,"Processed finished","An error occurred! Check console");
} ccConsole::ReleaseInstance(); return result;
}

int ccCommandLineParser::Parse(int nargs, char** args)

该方法被main函数调用。

 //主程序入口,十分重要
int main(int argc, char **argv)
{
//QT initialiation
qccApplication app(argc, argv); //Force 'english' local so as to get a consistent behavior everywhere
QLocale::setDefault(QLocale::English); #ifdef Q_OS_LINUX
// we reset the numeric locale. As suggested in documetation
// see http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings
// Basically - from doc: - "On Unix/Linux Qt is configured to use the system locale settings by default.
// This can cause a conflict when using POSIX functions, for instance,
// when converting between data types such as floats and strings"
setlocale(LC_NUMERIC,"C");
#endif #ifdef USE_VLD
VLDEnable();
#endif //splash screen
QSplashScreen* splash = ;
QTime splashStartTime; //Command line mode?
bool commandLine = (argc > && argv[][] == '-'); //specific case: translation file selection
int lastArgumentIndex = ;
QTranslator translator;
if (commandLine && QString(argv[]).toUpper() == "-LANG")
{
QString langFilename = QString(argv[]); //Load translation file
if (translator.load(langFilename, QCoreApplication::applicationDirPath()))
{
qApp->installTranslator(&translator);
}
else
{
QMessageBox::warning(, QObject::tr("Translation"), QObject::tr("Failed to load language file '%1'").arg(langFilename));
}
commandLine = false;
lastArgumentIndex = ;
} //command line mode
if (!commandLine)
{
//OpenGL?
if (!QGLFormat::hasOpenGL())
{
QMessageBox::critical(, "Error", "This application needs OpenGL to run!");
return EXIT_FAILURE;
} //splash screen
splashStartTime.start();
QPixmap pixmap(QString::fromUtf8(":/CC/images/imLogoV2Qt.png"));
splash = new QSplashScreen(pixmap,Qt::WindowStaysOnTopHint);
splash->show();
QApplication::processEvents();
} //global structures initialization
ccTimer::Init();
FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!)
ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization
ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization int result = ; if (commandLine)
{
//command line processing (no GUI)
result = ccCommandLineParser::Parse(argc,argv);
}
else
{
//main window init.
MainWindow* mainWindow = MainWindow::TheInstance();
if (!mainWindow)
{
QMessageBox::critical(, "Error", "Failed to initialize the main application window?!");
return EXIT_FAILURE;
}
mainWindow->show();
QApplication::processEvents(); if (argc > lastArgumentIndex)
{
if (splash)
splash->close(); //any additional argument is assumed to be a filename --> we try to load it/them
QStringList filenames;
for (int i = lastArgumentIndex; i<argc; ++i)
filenames << QString(argv[i]); mainWindow->addToDB(filenames);
} if (splash)
{
//we want the splash screen to be visible a minimum amount of time (1000 ms.)
while (splashStartTime.elapsed() < )
{
splash->raise();
QApplication::processEvents(); //to let the system breath!
} splash->close();
QApplication::processEvents(); delete splash;
splash = ;
} //let's rock!
try
{
result = app.exec();
}
catch(...)
{
QMessageBox::warning(, "CC crashed!","Hum, it seems that CC has crashed... Sorry about that :)");
}
} //release global structures
MainWindow::DestroyInstance();
FileIOFilter::UnregisterAll(); #ifdef CC_TRACK_ALIVE_SHARED_OBJECTS
//for debug purposes
unsigned alive = CCShareable::GetAliveCount();
if (alive > )
{
printf("Error: some shared objects (%u) have not been released on program end!",alive);
system("PAUSE");
}
#endif return result;
}

int main(int argc, char **argv)

两处最终都落实到FileIOFilter::SaveToFile()方法的调用。

 //保存文件
CC_FILE_ERROR FileIOFilter::SaveToFile( ccHObject* entities,
const QString& filename,
SaveParameters& parameters,
QString fileFilter)
{
if (fileFilter.isEmpty())
return CC_FERR_BAD_ARGUMENT;
//获取对应的文件格式,存储器
Shared filter = GetFilter(fileFilter,false);
if (!filter)
{
ccLog::Error(QString("[Load] Internal error: no filter corresponds to filter '%1'").arg(fileFilter));
return CC_FERR_UNKNOWN_FILE;
} return SaveToFile(entities, filename, parameters, filter);
} CC_FILE_ERROR FileIOFilter::SaveToFile( ccHObject* entities,
const QString& filename,
SaveParameters& parameters,
Shared filter)
{
if (!entities || filename.isEmpty() || !filter)
return CC_FERR_BAD_ARGUMENT; //if the file name has no extension, we had a default one!
QString completeFileName(filename);
if (QFileInfo(filename).suffix().isEmpty())
completeFileName += QString(".%1").arg(filter->getDefaultExtension()); CC_FILE_ERROR result = CC_FERR_NO_ERROR;
try
{
result = filter->saveToFile(entities, completeFileName, parameters);
}
catch(...)
{
ccLog::Warning(QString("[I/O] CC has caught an unhandled exception while saving file '%1'").arg(filename));
result = CC_FERR_CONSOLE_ERROR;
} if (result == CC_FERR_NO_ERROR)
{
ccLog::Print(QString("[I/O] File '%1' saved successfully").arg(filename));
}
else
{
DisplayErrorMessage(result,"saving",filename);
} return result;
}

FileIOFilter::SaveToFile

获取需要的文件存储器。

 //获取存取器
FileIOFilter::Shared FileIOFilter::GetFilter(QString fileFilter, bool onImport)
{
if (!fileFilter.isEmpty())
{
for (FilterContainer::const_iterator it=s_ioFilters.begin(); it!=s_ioFilters.end(); ++it)
{
QStringList otherFilters = (*it)->getFileFilters(onImport);
if (otherFilters.contains(fileFilter))
return *it;
}
} return Shared();
}

FileIOFilter::Shared FileIOFilter::GetFilter

这里重点研究一下obj文件的保存。

[CC]Mesh文件保存的更多相关文章

  1. java 文件保存到本地

    private void savePic(InputStream inputStream, String fileName) { OutputStream os = null; try { Strin ...

  2. C# 文件选择对话框,Unity3d文件保存对话框

    using OpenWinForm = System.Windows.Forms; 在unity3d中,使用FileDialog应该把System.Windows.Forms.dll拷贝到unity工 ...

  3. 怎么直接让火狐输入json数据,而不是弹出文件保存对话框?

    一.问题再现: 我需要浏览器输出的是json数据,但是浏览器弹出的是一个文件保存的对话框,这样的体验有点差.所以想怎么让浏览器直接输出到浏览器的页面上面,并且格式的输出,还可以编辑. 测试数据: ht ...

  4. php 下载保存文件保存到本地的两种方法

    第一种: 1 <? ?> 或 <?php //下载文件保存到本地//www.jbxue.comfunction downfile($fileurl){ob_start(); $fil ...

  5. 使用CURL下载远程文件保存到服务器

    比如微信公众平台开发,下载用户的头像到服务器上: /** * 使用CURL获取远程文件保存到服务器 *@param $image=$oJSON->headimgurl; 获取到的微信返回的头像U ...

  6. (qsf文件 、 tcl文件 和 csv(txt)文件的区别) FPGA管脚分配文件保存、导入导出方法

    FPGA管脚分配文件保存方法 使用别人的工程时,有时找不到他的管脚文件,但可以把他已经绑定好的管脚保存下来,输出到文件里. 方法一: 查看引脚绑定情况,quartus -> assignment ...

  7. 【转】warning C4819,该文件保存为 Unicode 格式以防止数据丢失,处理方法

    以下的解决方案只是把错误给屏蔽掉而已,并不能真正解决这个警告.仅供参考! 当项目引用到外部源代码后,经常出现4819错误,警告信息如下: warning C4819: 该文件包含不能在当前代码页(93 ...

  8. php动态网页实现页面静态化 通过在初次被访问时生成html文件保存起来,下次该PHP程序被访问时就直接找到以前被访问过的html页面

    一.什么是静态页面?什么是动态页面 静态页面是网页的代码都在页面中,不需要执行asp,php,jsp,.net等程序生成客户端网页代码的网页.不能   静态页面 动态页面 区别:           ...

  9. 重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口

    原文:重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口 [源码下载] 重新想象 Windows 8 Store Apps (26) ...

随机推荐

  1. Markdown 引用

    Markdown 使用 > 来标记区块引用,语法及效果如下: > 这是第一级引用 > > > 这是第二级引用 > > 现在回到第一级引用 > > ...

  2. day_6.8 py 网络编程

    2018-6-8 18:20:30 OSI模型:就是七层物理层 ICMP 我ping你的时候要用,不仅要知道ip地址和网卡号mac地址 ARP  在我和你通讯前不知道的mac地址需要广播一下,当我说的 ...

  3. 拓展 NLog 优雅的输送日志到 Logstash

    在上上篇博客通过对aspnetcore启动前配置做了一些更改,以及对nlog进行了自定义字段,可以把请求记录输送到mysql,正式情况可能不会这么部署.因为近期也在学习elk,所以就打算做一个实例,结 ...

  4. 跳石头|河中跳房子|NOIP2015提高组T4|二分法

    喵 提交地址:http://codevs.cn/problem/4768/ 题目: 题意:自己看 思路: 1.读入各个石头数据 2.直接二分答案: 枚举一个石头i和一个石头j,要求i和j之间的距离为m ...

  5. SQL Server 2016 共享功能目录 不可修改

    x 个人电脑上没有安装MSSQL,以前需要链接数据库写SQL,都是在{VS ->>视图->>SQL Server对象资源管理器}直接链接数据库进行访问操作的... 但是确实有些 ...

  6. Python:导入自定义模块

    在C语言里为了工程文件的主程序main代码简洁的效果,我们经常用include“XXX”的来导入其.h文件 在Python里Import自己的自定义模块需要注意几个坑 以main主函数和需要导入的ha ...

  7. iOS 抽取app中的图片图标资源

    iTunes 12.6之前的版本,我们手机连上MAC之后,可以在iTunes里看到应用选项,但是12.8之后的版本就不行了.无法通过iTunes 获取ipa文件进而获取APP图片资源. 不过还是有其他 ...

  8. .NET工程师必须掌握的知识点

    Microsoft SQL Server 数据库 一.创建和维护数据库 1.数据库 SQL Server 数据库的组成部分?(参见联机丛书) 如何保证数据库的完整性.安全性.并发性? 数据库设计创建步 ...

  9. [ovs][dpdk] ovs-dpdk, dpdk port 大量丢包

    gdb了ovs的代码,发现是 dpdk的imiss计数在不断的丢包. 看了ovs-openvswitchd的日志,重启时发现如下行: --21T11::.427Z||timeval|WARN|Unre ...

  10. ios APP改名推送名字还是旧的

    重启手机就行了 https://community.jiguang.cn/t/ios-app/14759