BOOL GetLangSaveFolderName( char *fileWithPath, char *filename ) { char szPath[256]; char *szFilter; szFilter = "Language Files (*.lang)\0*.lang\0\0"; PathFromFullPath( fileWithPath, szPath ); return GetSaveDialog( fileWithPath, filename, szPath, szFilter, ReturnString(IDS_LANG_SAVEAS), "lang", 1); }
CC_FILE_ERROR AsciiFilter::saveToFile(ccHObject* entity, QString filename, SaveParameters& parameters) { assert(entity && !filename.isEmpty()); AsciiSaveDlg* saveDialog = GetSaveDialog(parameters.parentWidget); assert(saveDialog); //if the dialog shouldn't be shown, we'll simply take the default values! if (parameters.alwaysDisplaySaveDialog && saveDialog->autoShow() && !saveDialog->exec()) { return CC_FERR_CANCELED_BY_USER; } if (!entity->isKindOf(CC_TYPES::POINT_CLOUD)) { if (entity->isA(CC_TYPES::HIERARCHY_OBJECT)) //multiple clouds? { QFileInfo fi(filename); QString extension = fi.suffix(); QString baseName = fi.completeBaseName(); QString path = fi.path(); unsigned count = entity->getChildrenNumber(); //we count the number of clouds first unsigned cloudCount = 0; { for (unsigned i=0; i<count; ++i) { ccHObject* child = entity->getChild(i); if (child->isKindOf(CC_TYPES::POINT_CLOUD)) ++cloudCount; } } //we can now create the corresponding file(s) if (cloudCount > 1) { unsigned counter = 0; //disable the save dialog so that it doesn't appear again! AsciiSaveDlg* saveDialog = GetSaveDialog(); assert(saveDialog); bool autoShow = saveDialog->autoShow(); saveDialog->setAutoShow(false); for (unsigned i=0; i<count; ++i) { ccHObject* child = entity->getChild(i); if (child->isKindOf(CC_TYPES::POINT_CLOUD)) { QString subFilename = path+QString("/"); subFilename += QString(baseName).replace("cloudname",child->getName(),Qt::CaseInsensitive); counter++; assert(counter <= cloudCount); subFilename += QString("_%1").arg(cloudCount-counter,6,10,QChar('0')); if (!extension.isEmpty()) subFilename += QString(".") + extension; CC_FILE_ERROR result = saveToFile(entity->getChild(i),subFilename,parameters); if (result != CC_FERR_NO_ERROR) { return result; } else { ccLog::Print(QString("[ASCII] Cloud '%1' has been saved in: %2").arg(child->getName()).arg(subFilename)); } } else { ccLog::Warning(QString("[ASCII] Entity '%1' can't be saved this way!").arg(child->getName())); } } //restore previous state saveDialog->setAutoShow(autoShow); return CC_FERR_NO_ERROR; } } else { return CC_FERR_BAD_ARGUMENT; } } QFile file(filename); if (!file.open(QFile::WriteOnly | QFile::Truncate)) return CC_FERR_WRITING; QTextStream stream(&file); ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(entity); unsigned numberOfPoints = cloud->size(); bool writeColors = cloud->hasColors(); bool writeNorms = cloud->hasNormals(); std::vector<ccScalarField*> theScalarFields; if (cloud->isKindOf(CC_TYPES::POINT_CLOUD)) { ccPointCloud* ccCloud = static_cast<ccPointCloud*>(cloud); for (unsigned i=0; i<ccCloud->getNumberOfScalarFields(); ++i) theScalarFields.push_back(static_cast<ccScalarField*>(ccCloud->getScalarField(i))); } bool writeSF = (theScalarFields.size() != 0); //progress dialog ccProgressDialog pdlg(true); CCLib::NormalizedProgress nprogress(&pdlg,numberOfPoints); pdlg.setMethodTitle(qPrintable(QString("Saving cloud [%1]").arg(cloud->getName()))); pdlg.setInfo(qPrintable(QString("Number of points: %1").arg(numberOfPoints))); pdlg.start(); //output precision const int s_coordPrecision = saveDialog->coordsPrecision(); const int s_sfPrecision = saveDialog->sfPrecision(); const int s_nPrecision = 2+sizeof(PointCoordinateType); //other parameters bool saveColumnsHeader = saveDialog->saveColumnsNamesHeader(); bool savePointCountHeader = saveDialog->savePointCountHeader(); bool swapColorAndSFs = saveDialog->swapColorAndSF(); QChar separator(saveDialog->getSeparator()); bool saveFloatColors = saveDialog->saveFloatColors(); if (saveColumnsHeader) { QString header("//"); header.append(AsciiHeaderColumns::X()); header.append(separator); header.append(AsciiHeaderColumns::Y()); header.append(separator); header.append(AsciiHeaderColumns::Z()); if (writeColors && !swapColorAndSFs) { header.append(separator); header.append(saveFloatColors ? AsciiHeaderColumns::Rf() : AsciiHeaderColumns::R()); header.append(separator); header.append(saveFloatColors ? AsciiHeaderColumns::Gf() : AsciiHeaderColumns::G()); header.append(separator); header.append(saveFloatColors ? AsciiHeaderColumns::Bf() : AsciiHeaderColumns::B()); } if (writeSF) { //add each associated SF name for (std::vector<ccScalarField*>::const_iterator it = theScalarFields.begin(); it != theScalarFields.end(); ++it) { QString sfName((*it)->getName()); sfName.replace(separator,'_'); header.append(separator); header.append(sfName); } } if (writeColors && swapColorAndSFs) { header.append(separator); header.append(saveFloatColors ? AsciiHeaderColumns::Rf() : AsciiHeaderColumns::R()); header.append(separator); header.append(saveFloatColors ? AsciiHeaderColumns::Gf() : AsciiHeaderColumns::G()); header.append(separator); header.append(saveFloatColors ? AsciiHeaderColumns::Bf() : AsciiHeaderColumns::B()); } if (writeNorms) { header.append(separator); header.append(AsciiHeaderColumns::Nx()); header.append(separator); header.append(AsciiHeaderColumns::Ny()); header.append(separator); header.append(AsciiHeaderColumns::Nz()); } stream << header << "\n"; } if (savePointCountHeader) { stream << QString::number(numberOfPoints) << "\n"; } CC_FILE_ERROR result = CC_FERR_NO_ERROR; for (unsigned i=0; i<numberOfPoints; ++i) { //line for the current point QString line; //write current point coordinates const CCVector3* P = cloud->getPoint(i); CCVector3d Pglobal = cloud->toGlobal3d<PointCoordinateType>(*P); line.append(QString::number(Pglobal.x,'f',s_coordPrecision)); line.append(separator); line.append(QString::number(Pglobal.y,'f',s_coordPrecision)); line.append(separator); line.append(QString::number(Pglobal.z,'f',s_coordPrecision)); QString colorLine; if (writeColors) { //add rgb color const ColorCompType* col = cloud->getPointColor(i); if (saveFloatColors) { colorLine.append(separator); colorLine.append(QString::number(static_cast<double>(col[0])/ccColor::MAX)); colorLine.append(separator); colorLine.append(QString::number(static_cast<double>(col[1])/ccColor::MAX)); colorLine.append(separator); colorLine.append(QString::number(static_cast<double>(col[2])/ccColor::MAX)); } else { colorLine.append(separator); colorLine.append(QString::number(col[0])); colorLine.append(separator); colorLine.append(QString::number(col[1])); colorLine.append(separator); colorLine.append(QString::number(col[2])); } if (!swapColorAndSFs) line.append(colorLine); } if (writeSF) { //add each associated SF values for (std::vector<ccScalarField*>::const_iterator it = theScalarFields.begin(); it != theScalarFields.end(); ++it) { line.append(separator); double sfVal = (*it)->getGlobalShift() + (*it)->getValue(i); line.append(QString::number(sfVal,'f',s_sfPrecision)); } } if (writeColors && swapColorAndSFs) line.append(colorLine); if (writeNorms) { //add normal vector const CCVector3& N = cloud->getPointNormal(i); line.append(separator); line.append(QString::number(N.x,'f',s_nPrecision)); line.append(separator); line.append(QString::number(N.y,'f',s_nPrecision)); line.append(separator); line.append(QString::number(N.z,'f',s_nPrecision)); } stream << line << "\n"; if (!nprogress.oneStep()) { result = CC_FERR_CANCELED_BY_USER; break; } } return result; }