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