0025387: Error appears during export to STEP operation in ImportExport MFC 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 "SaveCSFDBDlg.h"
10
11 #include "SaveSTEPDlg.h"
12
13 #include "TColStd_SequenceOfAsciiString.hxx"
14 #include "TColStd_SequenceOfExtendedString.hxx"
15 #include "OSD_Timer.hxx"
16
17 #include "IGESControl_Reader.hxx"
18 #include "STEPControl_Controller.hxx"
19
20 #include <BRepAlgo.hxx>
21 #include <FSD_File.hxx>
22 #include <ShapeSchema.hxx>
23 #include <PTopoDS_HShape.hxx>
24 #include <Storage_HSeqOfRoot.hxx>
25 #include <Storage_Root.hxx>
26 #include <PTColStd_PersistentTransientMap.hxx>
27 #include <MgtBRep.hxx>
28 #include <PTColStd_TransientPersistentMap.hxx>
29 #include <IGESControl_Controller.hxx>
30 #include <IGESControl_Writer.hxx>
31 #include <Interface_Static.hxx>
32 #include <STEPControl_Reader.hxx>
33 #include <Geom_Curve.hxx>
34 #include <STEPControl_Writer.hxx>
35 #include <TopoDS_Compound.hxx>
36 #include <Geom_Line.hxx>
37 #include <StlAPI_Writer.hxx>
38 #include <VrmlAPI_Writer.hxx>
39 #include <VrmlData_Scene.hxx>
40 #include <VrmlData_ShapeConvert.hxx>
41 #include <VrmlData_Appearance.hxx>
42 #include <VrmlData_Material.hxx>
43 #include <VrmlData_Group.hxx>
44 #include <VrmlData_ListOfNode.hxx>
45 #include <VrmlData_ShapeNode.hxx>
46
47 #include <XSControl_WorkSession.hxx>
48 #include <STEPConstruct_Styles.hxx>
49 #include <TColStd_HSequenceOfTransient.hxx>
50 #include <STEPConstruct.hxx>
51 #include <StepVisual_StyledItem.hxx>
52
53 #ifdef _DEBUG
54 #undef THIS_FILE
55 static char THIS_FILE[]=__FILE__;
56 //#define new DEBUG_NEW
57 #endif
58
59 //////////////////////////////////////////////////////////////////////
60 // Construction/Destruction
61 //////////////////////////////////////////////////////////////////////
62
63 Handle(TopTools_HSequenceOfShape) CImportExport::BuildSequenceFromContext(const Handle(AIS_InteractiveContext)& anInteractiveContext,
64                                                                           Handle(Quantity_HArray1OfColor)&      anArrayOfColors,
65                                                                           Handle(TColStd_HArray1OfReal)&        anArrayOfTransparencies) 
66 {
67     Handle(TopTools_HSequenceOfShape) aSequence;
68     Standard_Integer nb = anInteractiveContext->NbCurrents(), i = 1;
69     if (!nb)
70         return aSequence;
71
72     aSequence               = new TopTools_HSequenceOfShape();
73     anArrayOfColors         = new Quantity_HArray1OfColor(1, nb);
74     anArrayOfTransparencies = new TColStd_HArray1OfReal  (1, nb);
75
76     Handle(AIS_InteractiveObject) picked;
77     for(anInteractiveContext->InitCurrent();anInteractiveContext->MoreCurrent();anInteractiveContext->NextCurrent())
78       {
79         picked = anInteractiveContext->Current();
80         if (anInteractiveContext->Current()->IsKind(STANDARD_TYPE(AIS_Shape)))
81              {
82             Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast(picked);
83                 TopoDS_Shape aShape = aisShape->Shape();
84             aSequence->Append(aShape);
85             
86             Quantity_Color color;
87             aisShape->Color(color);
88             anArrayOfColors->SetValue(i, color);
89             
90             Standard_Real transparency = aisShape->Transparency();
91             anArrayOfTransparencies->SetValue(i, transparency);
92
93             i++;
94              }
95       }
96       return aSequence;
97 }
98
99 //======================================================================
100 //=                                                                    =
101 //=                      BREP                                          =
102 //=                                                                    =
103 //======================================================================
104
105 int CImportExport::ReadBREP (const Handle_AIS_InteractiveContext& anInteractiveContext)
106 {
107     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadBREP();
108         if(aSequence->IsEmpty())
109                 return 1;
110         Handle_AIS_Shape aShape;
111     for(int i=1;i<= aSequence->Length();i++){
112                 aShape = new AIS_Shape(aSequence->Value(i));
113                 anInteractiveContext->SetDisplayMode(aShape, 1, Standard_False);
114                 anInteractiveContext->Display(aShape, Standard_False);
115                 anInteractiveContext->SetCurrentObject(aShape, Standard_False);
116         } 
117         return 0;
118 }
119
120 Handle(TopTools_HSequenceOfShape) CImportExport::ReadBREP()
121 {
122   CFileDialog dlg(TRUE,
123                   NULL,
124                   NULL,
125                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
126                   L"BREP Files (*.brep , *.rle)|*.brep;  *.BREP; *.rle; *.RLE; |All Files (*.*)|*.*||",
127                   NULL ); 
128
129   CString CASROOTValue;
130   CASROOTValue.GetEnvironmentVariable (L"CASROOT");
131   CString initdir = (CASROOTValue + "\\..\\data\\occ");
132
133   dlg.m_ofn.lpstrInitialDir = initdir;
134
135   Handle(TopTools_HSequenceOfShape) aSequence= new TopTools_HSequenceOfShape();
136
137   if (dlg.DoModal() == IDOK) 
138   {
139     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
140     CString filename = dlg.GetPathName();
141     TopoDS_Shape aShape;
142     Standard_Boolean result = ReadBREP (filename, aShape);
143     if (result)
144     {
145       if (!BRepAlgo::IsValid(aShape))
146         MessageBoxW (AfxGetMainWnd()->m_hWnd, L"Warning: The shape is not valid!", L"Cascade Warning", MB_ICONWARNING);
147
148       aSequence->Append(aShape);
149     }
150     else 
151       MessageBoxW (AfxGetMainWnd()->m_hWnd, L"Error: The file was not read", L"Cascade Error", MB_ICONERROR);
152
153     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
154   }
155
156   return aSequence;
157 }
158 //----------------------------------------------------------------------
159
160 Standard_Boolean CImportExport::ReadBREP(CString      aFileName,
161                                         TopoDS_Shape& aShape)
162 {
163   aShape.Nullify();
164
165   std::filebuf aFileBuf;
166   std::istream aStream (&aFileBuf);
167   if (!aFileBuf.open (aFileName, ios::in))
168   {
169     return Standard_False;
170   }
171
172   BRep_Builder aBuilder;
173   BRepTools::Read (aShape, aStream, aBuilder);
174   return !aShape.IsNull();
175 }
176
177 void CImportExport::SaveBREP(const Handle_AIS_InteractiveContext& anInteractiveContext)
178 {
179         anInteractiveContext->InitCurrent();
180         if (anInteractiveContext->NbCurrents() == 0){
181                 AfxMessageBox (L"No shape selected for export!");
182                 return;
183         }
184         Handle(TopTools_HSequenceOfShape) aHSequenceOfShape;
185     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
186     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
187         aHSequenceOfShape = BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies);
188         int aLength = aHSequenceOfShape->Length();
189         if (aLength == 1){
190                 TopoDS_Shape RES = aHSequenceOfShape->Value(1);
191                 CImportExport::SaveBREP(RES);
192         } else {
193                 TopoDS_Compound RES;
194                 BRep_Builder MKCP;
195                 MKCP.MakeCompound(RES);
196                 for (Standard_Integer i=1;i<=aLength;i++)
197                 {
198                         TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
199                         if ( aShape.IsNull() ) 
200                         {
201                                 continue;
202                         }
203                         MKCP.Add(RES, aShape);
204                 }
205                 CImportExport::SaveBREP(RES);
206         }
207 }
208
209 Standard_Boolean CImportExport::SaveBREP(const TopoDS_Shape& aShape)
210 {
211   CFileDialog dlg (FALSE, L"*.brep",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
212                    L"BREP Files (*.brep)|*.brep;|BREP Files (*.BREP)|*.BREP;||", NULL);
213   
214 CString CASROOTValue;
215 CASROOTValue.GetEnvironmentVariable (L"CASROOT");
216 CString initdir = (CASROOTValue + "\\..\\data\\occ");
217
218 dlg.m_ofn.lpstrInitialDir = initdir;
219
220   Standard_Boolean result = Standard_False; 
221   if (dlg.DoModal() == IDOK)  
222   { 
223     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
224     CString filename = dlg.GetPathName(); 
225     result = SaveBREP (filename, aShape);
226     if (!result)  
227        MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd,
228                     L"Error : The shape or shapes were not saved.",
229                     L"CasCade Error", MB_ICONERROR);
230     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
231   } 
232   return result;
233 }
234
235 //----------------------------------------------------------------------------------------
236 Standard_Boolean CImportExport::SaveBREP (CString             aFileName,
237                                           const TopoDS_Shape& aShape)
238 {
239   std::filebuf aFileBuf;
240   std::ostream aStream (&aFileBuf);
241   if (!aFileBuf.open (aFileName, ios::out))
242   {
243     return Standard_False;
244   }
245
246   BRepTools::Write (aShape, aStream); 
247   return Standard_True;
248 }
249
250
251 //======================================================================
252 //=                                                                    =
253 //=                      CSFDB                                         =
254 //=                                                                    =
255 //======================================================================
256
257
258 TCollection_AsciiString CImportExport::BuildStorageErrorMessage( Storage_Error anError)
259
260
261     TCollection_AsciiString aMessage("Storage Status :");
262     switch ( anError ) {
263         case Storage_VSOk : 
264             aMessage += "no problem \n";
265         break;
266         case Storage_VSOpenError : 
267         aMessage += "OpenError while opening the stream \n";
268         break;
269         case Storage_VSModeError : 
270             aMessage += "the stream is opened with a wrong mode for operation \n";
271         break;
272         case Storage_VSCloseError : 
273             aMessage += "CloseError while closing the stream \n";
274         break;
275         case Storage_VSAlreadyOpen : 
276             aMessage += "stream is already opened \n";
277         break;
278         case Storage_VSNotOpen : 
279             aMessage += "stream not opened \n";
280         break;
281         case Storage_VSSectionNotFound : 
282             aMessage += "the section is not found \n";
283         break;
284         case Storage_VSWriteError : 
285             aMessage += "error during writing \n";
286         break;
287         case Storage_VSFormatError : 
288             aMessage += "wrong format error occured while reading \n";
289         break;
290         case Storage_VSUnknownType : 
291             aMessage += "try to read an unknown type \n";
292         break;
293         case Storage_VSTypeMismatch : 
294             aMessage += "try to read a wrong primitive type (read a char while expecting a real) \n";
295         break;
296         case Storage_VSInternalError : 
297             aMessage += "internal error \n ";
298         break;
299         case Storage_VSExtCharParityError : 
300             aMessage += "problem with 16bit characters, may be an 8bit character is inserted inside a 16bit string \n";
301         break;
302         default :
303             aMessage += "Unknown Status ";
304             aMessage += anError;
305             aMessage += " \n";
306         break;
307     }
308     return aMessage;
309 }
310
311 void CImportExport::ReadCSFDB(const Handle(AIS_InteractiveContext)& anInteractiveContext)
312 {
313     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadCSFDB();
314     for(int i=1;i<= aSequence->Length();i++)
315         anInteractiveContext->Display(new AIS_Shape(aSequence->Value(i)), Standard_False);
316 }
317
318 Handle(TopTools_HSequenceOfShape) CImportExport::ReadCSFDB() // not by reference --> the sequence is created here !!
319 {
320   CFileDialog dlg(TRUE,
321                   NULL,
322                   NULL,
323                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
324                   L"CSFDB Files (*.CSFDB , *.csf)|*.csfdb;  *.csf; |All Files (*.*)|*.*||", 
325                   NULL );
326
327 CString CASROOTValue;
328 CASROOTValue.GetEnvironmentVariable(L"CASROOT");
329 CString initdir = (CASROOTValue + "\\..\\data\\csfdb");
330
331 dlg.m_ofn.lpstrInitialDir = initdir;
332   
333   Handle(TopTools_HSequenceOfShape) aSequence = new TopTools_HSequenceOfShape();;
334   if (dlg.DoModal() == IDOK) 
335   {
336     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
337     TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )dlg.GetPathName());
338     TCollection_AsciiString    aFileName  (aFileNameW, '?');
339     TCollection_AsciiString Message;
340     Standard_Boolean result = ReadCSFDB (aFileName.ToCString(), aSequence, Message);
341     CString aMsg (Message.ToCString());
342     MessageBoxW(AfxGetApp()->m_pMainWnd->m_hWnd, aMsg, result ? L"CasCade" : L"CasCade Error", result ? MB_OK : MB_ICONERROR);
343     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
344   }
345   return aSequence;
346 }
347
348 Standard_Boolean CImportExport::ReadCSFDB(const Standard_CString& aFileName,
349                                           Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape, // out parameter
350                                           TCollection_AsciiString& ReturnMessage)               // out parameter
351 {
352     // an I/O driver
353     FSD_File f;
354
355     // the applicative Schema
356     Handle(ShapeSchema) s = new ShapeSchema;
357
358     // a Read/Write data object
359     Handle(Storage_Data) d = new Storage_Data;
360
361     d->ClearErrorStatus();
362
363     // Check file type
364     if ( FSD_File::IsGoodFileType( aFileName ) != Storage_VSOk)  {
365     ReturnMessage = "Bad file type for ";
366     ReturnMessage += aFileName;
367     ReturnMessage += " \n";
368     return Standard_False;
369     }
370
371     // Open the archive, Read mode
372     Storage_Error err = f.Open(aFileName, Storage_VSRead);
373     // Read all the persistent object in the file with the schema
374     if ( err != Storage_VSOk ) {
375       ReturnMessage += BuildStorageErrorMessage(d->ErrorStatus());
376       return Standard_False;
377     }
378
379     d = s->Read( f );
380         err = d->ErrorStatus() ;
381
382     if ( err != Storage_VSOk ) {
383       ReturnMessage += BuildStorageErrorMessage(d->ErrorStatus());
384       return Standard_False;
385     }
386     // Close the file driver
387     f.Close();
388
389     ReturnMessage += "Application Name :"; ReturnMessage += d->ApplicationName();ReturnMessage += "\n";
390     ReturnMessage += "Application Version :"; ReturnMessage += d->ApplicationVersion();ReturnMessage += "\n";
391     ReturnMessage += "Data type :"; ReturnMessage += d->DataType();ReturnMessage += "\n";
392     ReturnMessage += "== User Infos : ==\n";
393     const TColStd_SequenceOfAsciiString& UserInfo = d->UserInfo();
394     for (int i=1;i<=UserInfo.Length();i++)
395       {ReturnMessage += UserInfo(i);ReturnMessage += "\n";}
396     ReturnMessage += "== Comments : ==\n";
397     const TColStd_SequenceOfExtendedString& Comments=d->Comments();
398     for ( int i=1;i<=Comments.Length();i++)
399       {ReturnMessage += Comments(i);ReturnMessage += "\n";}
400     ReturnMessage += "----------------\n";
401
402
403     // Read all the root objects
404     // Get the root list
405     Handle(Storage_HSeqOfRoot)  roots = d->Roots();
406     Handle(Standard_Persistent) p;
407     Handle(Storage_Root) r;
408     Handle(PTopoDS_HShape) aPShape;
409     for ( int i = 1; i <= roots->Length() ; i++ ) 
410      {
411       // Get the root
412       r = roots->Value(i);
413
414       // Get the persistent application object from the root
415       p = r->Object();
416
417       // Display information
418       ReturnMessage += "Persistent Object "; ReturnMessage += i; ReturnMessage += "\n";
419       ReturnMessage += "Name             :"; ReturnMessage += r->Name(); ReturnMessage += "\n";
420       ReturnMessage += "Type             :"; ReturnMessage += r->Type(); ReturnMessage += "\n";
421
422       aPShape  = Handle(PTopoDS_HShape)::DownCast(p);
423
424       if ( !aPShape.IsNull() ) 
425         {
426               //   To Be  ReWriten to suppress the cout,
427           //    and provide a CallBack method for dynamic information. 
428               // Get the persistent shape
429               PTColStd_PersistentTransientMap aMap;
430               TopoDS_Shape aTShape;
431           MgtBRep::Translate(aPShape,aMap,aTShape,
432                     MgtBRep_WithTriangle);
433           aHSequenceOfShape->Append(aTShape);
434         } 
435             else
436             {
437                       ReturnMessage += "Error -> Unable to read\n";
438             } 
439     } 
440     return Standard_True;
441 }
442 //----------------------------------------------------------------------
443 void CImportExport::SaveCSFDB(const Handle(AIS_InteractiveContext)& anInteractiveContext)
444 {
445     anInteractiveContext->InitCurrent();
446         if (anInteractiveContext->NbCurrents() == 0){
447                 AfxMessageBox (L"No shape selected for export!");
448                 return;
449         }
450     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
451     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
452         CImportExport::SaveCSFDB(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
453 }
454
455 Standard_Boolean CImportExport::SaveCSFDB(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
456 {
457   Standard_Boolean result = Standard_False; 
458   CFileSaveCSFDBDialog aDlg(NULL);
459   aDlg.m_TriangleMode = MgtBRep_WithTriangle;
460   if (aDlg.DoModal() == IDOK) 
461   {
462         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
463         TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )aDlg.GetPathName());
464         TCollection_AsciiString    aFileName  (aFileNameW, '?');
465         TCollection_AsciiString Message;
466     //MgtBRep_TriangleMode selection = aDlg.m_TriangleMode;
467         Standard_Boolean result = SaveCSFDB (aFileName.ToCString(), aHSequenceOfShape, Message);
468         CString aMsg (Message.ToCString());
469         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, aMsg, result ? L"CasCade" : L"CasCade Error", result ? MB_OK : MB_ICONERROR);
470         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
471     } 
472   return result;
473 }
474
475 Standard_Boolean CImportExport::SaveCSFDB(const Standard_CString& aFileName,
476                                           const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
477                                           TCollection_AsciiString& ReturnMessage,// out parameter
478                                           MgtBRep_TriangleMode /*aTriangleMode*/ /* = MgtBRep_WithTriangle */)
479 {
480         Standard_Boolean ReturnValue = Standard_True;
481     if (aHSequenceOfShape->Length() == 0)
482     {
483         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
484         return Standard_False;
485     }
486  
487     // an I/O driver
488     FSD_File f;
489
490     // the applicative Schema containing 
491     // Pesistent Topology and Geometry
492     Handle(ShapeSchema) s = new ShapeSchema;
493
494     // a Read/Write data object
495     Handle(Storage_Data) d = new Storage_Data;
496
497     d->ClearErrorStatus();
498
499     //   To Be  ReWriten to suppress the Strings,
500     //    and provide a CallBack method for dynamic information. 
501
502     d->SetApplicationName  (TCollection_ExtendedString("SampleImportExport"));
503     d->SetApplicationVersion("1");
504     d->SetDataType(TCollection_ExtendedString("Shapes"));
505     d->AddToUserInfo("Try to store a Persistent set of Shapes in a flat file");
506     d->AddToComments(TCollection_ExtendedString("application is based on CasCade 2.0"));
507
508     // Open the archive, Write mode
509     Storage_Error err = f.Open(aFileName, Storage_VSWrite);
510
511     if ( err != Storage_VSOk ) {
512       ReturnMessage += BuildStorageErrorMessage(err);
513       return Standard_False;
514     }
515
516     PTColStd_TransientPersistentMap aMap;
517     ReturnMessage += "The Object have be saved in the file ";
518     ReturnMessage += aFileName;
519     ReturnMessage += "\n with the names : ";
520
521         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
522         {
523                 TopoDS_Shape aTShape= aHSequenceOfShape->Value(i);
524                 TCollection_AsciiString anObjectName("anObjectName_");
525                 anObjectName += i;
526                 ReturnMessage += anObjectName;
527                 ReturnMessage += " \n";
528
529                 if ( aTShape.IsNull() ) 
530                 {
531                         ReturnMessage += " Error : Invalid shape \n";
532                         ReturnValue = Standard_False;
533                         continue;
534                  }
535
536                 //Create the persistent Shape
537
538                 Handle(PTopoDS_HShape) aPShape = 
539                  MgtBRep::Translate(aTShape, aMap, MgtBRep_WithTriangle);
540
541  
542                 // Add the object in the data structure as root
543                 //   To Be  ReWriten to suppress the cout,
544                 //    and provide a CallBack method for dynamic information. 
545                 d->AddRoot(anObjectName, aPShape);
546         }
547
548     // Write the object in the file with the schema
549     s->Write( f, d);
550
551     // Close the driver
552     f.Close();
553
554     if ( d->ErrorStatus() != Storage_VSOk ) 
555      {
556         ReturnMessage += BuildStorageErrorMessage(d->ErrorStatus());
557         return Standard_False;
558      } 
559     return ReturnValue;
560 }
561
562
563 //======================================================================
564 //=                                                                    =
565 //=                      IGES                                          =
566 //=                                                                    =
567 //======================================================================
568
569
570
571 void CImportExport::ReadIGES(const Handle(AIS_InteractiveContext)& anInteractiveContext)
572 {
573     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadIGES();
574     for(int i=1;i<= aSequence->Length();i++)
575         anInteractiveContext->Display(new AIS_Shape(aSequence->Value(i)));
576
577 }
578
579 Handle(TopTools_HSequenceOfShape) CImportExport::ReadIGES()// not by reference --> the sequence is created here !!
580 {
581   CFileDialog dlg(TRUE,
582                   NULL,
583                   NULL,
584                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
585                   L"IGES Files (*.iges , *.igs)|*.iges; *.igs|All Files (*.*)|*.*||",
586                   NULL );
587
588 CString CASROOTValue;
589 CASROOTValue.GetEnvironmentVariable (L"CASROOT");
590 CString initdir = (CASROOTValue + "\\..\\data\\iges");
591
592 dlg.m_ofn.lpstrInitialDir = initdir;
593   
594   Handle(TopTools_HSequenceOfShape) aSequence = new TopTools_HSequenceOfShape();
595   if (dlg.DoModal() == IDOK) 
596   {
597     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
598     TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )dlg.GetPathName());
599     TCollection_AsciiString    aFileName  (aFileNameW, '?');
600     Standard_Integer status = ReadIGES (aFileName.ToCString(), aSequence);
601     if (status != IFSelect_RetDone)
602     {
603       MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Error : The file is not read", L"CasCade Error", MB_ICONERROR);
604     }
605
606         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
607    }
608   return aSequence;
609 }
610 //----------------------------------------------------------------------
611
612 Standard_Integer CImportExport::ReadIGES(const Standard_CString& aFileName,
613                                          Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
614 {
615
616     IGESControl_Reader Reader;
617
618     Standard_Integer status = Reader.ReadFile(aFileName);
619
620     if (status != IFSelect_RetDone) return status;
621     Reader.TransferRoots();
622     TopoDS_Shape aShape = Reader.OneShape();     
623         aHSequenceOfShape->Append(aShape);
624
625     return status;
626 }
627 //----------------------------------------------------------------------
628
629 void CImportExport::SaveIGES(const Handle(AIS_InteractiveContext)& anInteractiveContext)
630 {
631         anInteractiveContext->InitCurrent();
632         if (anInteractiveContext->NbCurrents() == 0){
633                 AfxMessageBox (L"No shape selected for export!");
634                 return;
635         }
636     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
637     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
638     CImportExport::SaveIGES(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
639 }
640
641 Standard_Boolean CImportExport::SaveIGES(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
642 {
643     if (aHSequenceOfShape->Length() == 0)
644     {
645         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
646         return Standard_False;
647     }
648
649   CFileDialog dlg(FALSE, L"*.iges",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
650                   L"IGES Files (*.iges )|*.iges;|IGES Files (*.igs )| *.igs;||", NULL);
651
652 CString CASROOTValue;
653 CASROOTValue.GetEnvironmentVariable (L"CASROOT");
654 CString initdir = (CASROOTValue + "\\..\\data\\iges");
655
656 dlg.m_ofn.lpstrInitialDir = initdir;
657   
658   Standard_Boolean result=Standard_False;
659   if (dlg.DoModal() == IDOK)  
660   { 
661     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
662
663     TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )dlg.GetPathName());
664     TCollection_AsciiString    aFileName  (aFileNameW, '?');
665
666     result = SaveIGES (aFileName.ToCString(), aHSequenceOfShape);
667     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
668    }
669     return result;
670 }
671 //----------------------------------------------------------------------
672
673 Standard_Boolean CImportExport::SaveIGES(const Standard_CString& aFileName,
674                                          const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
675 {
676
677     IGESControl_Controller::Init();
678         IGESControl_Writer ICW (Interface_Static::CVal("XSTEP.iges.unit"),
679                Interface_Static::IVal("XSTEP.iges.writebrep.mode"));
680         
681         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)  
682                 ICW.AddShape (aHSequenceOfShape->Value(i));                      
683
684         ICW.ComputeModel();
685         Standard_Boolean result = ICW.Write(aFileName );
686     return result;
687 }
688
689 //======================================================================
690
691 //======================================================================
692 //=                                                                    =
693 //=                      STEP                                          =
694 //=                                                                    =
695 //======================================================================
696
697 void CImportExport::ReadSTEP(const Handle(AIS_InteractiveContext)& anInteractiveContext)
698 {
699     Handle(TopTools_HSequenceOfShape) aSequence = CImportExport::ReadSTEP();
700                 if (!aSequence.IsNull()) {      
701                         for(int i=1;i<= aSequence->Length();i++)
702         anInteractiveContext->Display(new AIS_Shape(aSequence->Value(i)), Standard_False);
703                 }
704 }
705
706 Handle(TopTools_HSequenceOfShape) CImportExport::ReadSTEP()// not by reference --> the sequence is created here !!
707 {
708   CFileDialog dlg(TRUE,
709                   NULL,
710                   NULL,
711                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
712                   L"STEP Files (*.stp;*.step)|*.stp; *.step|All Files (*.*)|*.*||",
713                   NULL );
714
715 CString CASROOTValue;
716 CASROOTValue.GetEnvironmentVariable(L"CASROOT");
717 CString initdir = (CASROOTValue + "\\..\\data\\step");
718
719 dlg.m_ofn.lpstrInitialDir = initdir;
720   
721   Handle(TopTools_HSequenceOfShape) aSequence= new TopTools_HSequenceOfShape();
722   if (dlg.DoModal() == IDOK) 
723   {
724     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
725     TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )dlg.GetPathName());
726     TCollection_AsciiString    aFileName  (aFileNameW, '?');
727         IFSelect_ReturnStatus ReturnStatus = ReadSTEP (aFileName.ToCString(), aSequence);
728     switch (ReturnStatus) 
729     {
730        case IFSelect_RetError :
731            MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Not a valid Step file", L"ERROR", MB_ICONWARNING);
732        break;
733        case IFSelect_RetFail :
734            MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Reading has failed", L"ERROR", MB_ICONWARNING);
735        break;
736        case IFSelect_RetVoid :
737             MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Nothing to transfer", L"ERROR", MB_ICONWARNING);
738        break;
739     }
740     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));       
741   }
742   return aSequence;
743 }
744
745 IFSelect_ReturnStatus CImportExport::ReadSTEP(const Standard_CString& aFileName,
746                                               Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
747 {
748   aHSequenceOfShape->Clear();
749
750   // create additional log file
751   STEPControl_Reader aReader;
752   IFSelect_ReturnStatus status = aReader.ReadFile(aFileName);
753   if (status != IFSelect_RetDone)
754     return status;
755
756   aReader.WS()->MapReader()->SetTraceLevel(2); // increase default trace level
757
758   Standard_Boolean failsonly = Standard_False;
759   aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
760
761   // Root transfers
762   Standard_Integer nbr = aReader.NbRootsForTransfer();
763   aReader.PrintCheckTransfer (failsonly, IFSelect_ItemsByEntity);
764   for ( Standard_Integer n = 1; n<=nbr; n++) {
765     /*Standard_Boolean ok =*/ aReader.TransferRoot(n);
766   }
767
768   // Collecting resulting entities
769   Standard_Integer nbs = aReader.NbShapes();
770   if (nbs == 0) {
771     return IFSelect_RetVoid;
772   }
773   for (Standard_Integer i=1; i<=nbs; i++) {
774     aHSequenceOfShape->Append(aReader.Shape(i));
775   }
776
777   return status;
778 }
779
780
781 //----------------------------------------------------------------------
782 void CImportExport::SaveSTEP(const Handle(AIS_InteractiveContext)& anInteractiveContext)
783 {
784         anInteractiveContext->InitCurrent();
785         if (anInteractiveContext->NbCurrents() == 0){
786                 AfxMessageBox (L"No shape selected for export!");
787                 return;
788         }
789     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
790     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
791     CImportExport::SaveSTEP(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
792 }
793
794 // Return True if no error
795 Standard_Boolean TestFacetedBrep(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
796 {
797         Standard_Boolean OneErrorFound = Standard_False;
798         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
799         {
800           TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
801
802           TopExp_Explorer Ex(aShape,TopAbs_FACE);
803           while (Ex.More() && !OneErrorFound)
804                 {
805                 // Get the      Geom_Surface outside the TopoDS_Face
806                 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(Ex.Current()));
807                 // check if it is a plane.
808                 if (!aSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
809                     OneErrorFound=Standard_True;
810                 Ex.Next();
811                 }
812           TopExp_Explorer Ex2(aShape,TopAbs_EDGE);
813           while (Ex2.More() && !OneErrorFound)
814                 {
815                 // Get the      Geom_Curve outside the TopoDS_Face
816                 Standard_Real FirstDummy,LastDummy;
817                 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(Ex2.Current()),FirstDummy,LastDummy);
818                 // check if it is a line.
819                 if (!aCurve->IsKind(STANDARD_TYPE(Geom_Line)))
820                     OneErrorFound=Standard_True;
821                 Ex2.Next();
822                 }
823         }
824         return !OneErrorFound;
825 }
826
827 IFSelect_ReturnStatus CImportExport::SaveSTEP(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
828 {
829     if (aHSequenceOfShape->Length() == 0)
830       {
831         MessageBox (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
832         return IFSelect_RetError;
833       }
834
835     IFSelect_ReturnStatus status = IFSelect_RetVoid;
836
837         CFileSaveSTEPDialog aDlg(NULL);
838
839         aDlg.m_Cc1ModelType = STEPControl_AsIs;
840
841         if (aDlg.DoModal() == IDOK) {
842         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
843     TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )aDlg.GetPathName());
844     TCollection_AsciiString    aFileName  (aFileNameW, '?');
845
846                 STEPControl_StepModelType selection = aDlg.m_Cc1ModelType;
847
848         if(selection == STEPControl_FacetedBrep)
849
850         if (!TestFacetedBrep(aHSequenceOfShape))
851             {
852           MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"At least one shape doesn't contain facetes", L"CasCade Warning", MB_ICONWARNING);
853             return IFSelect_RetError;
854             }
855
856
857         status =  SaveSTEP (aFileName.ToCString(), aHSequenceOfShape, selection);
858         switch (status)
859           {
860             case IFSelect_RetError:
861                 MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Incorrect Data", L"ERROR", MB_ICONWARNING); 
862             break;
863             case IFSelect_RetFail:
864                 MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Writing has failed", L"ERROR", MB_ICONWARNING); 
865             break;
866             case IFSelect_RetVoid:
867                 MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"Nothing to transfer", L"ERROR", MB_ICONWARNING); 
868             break;
869           }
870         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
871   } 
872   return status;
873 }
874 //----------------------------------------------------------------------------------------
875 IFSelect_ReturnStatus CImportExport::SaveSTEP(const Standard_CString& aFileName,
876                                               const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
877
878 const STEPControl_StepModelType aValue /* =TopoDSToCc1Act_ManifoldSolidBrep */ )
879
880 {
881     // CREATE THE WRITER
882
883     STEPControl_Writer aWriter;
884
885         IFSelect_ReturnStatus status;
886         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)  
887         {
888                         status =  aWriter.Transfer(aHSequenceOfShape->Value(i), aValue);
889             if ( status != IFSelect_RetDone ) return status;
890         }     
891     status = aWriter.Write(aFileName);
892     return status;
893 }
894
895
896
897 //======================================================================
898 //=                                                                    =
899 //=                      STL                                           =
900 //=                                                                    =
901 //======================================================================
902
903 void CImportExport::SaveSTL(const Handle(AIS_InteractiveContext)& anInteractiveContext)
904 {
905     anInteractiveContext->InitCurrent();
906         if (anInteractiveContext->NbCurrents() == 0){
907                 AfxMessageBox (L"No shape selected for export!");
908                 return;
909         }
910     Handle(Quantity_HArray1OfColor)   anArrayOfColors;
911     Handle(TColStd_HArray1OfReal)     anArrayOfTransparencies;
912         CImportExport::SaveSTL(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies));
913 }
914
915 Standard_Boolean CImportExport::SaveSTL(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
916 {
917   CFileDialog dlg(FALSE, L"*.stl", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
918                       L"stl Files (*.stl)|*.stl;|STL Files (*.STL)|*.STL;||", NULL);
919
920 CString CASROOTValue;
921 CASROOTValue.GetEnvironmentVariable(L"CASROOT");
922 CString initdir = (CASROOTValue + "\\..\\data\\stl");
923
924 dlg.m_ofn.lpstrInitialDir = initdir;
925
926         Standard_Boolean result = Standard_False;
927
928         if (dlg.DoModal() == IDOK) {
929         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
930         TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )dlg.GetPathName());
931         TCollection_AsciiString    aFileName  (aFileNameW, '?');
932         TCollection_AsciiString Message;
933         result = SaveSTL (aFileName.ToCString(), aHSequenceOfShape, Message);
934         CString aMsg (Message.ToCString());
935         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, aMsg, result ? L"CasCade" : L"CasCade Error", result ? MB_OK : MB_ICONERROR);
936         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
937     } 
938   return result;
939 }
940
941 Standard_Boolean CImportExport::SaveSTL(const Standard_CString& aFileName,
942                                           const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
943                                           TCollection_AsciiString& ReturnMessage)
944 {
945         Standard_Boolean ReturnValue = Standard_True;
946     if (aHSequenceOfShape->Length() == 0)
947     {
948         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
949         return Standard_False;
950     }
951
952     PTColStd_TransientPersistentMap aMap;
953     ReturnMessage += "The Object have be saved in the file ";
954     ReturnMessage += aFileName;
955     ReturnMessage += "\n with the names : ";
956
957         TopoDS_Compound RES;
958         BRep_Builder MKCP;
959         MKCP.MakeCompound(RES);
960
961         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
962         {
963                 TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
964                 TCollection_AsciiString anObjectName("anObjectName_");
965                 anObjectName += i;
966                 ReturnMessage += anObjectName;
967                 ReturnMessage += " \n";
968
969                 if ( aShape.IsNull() ) 
970                 {
971                         ReturnMessage += " Error : Invalid shape \n";
972                         ReturnValue = Standard_False;
973                         continue;
974                  }
975
976                 MKCP.Add(RES, aShape);
977         }
978
979         StlAPI_Writer myStlWriter;
980         myStlWriter.Write(RES, aFileName);
981
982     return ReturnValue;
983 }
984
985
986 //======================================================================
987 //=                                                                    =
988 //=                      VRML                                          =
989 //=                                                                    =
990 //======================================================================
991
992 void CImportExport::SaveVRML(const Handle(AIS_InteractiveContext)& anInteractiveContext)
993 {
994    anInteractiveContext->InitCurrent();
995         if (anInteractiveContext->NbCurrents() == 0){
996                 AfxMessageBox (L"No shape selected for export!");
997                 return;
998         }
999     Handle(Quantity_HArray1OfColor) anArrayOfColors;
1000     Handle(TColStd_HArray1OfReal)   anArrayOfTransparencies;
1001         CImportExport::SaveVRML(BuildSequenceFromContext(anInteractiveContext, anArrayOfColors, anArrayOfTransparencies),
1002                             anArrayOfColors, anArrayOfTransparencies);
1003 }
1004
1005 Standard_Boolean CImportExport::SaveVRML(const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
1006                                          const Handle(Quantity_HArray1OfColor)&   anArrayOfColors,
1007                                          const Handle(TColStd_HArray1OfReal)&     anArrayOfTransparencies)
1008 {
1009   CFileDialog dlg(FALSE, L"*.vrml", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
1010                       L"vrml Files (*.vrml)|*.vrml;|vrm Files (*.vrm)|*.vrm;||", NULL);
1011
1012 CString CASROOTValue;
1013 CASROOTValue.GetEnvironmentVariable(L"CASROOT");
1014 CString initdir = (CASROOTValue + "\\..\\data\\vrml");
1015
1016 dlg.m_ofn.lpstrInitialDir = initdir;
1017   
1018   Standard_Boolean result = Standard_False;
1019
1020         if (dlg.DoModal() == IDOK) {
1021         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 
1022         TCollection_ExtendedString aFileNameW ((Standard_ExtString )(const wchar_t* )dlg.GetPathName());
1023         TCollection_AsciiString    aFileName  (aFileNameW, '?');
1024         TCollection_AsciiString Message;
1025         result = SaveVRML (aFileName.ToCString(), aHSequenceOfShape, anArrayOfColors, anArrayOfTransparencies, Message);
1026         CString aMsg (Message.ToCString());
1027         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, aMsg, result ? L"CasCade" : L"CasCade Error", result ? MB_OK : MB_ICONERROR);
1028         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); 
1029     } 
1030   return result;
1031 }
1032
1033 Standard_Boolean CImportExport::SaveVRML(const Standard_CString&                  aFileName,
1034                                          const Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape,
1035                                          const Handle(Quantity_HArray1OfColor)&   anArrayOfColors,
1036                                          const Handle(TColStd_HArray1OfReal)&     anArrayOfTransparencies,
1037                                          TCollection_AsciiString&                 ReturnMessage)
1038 {
1039         Standard_Boolean ReturnValue = Standard_True;
1040     if (aHSequenceOfShape->Length() == 0)
1041     {
1042         MessageBoxW (AfxGetApp()->m_pMainWnd->m_hWnd, L"No Shape in the HSequence!!", L"CasCade Warning", MB_ICONWARNING);
1043         return Standard_False;
1044     }
1045
1046     PTColStd_TransientPersistentMap aMap;
1047     ReturnMessage += "The Object has been saved in the file ";
1048     ReturnMessage += aFileName;
1049     ReturnMessage += "\n with the names : ";
1050
1051     // VRML scene.
1052     VrmlData_Scene scene;
1053     VrmlData_ShapeConvert converter(scene/*, 0.001*/); // from mm to meters 
1054     Standard_Integer iShape = 1; // Counter of shapes
1055
1056         for ( int i = 1; i <= aHSequenceOfShape->Length(); i++ )
1057         {
1058         // Shape
1059                 TopoDS_Shape shape = aHSequenceOfShape->Value( i );
1060                 if ( shape.IsNull() )
1061                 {
1062                         ReturnMessage += " Error : Invalid shape \n";
1063                         ReturnValue = Standard_False;
1064                         continue;
1065         }
1066
1067         // Color
1068         Quantity_Color color; // yellow
1069         if (!anArrayOfColors.IsNull())
1070             color = anArrayOfColors->Value(i);
1071
1072         // Transparency
1073         Standard_Real transparency = 0.0;
1074         if (!anArrayOfTransparencies.IsNull())
1075             transparency = anArrayOfTransparencies->Value(i);
1076
1077         // Give a name to the shape.
1078         TCollection_AsciiString name("Shape");
1079         name += TCollection_AsciiString(iShape++);
1080         converter.AddShape(shape, name.ToCString());
1081         ReturnMessage += name;
1082         ReturnMessage += '\n';
1083
1084         // Check presence of faces in the shape.
1085         TopExp_Explorer expl(shape, TopAbs_FACE);
1086         if (expl.More())
1087             converter.Convert(true, false, 0.01); // faces only
1088         else
1089             converter.Convert(false, true, 0.01); // edges only
1090
1091         // Name of the color & transparency.
1092         // It will be uniquely saved in VRML file.
1093         TCollection_AsciiString cname = Quantity_Color::StringName(color.Name());
1094         cname += transparency;
1095
1096         // Make the appearance (VRML attribute)
1097         Handle(VrmlData_Appearance) appearance = Handle(VrmlData_Appearance)::DownCast(scene.FindNode(cname.ToCString()));
1098         if (appearance.IsNull())
1099         {
1100             // Not found ... create a new one.
1101             Handle(VrmlData_Material) material = new VrmlData_Material(scene, cname.ToCString(), 0.2, 0.2, transparency);
1102             material->SetDiffuseColor(color);
1103             material->SetEmissiveColor(color);
1104             material->SetSpecularColor(color);
1105             scene.AddNode(material, false);
1106             appearance = new VrmlData_Appearance(scene, cname.ToCString());
1107             appearance->SetMaterial(material);
1108             scene.AddNode(appearance, false);
1109         }
1110
1111         // Apply the material to the shape of entity.
1112         Handle(VrmlData_Group) group = Handle(VrmlData_Group)::DownCast(scene.FindNode(name.ToCString()));
1113         if (!group.IsNull())
1114         {
1115             VrmlData_ListOfNode::Iterator itr = group->NodeIterator();
1116             for (; itr.More(); itr.Next())
1117             {
1118                 Handle(VrmlData_Node) node = itr.Value();
1119                 if (node->DynamicType() == STANDARD_TYPE(VrmlData_ShapeNode))
1120                 {
1121                     Handle(VrmlData_ShapeNode) shape = Handle(VrmlData_ShapeNode)::DownCast(node);
1122                     shape->SetAppearance(appearance);
1123                 }
1124                 else if (itr.Value()->DynamicType() == STANDARD_TYPE(VrmlData_Group))
1125                 {
1126                     Handle(VrmlData_Group) groupc = Handle(VrmlData_Group)::DownCast(itr.Value());
1127                     VrmlData_ListOfNode::Iterator itrc = groupc->NodeIterator();
1128                     for (; itrc.More(); itrc.Next())
1129                     {
1130                         Handle(VrmlData_Node) nodec = itrc.Value();
1131                         if (nodec->DynamicType() == STANDARD_TYPE(VrmlData_ShapeNode))
1132                         {
1133                             Handle(VrmlData_ShapeNode) shapec = Handle(VrmlData_ShapeNode)::DownCast(nodec);
1134                             shapec->SetAppearance(appearance);
1135                         }
1136                     } // for of group nodes...
1137                 } // if (it is a shape node...
1138             } // for of group nodes...
1139         } // if (!group.IsNull...
1140     } // iterator of shapes
1141
1142     // Call VRML writer
1143     ofstream writer(aFileName);
1144     writer<<scene;
1145     writer.close();
1146
1147     /* Old approach to store shapes in VRML (without color & transparency).
1148         TopoDS_Compound RES;
1149         BRep_Builder MKCP;
1150         MKCP.MakeCompound(RES);
1151
1152         for (Standard_Integer i=1;i<=aHSequenceOfShape->Length();i++)
1153         {
1154                 TopoDS_Shape aShape= aHSequenceOfShape->Value(i);
1155                 TCollection_AsciiString anObjectName("anObjectName_");
1156                 anObjectName += i;
1157                 ReturnMessage += anObjectName;
1158                 ReturnMessage += " \n";
1159
1160                 if ( aShape.IsNull() ) 
1161                 {
1162                         ReturnMessage += " Error : Invalid shape \n";
1163                         ReturnValue = Standard_False;
1164                         continue;
1165                  }
1166
1167                 MKCP.Add(RES, aShape);
1168         }
1169
1170         VrmlAPI_Writer myVrmlWriter;
1171         myVrmlWriter.Write(RES, aFileName);
1172     */
1173
1174     return ReturnValue;
1175 }
1176
1177
1178
1179