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