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

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

  1 void MainWindow::doActionSaveFile()
  2 {
  3     size_t selNum = m_selectedEntities.size();
  4     if (selNum == 0)
  5         return;
  6 
  7     ccHObject clouds("clouds");
  8     ccHObject meshes("meshes");
  9     ccHObject images("images");
 10     ccHObject polylines("polylines");
 11     ccHObject other("other");
 12     ccHObject otherSerializable("serializable");
 13     ccHObject::Container entitiesToDispatch;
 14     entitiesToDispatch.insert(entitiesToDispatch.begin(),m_selectedEntities.begin(),m_selectedEntities.end());
 15     ccHObject entitiesToSave;
 16     while (!entitiesToDispatch.empty())
 17     {
 18         ccHObject* child = entitiesToDispatch.back();
 19         entitiesToDispatch.pop_back();
 20 
 21         if (child->isA(CC_TYPES::HIERARCHY_OBJECT))
 22         {
 23             for (unsigned j=0; j<child->getChildrenNumber(); ++j)
 24                 entitiesToDispatch.push_back(child->getChild(j));
 25         }
 26         else
 27         {
 28             //we put the entity in the container corresponding to its type
 29             ccHObject* dest = 0;
 30             if (child->isA(CC_TYPES::POINT_CLOUD))
 31                 dest = &clouds;
 32             else if (child->isKindOf(CC_TYPES::MESH))
 33                 dest = &meshes;
 34             else if (child->isKindOf(CC_TYPES::IMAGE))
 35                 dest = &images;
 36             else if (child->isKindOf(CC_TYPES::POLY_LINE))
 37                 dest = &polylines;
 38             else if (child->isSerializable())
 39                 dest = &otherSerializable;
 40             else
 41                 dest = &other;
 42 
 43             assert(dest);
 44 
 45             //we don't want double insertions if the user has clicked both the father and child
 46             if (!dest->find(child->getUniqueID()))
 47             {
 48                 dest->addChild(child,ccHObject::DP_NONE);
 49                 entitiesToSave.addChild(child,ccHObject::DP_NONE);
 50             }
 51         }
 52     }
 53 
 54     bool hasCloud = (clouds.getChildrenNumber() != 0);
 55     bool hasMesh = (meshes.getChildrenNumber() != 0);
 56     bool hasImages = (images.getChildrenNumber() != 0);
 57     bool hasPolylines = (polylines.getChildrenNumber() != 0);
 58     bool hasSerializable = (otherSerializable.getChildrenNumber() != 0);
 59     bool hasOther = (other.getChildrenNumber() != 0);
 60 
 61     int stdSaveTypes =        static_cast<int>(hasCloud)
 62                         +    static_cast<int>(hasMesh)
 63                         +    static_cast<int>(hasImages)
 64                         +    static_cast<int>(hasPolylines)
 65                         +    static_cast<int>(hasSerializable);
 66     if (stdSaveTypes == 0)
 67     {
 68         ccConsole::Error("Can't save selected entity(ies) this way!");
 69         return;
 70     }
 71 
 72     //we set up the right file filters, depending on the selected
 73     //entities type (cloud, mesh, etc.).
 74     QStringList fileFilters;
 75     {
 76         const FileIOFilter::FilterContainer& filters = FileIOFilter::GetFilters();
 77         for (size_t i=0; i<filters.size(); ++i)
 78         {
 79             bool atLeastOneExclusive = false;
 80 
 81             //current I/O filter
 82             const FileIOFilter::Shared filter = filters[i];
 83 
 84             //does this filter can export one or several clouds?
 85             bool canExportClouds = true;
 86             if (hasCloud)
 87             {
 88                 bool isExclusive = true;
 89                 bool multiple = false;
 90                 canExportClouds = (        filter->canSave(CC_TYPES::POINT_CLOUD,multiple,isExclusive)
 91                                     &&    (multiple || clouds.getChildrenNumber() == 1) );
 92                 atLeastOneExclusive |= isExclusive;
 93             }
 94 
 95             //does this filter can export one or several meshes?
 96             bool canExportMeshes = true;
 97             if (hasMesh)
 98             {
 99                 bool isExclusive = true;
100                 bool multiple = false;
101                 canExportMeshes = (        filter->canSave(CC_TYPES::MESH,multiple,isExclusive)
102                                     &&    (multiple || meshes.getChildrenNumber() == 1) );
103                 atLeastOneExclusive |= isExclusive;
104             }
105 
106             //does this filter can export one or several polylines?
107             bool canExportPolylines = true;
108             if (hasPolylines)
109             {
110                 bool isExclusive = true;
111                 bool multiple = false;
112                 canExportPolylines = (    filter->canSave(CC_TYPES::POLY_LINE,multiple,isExclusive)
113                                     &&    (multiple || polylines.getChildrenNumber() == 1) );
114                 atLeastOneExclusive |= isExclusive;
115             }
116 
117             //does this filter can export one or several images?
118             bool canExportImages = true;
119             if (hasImages)
120             {
121                 bool isExclusive = true;
122                 bool multiple = false;
123                 canExportImages = (        filter->canSave(CC_TYPES::IMAGE,multiple,isExclusive)
124                                     &&    (multiple || images.getChildrenNumber() == 1) );
125                 atLeastOneExclusive |= isExclusive;
126             }
127 
128             //does this filter can export one or several other serializable entities?
129             bool canExportSerializables = true;
130             if (hasSerializable)
131             {
132                 //check if all entities have the same type
133                 {
134                     CC_CLASS_ENUM firstClassID = otherSerializable.getChild(0)->getUniqueID();
135                     for (unsigned j=1; j<otherSerializable.getChildrenNumber(); ++j)
136                     {
137                         if (otherSerializable.getChild(j)->getUniqueID() != firstClassID)
138                         {
139                             //we add a virtual second 'stdSaveType' so as to properly handle exlusivity
140                             ++stdSaveTypes;
141                             break;
142                         }
143                     }
144                 }
145 
146                 for (unsigned j=0; j<otherSerializable.getChildrenNumber(); ++j)
147                 {
148                     ccHObject* child = otherSerializable.getChild(j);
149                     bool isExclusive = true;
150                     bool multiple = false;
151                     canExportSerializables &= (        filter->canSave(child->getUniqueID(),multiple,isExclusive)
152                                                 &&    (multiple || otherSerializable.getChildrenNumber() == 1) );
153                     atLeastOneExclusive |= isExclusive;
154                 }
155             }
156 
157             bool useThisFilter =    canExportClouds
158                                 &&    canExportMeshes
159                                 &&    canExportImages
160                                 &&    canExportPolylines
161                                 &&    canExportSerializables
162                                 &&    (!atLeastOneExclusive || stdSaveTypes == 1);
163 
164             if (useThisFilter)
165             {
166                 QStringList ff = filter->getFileFilters(false);
167                 for (int j=0; j<ff.size(); ++j)
168                     fileFilters.append(ff[j]);
169             }
170         }
171     }
172 
173     //persistent settings
174     QSettings settings;
175     settings.beginGroup(ccPS::SaveFile());
176 
177     //default filter
178     QString selectedFilter = fileFilters.first();
179     if (hasCloud)
180         selectedFilter = settings.value(ccPS::SelectedOutputFilterCloud(),selectedFilter).toString();
181     else if (hasMesh)
182         selectedFilter = settings.value(ccPS::SelectedOutputFilterMesh(), selectedFilter).toString();
183     else if (hasImages)
184         selectedFilter = settings.value(ccPS::SelectedOutputFilterImage(), selectedFilter).toString();
185     else if (hasPolylines)
186         selectedFilter = settings.value(ccPS::SelectedOutputFilterPoly(), selectedFilter).toString();
187     
188     //default output path (+ filename)
189     QString currentPath = settings.value(ccPS::CurrentPath(),QApplication::applicationDirPath()).toString();
190     QString fullPathName = currentPath;
191     if (selNum == 1)
192     {
193         //hierarchy objects have generally as name: 'filename.ext (fullpath)'
194         //so we must only take the first part! (otherwise this type of name
195         //with a path inside perturbs the QFileDialog a lot ;))
196         QString defaultFileName(m_selectedEntities.front()->getName());
197         if (m_selectedEntities.front()->isA(CC_TYPES::HIERARCHY_OBJECT))
198         {
199             QStringList parts = defaultFileName.split(' ',QString::SkipEmptyParts);
200             if (parts.size() > 0)
201                 defaultFileName = parts[0];
202         }
203 
204         //we remove the extension
205         defaultFileName = QFileInfo(defaultFileName).baseName();
206 
207         if (!IsValidFileName(defaultFileName))
208         {
209             ccLog::Warning("[I/O] First entity's name would make an invalid filename! Can't use it...");
210             defaultFileName = "project";
211         }
212         
213         fullPathName += QString("/") + defaultFileName;
214     }
215 
216     //ask the user for the output filename
217     QString selectedFilename = QFileDialog::getSaveFileName(this,
218                                                             "Save file",
219                                                             fullPathName,
220                                                             fileFilters.join(s_fileFilterSeparator),
221                                                             &selectedFilter);
222 
223     if (selectedFilename.isEmpty())
224     {
225         //process cancelled by the user
226         return;
227     }
228 
229     //ignored items
230     if (hasOther)
231     {
232         ccConsole::Warning("[I/O] The following selected entites won't be saved:");
233         for (unsigned i=0; i<other.getChildrenNumber(); ++i)
234             ccConsole::Warning(QString("\t- %1s").arg(other.getChild(i)->getName()));
235     }
236 
237     CC_FILE_ERROR result = CC_FERR_NO_ERROR;
238     FileIOFilter::SaveParameters parameters;
239     {
240         parameters.alwaysDisplaySaveDialog = true;
241         parameters.parentWidget = this;
242     }
243     
244     //specific case: BIN format
245     if (selectedFilter == BinFilter::GetFileFilter())
246     {
247         if (selNum == 1)
248         {
249             result = FileIOFilter::SaveToFile(m_selectedEntities.front(),selectedFilename,parameters,selectedFilter);
250         }
251         else
252         {
253             //we'll regroup all selected entities in a temporary group
254             ccHObject tempContainer;
255             ConvertToGroup(m_selectedEntities,tempContainer,ccHObject::DP_NONE);
256             if (tempContainer.getChildrenNumber())
257             {
258                 result = FileIOFilter::SaveToFile(&tempContainer,selectedFilename,parameters,selectedFilter);
259             }
260             else
261             {
262                 ccLog::Warning("[I/O] None of the selected entities can be saved this way...");
263                 result = CC_FERR_NO_SAVE;
264             }
265         }
266     }
267     else if (entitiesToSave.getChildrenNumber() != 0)
268     {
269         //ignored items
270         /*if (hasSerializable)
271         {
272             if (!hasOther)
273                 ccConsole::Warning("[I/O] The following selected entites won't be saved:"); //display this warning only if not already done
274             for (unsigned i=0; i<otherSerializable.getChildrenNumber(); ++i)
275                 ccConsole::Warning(QString("\t- %1").arg(otherSerializable.getChild(i)->getName()));
276         }
277         //*/
278 
279         result = FileIOFilter::SaveToFile(    entitiesToSave.getChildrenNumber() > 1 ? &entitiesToSave : entitiesToSave.getChild(0),
280                                             selectedFilename,
281                                             parameters,
282                                             selectedFilter);
283     }
284 
285     //update default filters
286     if (hasCloud)
287         settings.setValue(ccPS::SelectedOutputFilterCloud(),selectedFilter);
288     if (hasMesh)
289         settings.setValue(ccPS::SelectedOutputFilterMesh(), selectedFilter);
290     if (hasImages)
291         settings.setValue(ccPS::SelectedOutputFilterImage(),selectedFilter);
292     if (hasPolylines)
293         settings.setValue(ccPS::SelectedOutputFilterPoly(), selectedFilter);
294 
295     //we update current file path
296     currentPath = QFileInfo(selectedFilename).absolutePath();
297     settings.setValue(ccPS::CurrentPath(),currentPath);
298     settings.endGroup();
299 }
void MainWindow::doActionSaveFile()

相关文章:

  • 2021-05-20
  • 2021-09-17
  • 2021-09-10
  • 2021-12-06
  • 2022-01-06
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-07-16
  • 2021-05-14
  • 2021-06-08
  • 2021-11-06
  • 2021-10-02
  • 2022-02-09
  • 2021-06-02
相关资源
相似解决方案