0030180: Data Exchange - VrmlAPI_Writer is expected to return export state
[occt.git] / src / VrmlAPI / VrmlAPI_Writer.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <BRep_Tool.hxx>
16 #include <OSD_OpenFile.hxx>
17 #include <OSD_Path.hxx>
18 #include <Poly_Triangulation.hxx>
19 #include <Quantity_HArray1OfColor.hxx>
20 #include <Standard_Stream.hxx>
21 #include <TColStd_HArray1OfReal.hxx>
22 #include <TopAbs_ShapeEnum.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Face.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopTools_Array1OfShape.hxx>
28 #include <Vrml.hxx>
29 #include <Vrml_Group.hxx>
30 #include <Vrml_Instancing.hxx>
31 #include <Vrml_Material.hxx>
32 #include <Vrml_Separator.hxx>
33 #include <VrmlAPI_Writer.hxx>
34 #include <VrmlConverter_Drawer.hxx>
35 #include <VrmlConverter_IsoAspect.hxx>
36 #include <VrmlConverter_LineAspect.hxx>
37 #include <VrmlConverter_PointAspect.hxx>
38 #include <VrmlConverter_Projector.hxx>
39 #include <VrmlConverter_ShadedShape.hxx>
40 #include <VrmlConverter_ShadingAspect.hxx>
41 #include <VrmlConverter_WFDeflectionShape.hxx>
42 #include <VrmlData_Scene.hxx>
43 #include <VrmlData_ShapeConvert.hxx>
44
45 VrmlAPI_Writer::VrmlAPI_Writer()
46 {
47   myDrawer = new VrmlConverter_Drawer;
48   myDeflection = -1;
49   Quantity_Color color;
50   color.SetValues(0, 0, 0, Quantity_TOC_RGB);
51   Handle(Quantity_HArray1OfColor) Col1 = new Quantity_HArray1OfColor(1,1);
52   Col1->SetValue(1,color);
53   Handle(TColStd_HArray1OfReal) kik1 = new TColStd_HArray1OfReal(1,1,0.0);
54   Handle(TColStd_HArray1OfReal) kik2 = new TColStd_HArray1OfReal(1,1,0.1);
55   myFrontMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
56   myPointsMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
57   myUisoMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
58   myVisoMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
59   myLineMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
60   myWireMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
61   myFreeBoundsMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
62   myUnfreeBoundsMaterial = new Vrml_Material(Col1,Col1, Col1, Col1, kik1, kik2);
63   DX = 1;      
64   DY = -1;  
65   DZ = 1;
66   XUp = 0;
67   YUp = 0;
68   ZUp = 1;
69   Focus = 6;
70   ResetToDefaults();
71 }
72
73 void VrmlAPI_Writer::ResetToDefaults() 
74 {
75   myTransparency = 0.0;
76   myShininess = 0.1;
77   Handle(TColStd_HArray1OfReal) kik1 = new TColStd_HArray1OfReal(1,1,myTransparency);
78   Handle(TColStd_HArray1OfReal) kik2 = new TColStd_HArray1OfReal(1,1,myShininess);
79   Handle(Quantity_HArray1OfColor) Col = new Quantity_HArray1OfColor(1,1);
80   Quantity_Color color; 
81   color.SetValues(0, 0, 0, Quantity_TOC_RGB);
82   Col->SetValue(1,color);
83   //
84   myFrontMaterial->SetAmbientColor(Col); myFrontMaterial->SetTransparency(kik1);myFrontMaterial->SetShininess(kik2);
85   myPointsMaterial->SetAmbientColor(Col); myPointsMaterial->SetTransparency(kik1);myPointsMaterial->SetShininess(kik2);
86   myUisoMaterial->SetAmbientColor(Col); myUisoMaterial->SetTransparency(kik1);myUisoMaterial->SetShininess(kik2);
87   myVisoMaterial->SetAmbientColor(Col); myVisoMaterial->SetTransparency(kik1);myVisoMaterial->SetShininess(kik2);
88   myLineMaterial->SetAmbientColor(Col); myLineMaterial->SetTransparency(kik1);myLineMaterial->SetShininess(kik2);
89   myWireMaterial->SetAmbientColor(Col); myWireMaterial->SetTransparency(kik1); myWireMaterial->SetShininess(kik2);
90   myFreeBoundsMaterial->SetAmbientColor(Col); myFreeBoundsMaterial->SetTransparency(kik1);myFreeBoundsMaterial->SetShininess(kik2);
91   myUnfreeBoundsMaterial->SetAmbientColor(Col); myUnfreeBoundsMaterial->SetTransparency(kik1);myUnfreeBoundsMaterial->SetShininess(kik2);
92   //
93   //
94   Handle(Quantity_HArray1OfColor) Col2 = new Quantity_HArray1OfColor(1,1);
95   color.SetValues(0.75, 0.75, 0.75, Quantity_TOC_RGB);
96   Col2->SetValue(1,color);
97   Handle(Quantity_HArray1OfColor) Col3 = new Quantity_HArray1OfColor(1,1);
98   color.SetValues(0.82, 0.79, 0.42, Quantity_TOC_RGB);
99   Col3->SetValue(1,color);
100   
101   myUisoMaterial->SetDiffuseColor(Col2);
102   myVisoMaterial->SetDiffuseColor(Col2);
103   myFreeBoundsMaterial->SetDiffuseColor(Col2);
104   myUnfreeBoundsMaterial->SetDiffuseColor(Col2);
105   
106   //
107 //  Handle(Quantity_HArray1OfColor) Col3 = new Quantity_HArray1OfColor(1,1);
108 //  color.SetValues(Quantity_NOC_GOLD);
109 //  Col3->SetValue(1,color);
110   myLineMaterial->SetDiffuseColor(Col2);
111   myWireMaterial->SetDiffuseColor(Col2);
112   //
113 //  Handle(Quantity_HArray1OfColor) Col4 = new Quantity_HArray1OfColor(1,1);
114 //  color.SetValues(Quantity_NOC_GOLD);
115 //  Col4->SetValue(1,color);
116   myFrontMaterial->SetDiffuseColor(Col2);
117   myPointsMaterial->SetDiffuseColor(Col2);
118   //
119   
120   myUisoMaterial->SetSpecularColor(Col3);
121   myVisoMaterial->SetSpecularColor(Col3);
122   myFreeBoundsMaterial->SetSpecularColor(Col3);
123   myUnfreeBoundsMaterial->SetSpecularColor(Col3);
124   myLineMaterial->SetSpecularColor(Col3);
125   myWireMaterial->SetSpecularColor(Col3);
126   myFrontMaterial->SetSpecularColor(Col3);
127   myPointsMaterial->SetSpecularColor(Col3);
128   
129   myRepresentation = VrmlAPI_BothRepresentation;
130 }
131 Handle(VrmlConverter_Drawer) VrmlAPI_Writer::Drawer() const
132 {
133   return myDrawer;
134 }
135 void VrmlAPI_Writer::SetDeflection(const Standard_Real aDef)
136 {
137   myDeflection = aDef;
138   if (myDeflection > 0) {
139     myDrawer->SetMaximalChordialDeviation(myDeflection);
140     myDrawer->SetTypeOfDeflection(Aspect_TOD_ABSOLUTE);
141   }
142   else myDrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
143 }
144 void VrmlAPI_Writer::SetRepresentation(const VrmlAPI_RepresentationOfShape aRep)
145 {
146   myRepresentation = aRep;
147 }
148 void VrmlAPI_Writer::SetTransparencyToMaterial(Handle(Vrml_Material)& aMaterial,const Standard_Real aTransparency) 
149 {
150   Handle(TColStd_HArray1OfReal) t = new TColStd_HArray1OfReal(1,1,aTransparency);
151   aMaterial->SetTransparency(t);
152 }
153
154 void VrmlAPI_Writer::SetShininessToMaterial(Handle(Vrml_Material)& aMaterial,const Standard_Real aShininess) 
155 {  
156   Handle(TColStd_HArray1OfReal) s = new TColStd_HArray1OfReal(1,1,aShininess);
157   aMaterial->SetShininess(s);
158 }
159
160 void VrmlAPI_Writer::SetAmbientColorToMaterial(Handle(Vrml_Material)& aMaterial,const Handle(Quantity_HArray1OfColor)& Color) 
161 {
162   aMaterial->SetAmbientColor(Color);
163 }
164
165 void VrmlAPI_Writer::SetDiffuseColorToMaterial(Handle(Vrml_Material)& aMaterial,const Handle(Quantity_HArray1OfColor)& Color) 
166 {
167   aMaterial->SetDiffuseColor(Color);
168 }
169
170 void VrmlAPI_Writer::SetSpecularColorToMaterial(Handle(Vrml_Material)& aMaterial,const Handle(Quantity_HArray1OfColor)& Color) 
171 {
172   aMaterial->SetSpecularColor(Color);
173 }
174
175 void VrmlAPI_Writer::SetEmissiveColorToMaterial(Handle(Vrml_Material)& aMaterial,const Handle(Quantity_HArray1OfColor)& Color) 
176 {
177   aMaterial->SetEmissiveColor(Color);
178 }
179
180 VrmlAPI_RepresentationOfShape VrmlAPI_Writer::GetRepresentation() const
181 {
182   return myRepresentation;  
183 }
184
185 Handle(Vrml_Material) VrmlAPI_Writer::GetFrontMaterial() const
186 {
187   return myFrontMaterial;
188 }
189
190 Handle(Vrml_Material) VrmlAPI_Writer::GetPointsMaterial() const
191 {
192   return myPointsMaterial;
193 }
194
195 Handle(Vrml_Material) VrmlAPI_Writer::GetUisoMaterial() const
196 {
197   return myUisoMaterial;
198 }
199
200 Handle(Vrml_Material) VrmlAPI_Writer::GetVisoMaterial() const
201 {
202   return myVisoMaterial;
203 }
204
205 Handle(Vrml_Material) VrmlAPI_Writer::GetLineMaterial() const
206 {
207   return myLineMaterial;
208 }
209
210 Handle(Vrml_Material) VrmlAPI_Writer::GetWireMaterial() const
211 {
212   return myWireMaterial;
213 }
214
215 Handle(Vrml_Material) VrmlAPI_Writer::GetFreeBoundsMaterial() const
216 {
217   return myFreeBoundsMaterial;
218 }
219
220 Handle(Vrml_Material) VrmlAPI_Writer::GetUnfreeBoundsMaterial() const
221 {
222   return myUnfreeBoundsMaterial;
223 }
224
225 Standard_Boolean VrmlAPI_Writer::Write(const TopoDS_Shape& aShape,const Standard_CString aFile, const Standard_Integer aVersion) const
226 {
227   if (aVersion == 1)
228     return write_v1 (aShape, aFile);
229   else if (aVersion == 2)
230     return write_v2 (aShape, aFile);
231
232   return Standard_False;
233 }
234
235 Standard_Boolean VrmlAPI_Writer::write_v1(const TopoDS_Shape& aShape,const Standard_CString aFile) const
236 {
237   OSD_Path thePath(aFile);
238   TCollection_AsciiString theFile;thePath.SystemName(theFile);
239   std::ofstream outfile;
240   OSD_OpenStream(outfile, theFile.ToCString(), std::ios::out);
241   if (!outfile)
242   {
243     return Standard_False;
244   }
245   Handle(VrmlConverter_IsoAspect) ia = new VrmlConverter_IsoAspect;  // UIso
246   Handle(VrmlConverter_IsoAspect) ia1 = new VrmlConverter_IsoAspect; //VIso
247   ia->SetMaterial(myUisoMaterial);
248   ia->SetHasMaterial(Standard_True);
249   myDrawer->SetUIsoAspect(ia);
250   ia1->SetMaterial(myVisoMaterial);
251   ia1->SetHasMaterial(Standard_True);
252   myDrawer->SetVIsoAspect(ia1);
253 // default Number of iso lines is 10
254 //----  Definition of LineAspect (default - without own material)
255   Handle(VrmlConverter_LineAspect) la = new VrmlConverter_LineAspect;
256   la->SetMaterial(myLineMaterial);
257   la->SetHasMaterial(Standard_True);
258   myDrawer->SetLineAspect(la);
259 //----  Definition of Wire (without any neighbour)
260   Handle(VrmlConverter_LineAspect) lw = new VrmlConverter_LineAspect;
261   lw->SetMaterial(myWireMaterial);
262   lw->SetHasMaterial(Standard_True);
263   myDrawer->SetWireAspect(lw);
264 //----  Definition of Free boundaries
265   Handle(VrmlConverter_LineAspect) lf = new VrmlConverter_LineAspect;
266   lf->SetMaterial(myFreeBoundsMaterial);
267   lf->SetHasMaterial(Standard_True);
268   myDrawer->SetFreeBoundaryAspect(lf);
269 //----  Definition of Unfree boundaries
270   Handle(VrmlConverter_LineAspect) lun = new VrmlConverter_LineAspect;
271   lun->SetMaterial(myUnfreeBoundsMaterial);
272   lun->SetHasMaterial(Standard_True);
273   myDrawer->SetUnFreeBoundaryAspect(lun);
274 //----  Definition of Points (default - without own material)
275   Handle(VrmlConverter_PointAspect) pa = new VrmlConverter_PointAspect;
276   pa->SetMaterial(myPointsMaterial);
277   pa->SetHasMaterial(Standard_True);
278   myDrawer->SetPointAspect(pa);
279 //-----------------------------------------
280   Handle(VrmlConverter_ShadingAspect) sa = new VrmlConverter_ShadingAspect;
281   sa->SetFrontMaterial(myFrontMaterial);
282   sa->SetHasMaterial(Standard_True);
283   Vrml_ShapeHints  sh;
284   sa->SetShapeHints(sh);
285   myDrawer->SetShadingAspect(sa);
286 //-------- Shape --------------------------
287   TopTools_Array1OfShape Shapes(1,1);
288   Shapes.SetValue(1,aShape);
289
290   // Check shape tesselation
291   TopExp_Explorer anExp (aShape, TopAbs_FACE);
292   TopLoc_Location aLoc;
293   Standard_Boolean hasTriangles = Standard_False;
294   for (; anExp.More(); anExp.Next())
295   {
296     const TopoDS_Face& aFace = TopoDS::Face (anExp.Current());
297     if (!aFace.IsNull()) 
298     {
299       Handle(Poly_Triangulation) aTri =
300         BRep_Tool::Triangulation (aFace, aLoc);
301
302       if (!aTri.IsNull())
303       {
304         hasTriangles = Standard_True;
305         break;
306       }
307     }
308   }
309
310 //=========================================
311 //----  Definition of data for Projector
312 //=========================================
313
314   VrmlConverter_TypeOfLight Light = VrmlConverter_NoLight;
315   VrmlConverter_TypeOfCamera Camera = VrmlConverter_PerspectiveCamera;
316   Handle(VrmlConverter_Projector) projector = new VrmlConverter_Projector (Shapes, 
317                                                                            Focus, 
318                                                                            DX,  DY,  DZ, 
319                                                                            XUp, YUp, ZUp,
320                                                                            Camera,
321                                                                            Light);
322   Vrml::VrmlHeaderWriter(outfile);
323   if (myRepresentation == VrmlAPI_BothRepresentation)
324     Vrml::CommentWriter(" This file contents both Shaded and Wire Frame representation of selected Shape ",outfile);   
325   if (myRepresentation == VrmlAPI_ShadedRepresentation)
326     Vrml::CommentWriter(" This file contents only Shaded representation of selected Shape ",outfile);   
327   if (myRepresentation == VrmlAPI_WireFrameRepresentation)
328     Vrml::CommentWriter(" This file contents only Wire Frame representation of selected Shape ",outfile);   
329   Vrml_Separator S1;
330   S1.Print(outfile); 
331   projector->Add(outfile);
332   Light = VrmlConverter_DirectionLight;
333   Camera = VrmlConverter_OrthographicCamera;
334   Handle(VrmlConverter_Projector) projector1 = new VrmlConverter_Projector (Shapes, 
335                                                                            Focus, 
336                                                                            DX,  DY,  DZ, 
337                                                                            XUp, YUp, ZUp,
338                                                                            Camera,
339                                                                            Light);
340   projector1->Add(outfile);
341   Vrml_Separator S2;
342   S2.Print(outfile); 
343   if ( (myRepresentation == VrmlAPI_ShadedRepresentation || myRepresentation == VrmlAPI_BothRepresentation) && hasTriangles)
344     {
345       Vrml_Group Group1;
346       Group1.Print(outfile);
347       Vrml_Instancing I2 ("Shaded representation of shape");
348       I2.DEF(outfile);
349       VrmlConverter_ShadedShape::Add(outfile,aShape,myDrawer);
350       Group1.Print(outfile);
351     }
352   if (myRepresentation == VrmlAPI_WireFrameRepresentation || myRepresentation == VrmlAPI_BothRepresentation)
353     {
354       Vrml_Group Group2;
355       Group2.Print(outfile);
356       Vrml_Instancing I3 ("Wire Frame representation of shape");
357       I3.DEF(outfile);
358       VrmlConverter_WFDeflectionShape::Add(outfile,aShape,myDrawer);
359       Group2.Print(outfile);
360     }
361   S2.Print(outfile);
362   S1.Print(outfile);
363
364   outfile.close();
365   return outfile.good();
366 }
367
368 Standard_Boolean VrmlAPI_Writer::write_v2(const TopoDS_Shape& aShape,const Standard_CString aFile) const
369 {
370   Standard_Boolean anExtFace = Standard_False;
371   if(myRepresentation == VrmlAPI_ShadedRepresentation || myRepresentation == VrmlAPI_BothRepresentation) 
372     anExtFace = Standard_True;
373
374   Standard_Boolean anExtEdge = Standard_False;
375   if(myRepresentation == VrmlAPI_WireFrameRepresentation || myRepresentation == VrmlAPI_BothRepresentation)
376     anExtEdge = Standard_True;
377
378   VrmlData_Scene aScene;
379   VrmlData_ShapeConvert aConv(aScene);
380   aConv.AddShape(aShape);
381   aConv.Convert(anExtFace, anExtEdge);
382
383   std::ofstream anOutStream;
384   OSD_OpenStream(anOutStream, aFile, std::ios::out);
385   if (anOutStream)
386   {
387     anOutStream << aScene;
388     anOutStream.close();
389     return anOutStream.good();
390   }
391
392   return Standard_False;
393 }
394
395 //=======================================================================
396 //function : WriteDoc
397 //purpose  : 
398 //=======================================================================
399 Standard_Boolean VrmlAPI_Writer::WriteDoc(
400   const Handle(TDocStd_Document) &theDoc,
401   const Standard_CString theFile,
402   const Standard_Real theScale) const
403 {
404   VrmlData_Scene aScene;
405   VrmlData_ShapeConvert aConv(aScene, theScale);
406   aConv.ConvertDocument(theDoc);
407
408   std::ofstream anOutStream;
409   OSD_OpenStream(anOutStream, theFile, std::ios::out);
410   if (anOutStream)
411   {
412     anOutStream << aScene;
413     anOutStream.close();
414     return anOutStream.good();
415   }
416
417   return Standard_False;
418 }
419