0027880: Samples - fix handling of Unicode paths within MFC import/export sample
[occt.git] / samples / mfc / standard / Common / ImportExport / ImportExport.cpp
1 // ImportExport.cpp: implementation of the CImportExport class.
2 //
3 //////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "ImportExport.h"
7 #include <OCC_App.h>
8
9 #include "SaveSTEPDlg.h"
10
11 #include "TColStd_SequenceOfAsciiString.hxx"
12 #include "TColStd_SequenceOfExtendedString.hxx"
13 #include "OSD_Timer.hxx"
14
15 #include "IGESControl_Reader.hxx"
16 #include "STEPControl_Controller.hxx"
17
18 #include <BRepAlgo.hxx>
19 #include <IGESControl_Controller.hxx>
20 #include <IGESControl_Writer.hxx>
21 #include <Interface_Static.hxx>
22 #include <STEPControl_Reader.hxx>
23 #include <Geom_Curve.hxx>
24 #include <STEPControl_Writer.hxx>
25 #include <TopoDS_Compound.hxx>
26 #include <Geom_Line.hxx>
27 #include <StlAPI_Writer.hxx>
28 #include <VrmlAPI_Writer.hxx>
29 #include <VrmlData_Scene.hxx>
30 #include <VrmlData_ShapeConvert.hxx>
31 #include <VrmlData_Appearance.hxx>
32 #include <VrmlData_Material.hxx>
33 #include <VrmlData_Group.hxx>
34 #include <VrmlData_ListOfNode.hxx>
35 #include <VrmlData_ShapeNode.hxx>
36
37 #include <XSControl_WorkSession.hxx>
38 #include <XSControl_TransferReader.hxx>
39 #include <STEPConstruct_Styles.hxx>
40 #include <TColStd_HSequenceOfTransient.hxx>
41 #include <STEPConstruct.hxx>
42 #include <StepVisual_StyledItem.hxx>
43
44 #ifdef _DEBUG
45 #undef THIS_FILE
46 static char THIS_FILE[]=__FILE__;
47 //#define new DEBUG_NEW
48 #endif
49
50 //////////////////////////////////////////////////////////////////////
51 // Construction/Destruction
52 //////////////////////////////////////////////////////////////////////
53
54 Handle(TopTools_HSequenceOfShape) CImportExport::BuildSequenceFromContext(const Handle(AIS_InteractiveContext)& anInteractiveContext,
55                                                                           Handle(Quantity_HArray1OfColor)&      anArrayOfColors,
56                                                                           Handle(TColStd_HArray1OfReal)&        anArrayOfTransparencies) 
57 {
58     Handle(TopTools_HSequenceOfShape) aSequence;
59     Standard_Integer nb = anInteractiveContext->NbCurrents(), i = 1;
60     if (!nb)
61         return aSequence;
62
63     aSequence               = new TopTools_HSequenceOfShape();
64     anArrayOfColors         = new Quantity_HArray1OfColor(1, nb);
65     anArrayOfTransparencies = new TColStd_HArray1OfReal  (1, nb);
66
67     Handle(AIS_InteractiveObject) picked;
68     for(anInteractiveContext->InitCurrent();anInteractiveContext->MoreCurrent();anInteractiveContext->NextCurrent())
69       {
70         picked = anInteractiveContext->Current();
71         if (anInteractiveContext->Current()->IsKind(STANDARD_TYPE(AIS_Shape)))
72              {
73             Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast(picked);
74                 TopoDS_Shape aShape = aisShape->Shape();
75             aSequence->Append(aShape);
76             
77             Quantity_Color color;
78             aisShape->Color(color);
79             anArrayOfColors->SetValue(i, color);
80             
81             Standard_Real transparency = aisShape->Transparency();
82             anArrayOfTransparencies->SetValue(i, transparency);
83
84             i++;
85              }
86       }
87       return aSequence;
88 }
89
90 //======================================================================
91 //=                                                                    =
92 //=                      BREP                                          =
93 //=                                                                    =
94 //======================================================================
95
96 int CImportExport::ReadBREP (const Handle(AIS_InteractiveContext)& anInteractiveContext)
97 {
98     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadBREP();
99         if(aSequence->IsEmpty())
100                 return 1;
101         Handle(AIS_Shape) aShape;
102     for(int i=1;i<= aSequence->Length();i++){
103                 aShape = new AIS_Shape(aSequence->Value(i));
104                 anInteractiveContext->SetDisplayMode(aShape, 1, Standard_False);
105                 anInteractiveContext->Display(aShape, Standard_False);
106                 anInteractiveContext->SetCurrentObject(aShape, Standard_False);
107         } 
108         return 0;
109 }
110
111 Handle(TopTools_HSequenceOfShape) CImportExport::ReadBREP()
112 {
113   CFileDialog dlg(TRUE,
114                   NULL,
115                   NULL,
116                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
117                   L"BREP Files (*.brep , *.rle)|*.brep;  *.BREP; *.rle; *.RLE; |All Files (*.*)|*.*||",
118                   NULL ); 
119
120   CString SHAREPATHValue;
121   SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
122   CString initdir = (SHAREPATHValue + "\\occ");
123
124   dlg.m_ofn.lpstrInitialDir = initdir;
125
126   Handle(TopTools_HSequenceOfShape) aSequence= new TopTools_HSequenceOfShape();
127
128   if (dlg.DoModal() == IDOK) 
129   {
130     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
131     CString filename = dlg.GetPathName();
132     TopoDS_Shape aShape;
133     Standard_Boolean result = ReadBREP (filename, aShape);
134     if (result)
135     {
136       if (!BRepAlgo::IsValid(aShape))
137         MessageBoxW (AfxGetMainWnd()->m_hWnd, L"Warning: The shape is not valid!", L"Cascade Warning", MB_ICONWARNING);
138
139       aSequence->Append(aShape);
140     }
141     else 
142       MessageBoxW (AfxGetMainWnd()->m_hWnd, L"Error: The file was not read", L"Cascade Error", MB_ICONERROR);
143
144     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
145   }
146
147   return aSequence;
148 }
149 //----------------------------------------------------------------------
150
151 Standard_Boolean CImportExport::ReadBREP(CString      aFileName,
152                                         TopoDS_Shape& aShape)
153 {
154   aShape.Nullify();
155
156   std::filebuf aFileBuf;
157   std::istream aStream (&aFileBuf);
158   if (!aFileBuf.open (aFileName, ios::in))
159   {
160     return Standard_False;
161   }
162
163   BRep_Builder aBuilder;
164   BRepTools::Read (aShape, aStream, aBuilder);
165   return !aShape.IsNull();
166 }
167
168 void CImportExport::SaveBREP(const Handle(AIS_InteractiveContext)& anInteractiveContext)
169 {
170         anInteractiveContext->InitCurrent();
171         if (anInteractiveContext->NbCurrents() == 0){
172                 AfxMessageBox (L"No shape selected for export!");
173                 return;
174         }
175         Handle(TopTools_HSequenceOfShape) aHSequenceOfShape;
176     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
177     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
178         aHSequenceOfShape = BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies);
179         int aLength = aHSequenceOfShape->Length();
180         if (aLength == 1){
181                 TopoDS_Shape RES = aHSequenceOfShape->Value(1);
182                 CImportExport::SaveBREP(RES);
183         } else {
184                 TopoDS_Compound RES;
185                 BRep_Builder MKCP;
186                 MKCP.MakeCompound(RES);
187                 for (Standard_Integer i=1;i<=aLength;i++)
188                 {
189                         TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
190                         if ( aShape.IsNull() ) 
191                         {
192                                 continue;
193                         }
194                         MKCP.Add(RES, aShape);
195                 }
196                 CImportExport::SaveBREP(RES);
197         }
198 }
199
200 Standard_Boolean CImportExport::SaveBREP(const TopoDS_Shape& aShape)
201 {
202   CFileDialog dlg (FALSE, L"*.brep",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
203                    L"BREP Files (*.brep)|*.brep;|BREP Files (*.BREP)|*.BREP;||", NULL);
204   
205 CString SHAREPATHValue;
206 SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
207 CString initdir = (SHAREPATHValue + "\\occ");
208
209 dlg.m_ofn.lpstrInitialDir = initdir;
210
211   Standard_Boolean result = Standard_False; 
212   if (dlg.DoModal() == IDOK)  
213   { 
214     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
215     CString filename = dlg.GetPathName(); 
216     result = SaveBREP (filename, aShape);
217     if (!result)  
218        MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd,
219                     L"Error : The shape or shapes were not saved.",
220                     L"CasCade Error", MB_ICONERROR);
221     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
222   } 
223   return result;
224 }
225
226 //----------------------------------------------------------------------------------------
227 Standard_Boolean CImportExport::SaveBREP (CString             aFileName,
228                                           const TopoDS_Shape& aShape)
229 {
230   std::filebuf aFileBuf;
231   std::ostream aStream (&aFileBuf);
232   if (!aFileBuf.open (aFileName, ios::out))
233   {
234     return Standard_False;
235   }
236
237   BRepTools::Write (aShape, aStream); 
238   return Standard_True;
239 }
240
241 //======================================================================
242 //=                                                                    =
243 //=                      IGES                                          =
244 //=                                                                    =
245 //======================================================================
246
247
248
249 void CImportExport::ReadIGES(const Handle(AIS_InteractiveContext)& anInteractiveContext)
250 {
251     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadIGES();
252     for(int i=1;i<= aSequence->Length();i++)
253         anInteractiveContext->Display(new AIS_Shape(aSequence->Value(i)));
254
255 }
256
257 Handle(TopTools_HSequenceOfShape) CImportExport::ReadIGES()// not by reference --> the sequence is created here !!
258 {
259   CFileDialog dlg(TRUE,
260                   NULL,
261                   NULL,
262                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
263                   L"IGES Files (*.iges , *.igs)|*.iges; *.igs|All Files (*.*)|*.*||",
264                   NULL );
265
266 CString SHAREPATHValue;
267 SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
268 CString initdir = (SHAREPATHValue + "\\iges");
269
270 dlg.m_ofn.lpstrInitialDir = initdir;
271   
272   Handle(TopTools_HSequenceOfShape) aSequence = new TopTools_HSequenceOfShape();
273   if (dlg.DoModal() == IDOK) 
274   {
275     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
276     TCollection_AsciiString aFileName ((const wchar_t* )dlg.GetPathName());
277     Standard_Integer status = ReadIGES (aFileName.ToCString(), aSequence);
278     if (status != IFSelect_RetDone)
279     {
280       MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Error : The file is not read", L"CasCade Error", MB_ICONERROR);
281     }
282
283         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
284    }
285   return aSequence;
286 }
287 //----------------------------------------------------------------------
288
289 Standard_Integer CImportExport::ReadIGES(const Standard_CString& aFileName,
290                                          Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
291 {
292
293     IGESControl_Reader Reader;
294
295     Standard_Integer status = Reader.ReadFile(aFileName);
296
297     if (status != IFSelect_RetDone) return status;
298     Reader.TransferRoots();
299     TopoDS_Shape aShape = Reader.OneShape();     
300         aHSequenceOfShape->Append(aShape);
301
302     return status;
303 }
304 //----------------------------------------------------------------------
305
306 void CImportExport::SaveIGES(const Handle(AIS_InteractiveContext)& anInteractiveContext)
307 {
308         anInteractiveContext->InitCurrent();
309         if (anInteractiveContext->NbCurrents() == 0){
310                 AfxMessageBox (L"No shape selected for export!");
311                 return;
312         }
313     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
314     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
315     CImportExport::SaveIGES(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
316 }
317
318 Standard_Boolean CImportExport::SaveIGES(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
319 {
320     if (aHSequenceOfShape->Length() == 0)
321     {
322         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
323         return Standard_False;
324     }
325
326   CFileDialog dlg(FALSE, L"*.iges",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
327                   L"IGES Files (*.iges )|*.iges;|IGES Files (*.igs )| *.igs;||", NULL);
328
329 CString SHAREPATHValue;
330 SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
331 CString initdir = (SHAREPATHValue + "\\iges");
332
333 dlg.m_ofn.lpstrInitialDir = initdir;
334   
335   Standard_Boolean result=Standard_False;
336   if (dlg.DoModal() == IDOK)  
337   { 
338     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
339
340     TCollection_AsciiString aFileName ((const wchar_t* )dlg.GetPathName());
341
342     result = SaveIGES (aFileName.ToCString(), aHSequenceOfShape);
343     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
344    }
345     return result;
346 }
347 //----------------------------------------------------------------------
348
349 Standard_Boolean CImportExport::SaveIGES(const Standard_CString& aFileName,
350                                          const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
351 {
352
353     IGESControl_Controller::Init();
354         IGESControl_Writer ICW (Interface_Static::CVal("XSTEP.iges.unit"),
355                Interface_Static::IVal("XSTEP.iges.writebrep.mode"));
356         
357         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)  
358                 ICW.AddShape (aHSequenceOfShape->Value(i));                      
359
360         ICW.ComputeModel();
361         Standard_Boolean result = ICW.Write(aFileName );
362     return result;
363 }
364
365 //======================================================================
366
367 //======================================================================
368 //=                                                                    =
369 //=                      STEP                                          =
370 //=                                                                    =
371 //======================================================================
372
373 void CImportExport::ReadSTEP(const Handle(AIS_InteractiveContext)& anInteractiveContext)
374 {
375     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadSTEP();
376                 if (!aSequence.IsNull()) {      
377                         for(int i=1;i<= aSequence->Length();i++)
378         anInteractiveContext->Display(new AIS_Shape(aSequence->Value(i)), Standard_False);
379                 }
380 }
381
382 Handle(TopTools_HSequenceOfShape) CImportExport::ReadSTEP()// not by reference --> the sequence is created here !!
383 {
384   CFileDialog dlg(TRUE,
385                   NULL,
386                   NULL,
387                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
388                   L"STEP Files (*.stp;*.step)|*.stp; *.step|All Files (*.*)|*.*||",
389                   NULL );
390
391 CString SHAREPATHValue;
392 SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
393 CString initdir = (SHAREPATHValue + "\\step");
394
395 dlg.m_ofn.lpstrInitialDir = initdir;
396   
397   Handle(TopTools_HSequenceOfShape) aSequence= new TopTools_HSequenceOfShape();
398   if (dlg.DoModal() == IDOK) 
399   {
400     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
401     TCollection_AsciiString aFileName ((const wchar_t* )dlg.GetPathName());
402         IFSelect_ReturnStatus ReturnStatus = ReadSTEP (aFileName.ToCString(), aSequence);
403     switch (ReturnStatus) 
404     {
405        case IFSelect_RetError :
406            MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Not a valid Step file", L"ERROR", MB_ICONWARNING);
407        break;
408        case IFSelect_RetFail :
409            MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Reading has failed", L"ERROR", MB_ICONWARNING);
410        break;
411        case IFSelect_RetVoid :
412             MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Nothing to transfer", L"ERROR", MB_ICONWARNING);
413        break;
414     }
415     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));       
416   }
417   return aSequence;
418 }
419
420 IFSelect_ReturnStatus CImportExport::ReadSTEP(const Standard_CString& aFileName,
421                                               Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
422 {
423   aHSequenceOfShape->Clear();
424
425   // create additional log file
426   STEPControl_Reader aReader;
427   IFSelect_ReturnStatus status = aReader.ReadFile(aFileName);
428   if (status != IFSelect_RetDone)
429     return status;
430
431   aReader.WS()->TransferReader()->TransientProcess()->SetTraceLevel(2); // increase default trace level
432
433   Standard_Boolean failsonly = Standard_False;
434   aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
435
436   // Root transfers
437   Standard_Integer nbr = aReader.NbRootsForTransfer();
438   aReader.PrintCheckTransfer (failsonly, IFSelect_ItemsByEntity);
439   for ( Standard_Integer n = 1; n<=nbr; n++) {
440     /*Standard_Boolean ok =*/ aReader.TransferRoot(n);
441   }
442
443   // Collecting resulting entities
444   Standard_Integer nbs = aReader.NbShapes();
445   if (nbs == 0) {
446     return IFSelect_RetVoid;
447   }
448   for (Standard_Integer i=1; i<=nbs; i++) {
449     aHSequenceOfShape->Append(aReader.Shape(i));
450   }
451
452   return status;
453 }
454
455
456 //----------------------------------------------------------------------
457 void CImportExport::SaveSTEP(const Handle(AIS_InteractiveContext)& anInteractiveContext)
458 {
459         anInteractiveContext->InitCurrent();
460         if (anInteractiveContext->NbCurrents() == 0){
461                 AfxMessageBox (L"No shape selected for export!");
462                 return;
463         }
464     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
465     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
466     CImportExport::SaveSTEP(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
467 }
468
469 // Return True if no error
470 Standard_Boolean TestFacetedBrep(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
471 {
472         Standard_Boolean OneErrorFound = Standard_False;
473         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
474         {
475           TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
476
477           TopExp_Explorer Ex(aShape,TopAbs_FACE);
478           while (Ex.More() && !OneErrorFound)
479                 {
480                 // Get the      Geom_Surface outside the TopoDS_Face
481                 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(Ex.Current()));
482                 // check if it is a plane.
483                 if (!aSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
484                     OneErrorFound=Standard_True;
485                 Ex.Next();
486                 }
487           TopExp_Explorer Ex2(aShape,TopAbs_EDGE);
488           while (Ex2.More() && !OneErrorFound)
489                 {
490                 // Get the      Geom_Curve outside the TopoDS_Face
491                 Standard_Real FirstDummy,LastDummy;
492                 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(Ex2.Current()),FirstDummy,LastDummy);
493                 // check if it is a line.
494                 if (!aCurve->IsKind(STANDARD_TYPE(Geom_Line)))
495                     OneErrorFound=Standard_True;
496                 Ex2.Next();
497                 }
498         }
499         return !OneErrorFound;
500 }
501
502 IFSelect_ReturnStatus CImportExport::SaveSTEP(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
503 {
504     if (aHSequenceOfShape->Length() == 0)
505       {
506         MessageBox (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
507         return IFSelect_RetError;
508       }
509
510     IFSelect_ReturnStatus status = IFSelect_RetVoid;
511
512         CFileSaveSTEPDialog aDlg(NULL);
513
514         aDlg.m_Cc1ModelType = STEPControl_AsIs;
515
516         if (aDlg.DoModal() == IDOK) {
517         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
518     TCollection_AsciiString aFileName ((const wchar_t* )aDlg.GetPathName());
519
520                 STEPControl_StepModelType selection = aDlg.m_Cc1ModelType;
521
522         if(selection == STEPControl_FacetedBrep)
523
524         if (!TestFacetedBrep(aHSequenceOfShape))
525             {
526           MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"At least one shape doesn't contain facetes", L"CasCade Warning", MB_ICONWARNING);
527             return IFSelect_RetError;
528             }
529
530
531         status =  SaveSTEP (aFileName.ToCString(), aHSequenceOfShape, selection);
532         switch (status)
533           {
534             case IFSelect_RetError:
535                 MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Incorrect Data", L"ERROR", MB_ICONWARNING); 
536             break;
537             case IFSelect_RetFail:
538                 MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Writing has failed", L"ERROR", MB_ICONWARNING); 
539             break;
540             case IFSelect_RetVoid:
541                 MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Nothing to transfer", L"ERROR", MB_ICONWARNING); 
542             break;
543           }
544         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
545   } 
546   return status;
547 }
548 //----------------------------------------------------------------------------------------
549 IFSelect_ReturnStatus CImportExport::SaveSTEP(const Standard_CString& aFileName,
550                                               const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
551
552 const STEPControl_StepModelType aValue /* =TopoDSToCc1Act_ManifoldSolidBrep */ )
553
554 {
555     // CREATE THE WRITER
556
557     STEPControl_Writer aWriter;
558
559         IFSelect_ReturnStatus status;
560         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)  
561         {
562                         status =  aWriter.Transfer(aHSequenceOfShape->Value(i), aValue);
563             if ( status != IFSelect_RetDone ) return status;
564         }     
565     status = aWriter.Write(aFileName);
566     return status;
567 }
568
569
570
571 //======================================================================
572 //=                                                                    =
573 //=                      STL                                           =
574 //=                                                                    =
575 //======================================================================
576
577 void CImportExport::SaveSTL(const Handle(AIS_InteractiveContext)& anInteractiveContext)
578 {
579     anInteractiveContext->InitCurrent();
580         if (anInteractiveContext->NbCurrents() == 0){
581                 AfxMessageBox (L"No shape selected for export!");
582                 return;
583         }
584     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
585     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
586         CImportExport::SaveSTL(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
587 }
588
589 Standard_Boolean CImportExport::SaveSTL(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
590 {
591   CFileDialog dlg(FALSE, L"*.stl", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
592                       L"stl Files (*.stl)|*.stl;|STL Files (*.STL)|*.STL;||", NULL);
593
594 CString SHAREPATHValue;
595 SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
596 CString initdir = (SHAREPATHValue + "\\stl");
597
598 dlg.m_ofn.lpstrInitialDir = initdir;
599
600         Standard_Boolean result = Standard_False;
601
602         if (dlg.DoModal() == IDOK) {
603         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
604         TCollection_AsciiString aFileName ((const wchar_t* )dlg.GetPathName());
605         TCollection_AsciiString Message;
606         result = SaveSTL (aFileName.ToCString(), aHSequenceOfShape, Message);
607         CString aMsg (TCollection_ExtendedString (Message).ToWideString());
608         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, aMsg, result ? L"CasCade" : L"CasCade Error", result ? MB_OK : MB_ICONERROR);
609         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
610     } 
611   return result;
612 }
613
614 Standard_Boolean CImportExport::SaveSTL(const Standard_CString& aFileName,
615                                           const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
616                                           TCollection_AsciiString& ReturnMessage)
617 {
618         Standard_Boolean ReturnValue = Standard_True;
619     if (aHSequenceOfShape->Length() == 0)
620     {
621         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
622         return Standard_False;
623     }
624
625     ReturnMessage += "The Object have be saved in the file ";
626     ReturnMessage += aFileName;
627     ReturnMessage += "\n with the names : ";
628
629         TopoDS_Compound RES;
630         BRep_Builder MKCP;
631         MKCP.MakeCompound(RES);
632
633         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
634         {
635                 TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
636                 TCollection_AsciiString anObjectName("anObjectName_");
637                 anObjectName += i;
638                 ReturnMessage += anObjectName;
639                 ReturnMessage += " \n";
640
641                 if ( aShape.IsNull() ) 
642                 {
643                         ReturnMessage += " Error : Invalid shape \n";
644                         ReturnValue = Standard_False;
645                         continue;
646                  }
647
648                 MKCP.Add(RES, aShape);
649         }
650
651         StlAPI_Writer myStlWriter;
652         myStlWriter.Write(RES, aFileName);
653
654     return ReturnValue;
655 }
656
657
658 //======================================================================
659 //=                                                                    =
660 //=                      VRML                                          =
661 //=                                                                    =
662 //======================================================================
663
664 void CImportExport::SaveVRML(const Handle(AIS_InteractiveContext)& anInteractiveContext)
665 {
666    anInteractiveContext->InitCurrent();
667         if (anInteractiveContext->NbCurrents() == 0){
668                 AfxMessageBox (L"No shape selected for export!");
669                 return;
670         }
671     Handle(Quantity_HArray1OfColor) anArrayOfColors;
672     Handle(TColStd_HArray1OfReal)   anArrayOfTransparencies;
673         CImportExport::SaveVRML(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies),
674                             anArrayOfColors, anArrayOfTransparencies);
675 }
676
677 Standard_Boolean CImportExport::SaveVRML(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
678                                          const Handle(Quantity_HArray1OfColor)&   anArrayOfColors,
679                                          const Handle(TColStd_HArray1OfReal)&     anArrayOfTransparencies)
680 {
681   CFileDialog dlg(FALSE, L"*.vrml", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
682                       L"vrml Files (*.vrml)|*.vrml;|vrm Files (*.vrm)|*.vrm;||", NULL);
683
684 CString SHAREPATHValue;
685 SHAREPATHValue.GetEnvironmentVariable (L"CSF_OCCTDataPath");
686 CString initdir = (SHAREPATHValue + "\\vrml");
687
688 dlg.m_ofn.lpstrInitialDir = initdir;
689   
690   Standard_Boolean result = Standard_False;
691
692         if (dlg.DoModal() == IDOK) {
693         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
694         TCollection_AsciiString aFileName ((const wchar_t* )dlg.GetPathName());
695         TCollection_AsciiString Message;
696         result = SaveVRML (aFileName.ToCString(), aHSequenceOfShape, anArrayOfColors, anArrayOfTransparencies, Message);
697         CString aMsg (TCollection_ExtendedString(Message).ToWideString());
698         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, aMsg, result ? L"CasCade" : L"CasCade Error", result ? MB_OK : MB_ICONERROR);
699         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
700     } 
701   return result;
702 }
703
704 Standard_Boolean CImportExport::SaveVRML(const Standard_CString&                  aFileName,
705                                          const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
706                                          const Handle(Quantity_HArray1OfColor)&   anArrayOfColors,
707                                          const Handle(TColStd_HArray1OfReal)&     anArrayOfTransparencies,
708                                          TCollection_AsciiString&                 ReturnMessage)
709 {
710         Standard_Boolean ReturnValue = Standard_True;
711     if (aHSequenceOfShape->Length() == 0)
712     {
713         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
714         return Standard_False;
715     }
716
717     ReturnMessage += "The Object has been saved in the file ";
718     ReturnMessage += aFileName;
719     ReturnMessage += "\n with the names : ";
720
721     // VRML scene.
722     VrmlData_Scene scene;
723     VrmlData_ShapeConvert converter(scene/*, 0.001*/); // from mm to meters 
724     Standard_Integer iShape = 1; // Counter of shapes
725
726     for (int i = 1; i <= aHSequenceOfShape->Length(); i++)
727     {
728         // Shape
729         TopoDS_Shape shape = aHSequenceOfShape->Value(i);
730         if (shape.IsNull())
731         {
732           ReturnMessage += " Error : Invalid shape \n";
733           ReturnValue = Standard_False;
734           continue;
735         }
736
737         // Color
738         Quantity_Color color; // yellow
739         if (!anArrayOfColors.IsNull())
740             color = anArrayOfColors->Value(i);
741
742         // Transparency
743         Standard_Real transparency = 0.0;
744         if (!anArrayOfTransparencies.IsNull())
745             transparency = anArrayOfTransparencies->Value(i);
746
747         // Give a name to the shape.
748         TCollection_AsciiString name("Shape");
749         name += TCollection_AsciiString(iShape++);
750         converter.AddShape(shape, name.ToCString());
751         ReturnMessage += name;
752         ReturnMessage += '\n';
753
754         // Check presence of faces in the shape.
755         TopExp_Explorer expl(shape, TopAbs_FACE);
756         if (expl.More())
757             converter.Convert(true, false, 0.01); // faces only
758         else
759             converter.Convert(false, true, 0.01); // edges only
760
761         // Name of the color & transparency.
762         // It will be uniquely saved in VRML file.
763         TCollection_AsciiString cname = Quantity_Color::StringName(color.Name());
764         cname += transparency;
765
766         // Make the appearance (VRML attribute)
767         Handle(VrmlData_Appearance) appearance = Handle(VrmlData_Appearance)::DownCast(scene.FindNode(cname.ToCString()));
768         if (appearance.IsNull())
769         {
770             // Not found ... create a new one.
771             Handle(VrmlData_Material) material = new VrmlData_Material(scene, cname.ToCString(), 0.2, 0.2, transparency);
772             material->SetDiffuseColor(color);
773             material->SetEmissiveColor(color);
774             material->SetSpecularColor(color);
775             scene.AddNode(material, false);
776             appearance = new VrmlData_Appearance(scene, cname.ToCString());
777             appearance->SetMaterial(material);
778             scene.AddNode(appearance, false);
779         }
780
781         // Apply the material to the shape of entity.
782         Handle(VrmlData_Group) group = Handle(VrmlData_Group)::DownCast(scene.FindNode(name.ToCString()));
783         if (!group.IsNull())
784         {
785             VrmlData_ListOfNode::Iterator itr = group->NodeIterator();
786             for (; itr.More(); itr.Next())
787             {
788                 Handle(VrmlData_Node) node = itr.Value();
789                 if (node->DynamicType() == STANDARD_TYPE(VrmlData_ShapeNode))
790                 {
791                     Handle(VrmlData_ShapeNode) aShape = Handle(VrmlData_ShapeNode)::DownCast(node);
792                     aShape->SetAppearance(appearance);
793                 }
794                 else if (itr.Value()->DynamicType() == STANDARD_TYPE(VrmlData_Group))
795                 {
796                     Handle(VrmlData_Group) groupc = Handle(VrmlData_Group)::DownCast(itr.Value());
797                     VrmlData_ListOfNode::Iterator itrc = groupc->NodeIterator();
798                     for (; itrc.More(); itrc.Next())
799                     {
800                         Handle(VrmlData_Node) nodec = itrc.Value();
801                         if (nodec->DynamicType() == STANDARD_TYPE(VrmlData_ShapeNode))
802                         {
803                             Handle(VrmlData_ShapeNode) shapec = Handle(VrmlData_ShapeNode)::DownCast(nodec);
804                             shapec->SetAppearance(appearance);
805                         }
806                     } // for of group nodes...
807                 } // if (it is a shape node...
808             } // for of group nodes...
809         } // if (!group.IsNull...
810     } // iterator of shapes
811
812     // Call VRML writer
813     ofstream writer(aFileName);
814     writer<<scene;
815     writer.close();
816
817     /* Old approach to store shapes in VRML (without color & transparency).
818         TopoDS_Compound RES;
819         BRep_Builder MKCP;
820         MKCP.MakeCompound(RES);
821
822         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
823         {
824                 TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
825                 TCollection_AsciiString anObjectName("anObjectName_");
826                 anObjectName += i;
827                 ReturnMessage += anObjectName;
828                 ReturnMessage += " \n";
829
830                 if ( aShape.IsNull() ) 
831                 {
832                         ReturnMessage += " Error : Invalid shape \n";
833                         ReturnValue = Standard_False;
834                         continue;
835                  }
836
837                 MKCP.Add(RES, aShape);
838         }
839
840         VrmlAPI_Writer myVrmlWriter;
841         myVrmlWriter.Write(RES, aFileName);
842     */
843
844     return ReturnValue;
845 }
846
847
848
849