[CC]Mesh文件保存
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文件保存的更多相关文章
- java 文件保存到本地
private void savePic(InputStream inputStream, String fileName) { OutputStream os = null; try { Strin ...
- C# 文件选择对话框,Unity3d文件保存对话框
using OpenWinForm = System.Windows.Forms; 在unity3d中,使用FileDialog应该把System.Windows.Forms.dll拷贝到unity工 ...
- 怎么直接让火狐输入json数据,而不是弹出文件保存对话框?
一.问题再现: 我需要浏览器输出的是json数据,但是浏览器弹出的是一个文件保存的对话框,这样的体验有点差.所以想怎么让浏览器直接输出到浏览器的页面上面,并且格式的输出,还可以编辑. 测试数据: ht ...
- php 下载保存文件保存到本地的两种方法
第一种: 1 <? ?> 或 <?php //下载文件保存到本地//www.jbxue.comfunction downfile($fileurl){ob_start(); $fil ...
- 使用CURL下载远程文件保存到服务器
比如微信公众平台开发,下载用户的头像到服务器上: /** * 使用CURL获取远程文件保存到服务器 *@param $image=$oJSON->headimgurl; 获取到的微信返回的头像U ...
- (qsf文件 、 tcl文件 和 csv(txt)文件的区别) FPGA管脚分配文件保存、导入导出方法
FPGA管脚分配文件保存方法 使用别人的工程时,有时找不到他的管脚文件,但可以把他已经绑定好的管脚保存下来,输出到文件里. 方法一: 查看引脚绑定情况,quartus -> assignment ...
- 【转】warning C4819,该文件保存为 Unicode 格式以防止数据丢失,处理方法
以下的解决方案只是把错误给屏蔽掉而已,并不能真正解决这个警告.仅供参考! 当项目引用到外部源代码后,经常出现4819错误,警告信息如下: warning C4819: 该文件包含不能在当前代码页(93 ...
- php动态网页实现页面静态化 通过在初次被访问时生成html文件保存起来,下次该PHP程序被访问时就直接找到以前被访问过的html页面
一.什么是静态页面?什么是动态页面 静态页面是网页的代码都在页面中,不需要执行asp,php,jsp,.net等程序生成客户端网页代码的网页.不能 静态页面 动态页面 区别: ...
- 重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口
原文:重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口 [源码下载] 重新想象 Windows 8 Store Apps (26) ...
随机推荐
- Android开发训练之第五章第七节——Transmitting Network Data Using Volley
Transmitting Network Data Using Volley GET STARTED DEPENDENCIES AND PREREQUISITES Android 1.6 (API L ...
- iOS - 开发中加载本地word/pdf文档说明
最近项目中要加载一个本地的word/pdf等文件比如<用户隐私政策><用户注册说明>,有两种方法加载 > 用QLPreviewController控制器实现 步骤 : & ...
- mui---子页面主动调用父页面的方法
我们在做APP的时候,很多时候会有这样的功能需求,例如:登录,充值,如果登录成功,或充值成功后,需要更改当前页面以及父页面的状态信息,就会用到在子页面调用父页面的方法来实现:在子页面刷新父页面的功能. ...
- day_6.7 py tcp
2018-6-7 09:20:34 #!/usr/bin/env python #!--*--coding:utf-8 --*-- #!@Time :2018/6/7 9:54 #!@Author T ...
- jquery <img> 图片懒加载 和 标签如果没有加载出图片或没有图片,就显示默认的图片
参考链接:http://www.jq22.com/jquery-info390 或压缩包下载地址:链接:http://pan.baidu.com/s/1hsj8ZWw 密码:4a7s 下面是没有 ...
- VBS数组导入Excel
<script language="vbscript"> dim arr(9999,4) for i=0 to 9999 for j = 0 to 4 arr(i,j) ...
- Maven内存修改
为了解决maven内存经常溢出的问题,建议到安装的Maven目录下查找bin目录下的mvn.bat文件,用任意一款编辑器软件打开该文件,然后添加如下代码: set MAVEN_OPTS=-Xmx512 ...
- SSH框架下的表单重复提交
前几天做了一个功能,是在某个操作后,刷新父页面的,刷新时弹出了下面图的框: 网上查了之后发现这个框是表单重复提交时出现的.分析后发现,这个页面的上一个动作是form submit(在ssh框架下),这 ...
- 洛谷P1403 约数研究【思维】
题目:https://www.luogu.org/problemnew/show/P1403 题意: 定义$f(n)$为n的因子个数.给定一个数n,求$f(1)$到$f(n)$之和. 思路: 最直接的 ...
- 第一次java程序测试感受
第一次JAVA程序设计测试,检验了一个暑假的成果.显而易见,我做的并不是很好,程序最起码的输入输出以及方法的定义还是没有问题的,但是考到了文件输入输出便看出来了.对于文件的输入输出,虽然我预习到那里, ...