0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / VrmlData / VrmlData_Geometry.cxx
1 // File:      VrmlData_Geometry.cxx
2 // Created:   25.05.06 17:07:37
3 // Author:    Alexander GRIGORIEV
4 // Copyright: Open Cascade 2006
5
6
7 #include <VrmlData_Scene.hxx>
8 #include <VrmlData_Coordinate.hxx>
9 #include <VrmlData_Color.hxx>
10 #include <VrmlData_Normal.hxx>
11 #include <VrmlData_TextureCoordinate.hxx>
12 #include <VrmlData_InBuffer.hxx>
13 #include <VrmlData_Box.hxx>
14 #include <VrmlData_Cone.hxx>
15 #include <VrmlData_Cylinder.hxx>
16 #include <VrmlData_Sphere.hxx>
17 #include <VrmlData_UnknownNode.hxx>
18 #include <BRepPrimAPI_MakeBox.hxx>
19 #include <BRepPrim_Cone.hxx>
20 #include <BRepPrim_Cylinder.hxx>
21 #include <BRepPrim_Sphere.hxx>
22 #include <BRepPrim_Builder.hxx>
23 #include <NCollection_Vector.hxx>
24 #include <Standard_ErrorHandler.hxx>
25
26 #ifdef WNT
27 #define _CRT_SECURE_NO_DEPRECATE
28 #pragma warning (disable:4996)
29 #endif
30
31 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Geometry, VrmlData_Node)
32 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Geometry, VrmlData_Node)
33 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Box, VrmlData_Geometry)
34 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Box, VrmlData_Geometry)
35 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Cone, VrmlData_Geometry)
36 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Cone, VrmlData_Geometry)
37 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Cylinder, VrmlData_Geometry)
38 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Cylinder, VrmlData_Geometry)
39 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Sphere, VrmlData_Geometry)
40 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Sphere, VrmlData_Geometry)
41 IMPLEMENT_STANDARD_HANDLE  (VrmlData_ArrayVec3d, VrmlData_Node)
42 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_ArrayVec3d, VrmlData_Node)
43 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Color, VrmlData_ArrayVec3d)
44 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Color, VrmlData_ArrayVec3d)
45 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Coordinate, VrmlData_ArrayVec3d)
46 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Coordinate, VrmlData_ArrayVec3d)
47 IMPLEMENT_STANDARD_HANDLE  (VrmlData_Normal, VrmlData_ArrayVec3d)
48 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Normal, VrmlData_ArrayVec3d)
49 IMPLEMENT_STANDARD_HANDLE  (VrmlData_TextureCoordinate, VrmlData_Node)
50 IMPLEMENT_STANDARD_RTTIEXT (VrmlData_TextureCoordinate, VrmlData_Node)
51
52 //=======================================================================
53 //function : Value
54 //purpose  : 
55 //=======================================================================
56
57 const gp_XYZ& VrmlData_ArrayVec3d::Value (const Standard_Integer i) const
58 {
59   size_t anIndex = (size_t)i;
60   if  (anIndex < 0 || anIndex >= myLength) {
61     static gp_XYZ anOrigin (0., 0., 0.);
62     return anOrigin;
63   }
64   return myArray[i];
65 }
66
67 //=======================================================================
68 //function : AllocateValues
69 //purpose  : 
70 //=======================================================================
71
72 Standard_Boolean VrmlData_ArrayVec3d::AllocateValues
73                                 (const Standard_Size theLength)
74 {
75   myArray = reinterpret_cast <const gp_XYZ *>
76     (Scene().Allocator()->Allocate (theLength*sizeof(gp_XYZ)));
77   myLength = theLength;
78   return (myArray != 0L);
79 }
80
81 //=======================================================================
82 //function : VrmlData_Box::TShape
83 //purpose  : 
84 //=======================================================================
85
86 const Handle(TopoDS_TShape)& VrmlData_Box::TShape ()
87 {
88   if (myIsModified) {
89     try {
90       const TopoDS_Shell aShell =
91         BRepPrimAPI_MakeBox (gp_Pnt (-0.5 * mySize),
92                              mySize.X(), mySize.Y(), mySize.Z());
93       SetTShape (aShell.TShape());
94       myIsModified = Standard_False;
95     } catch (Standard_Failure) {
96       myTShape.Nullify();
97     }
98   }
99   return myTShape;
100 }
101
102 //=======================================================================
103 //function : VrmlData_Box::Clone
104 //purpose  : 
105 //=======================================================================
106
107 Handle(VrmlData_Node) VrmlData_Box::Clone
108                                 (const Handle(VrmlData_Node)& theOther) const
109 {
110   Handle(VrmlData_Box) aResult =
111     Handle(VrmlData_Box)::DownCast (VrmlData_Node::Clone(theOther));
112   if (aResult.IsNull())
113     aResult = new VrmlData_Box (theOther.IsNull() ? Scene() : theOther->Scene(),
114                                 Name());
115   aResult->SetSize(mySize);
116   return aResult;
117 }
118
119 //=======================================================================
120 //function : VrmlData_Box::Read
121 //purpose  : 
122 //=======================================================================
123
124 VrmlData_ErrorStatus VrmlData_Box::Read (VrmlData_InBuffer& theBuffer)
125 {
126   VrmlData_ErrorStatus aStatus;
127   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
128     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "size"))
129       aStatus = Scene().ReadXYZ (theBuffer, mySize,
130                                  Standard_True, Standard_True);
131     if (OK(aStatus))
132       aStatus = readBrace (theBuffer);
133   }
134   return aStatus;
135 }
136
137 //=======================================================================
138 //function : VrmlData_Box::Write
139 //purpose  : 
140 //=======================================================================
141
142 VrmlData_ErrorStatus VrmlData_Box::Write (const char * thePrefix) const
143 {
144   static char header[] = "Box {";
145   VrmlData_ErrorStatus aStatus;
146   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
147   {
148     char buf[128];
149     sprintf (buf, "size %.12g %.12g %.12g", mySize.X(), mySize.Y(), mySize.Z());
150     Scene().WriteLine (buf);
151     aStatus = WriteClosing();
152   }
153   return aStatus;
154 }
155
156 //=======================================================================
157 //function : VrmlData_Cone::TShape
158 //purpose  : 
159 //=======================================================================
160
161 const Handle(TopoDS_TShape)& VrmlData_Cone::TShape ()
162 {
163   if (myIsModified && (myHasBottom || myHasSide)) {
164     try {
165       gp_Ax2 aLocalAxis (gp_Pnt (0., -0.5 * myHeight, 0.),
166                          gp_Dir (0., 1., 0.));
167       BRepPrim_Cone aBuilder (aLocalAxis, myBottomRadius, 0., myHeight);
168       if (!myHasBottom)
169         myTShape = aBuilder.LateralFace().TShape();
170       else if (!myHasSide) 
171         myTShape = aBuilder.BottomFace().TShape();
172       else
173         myTShape = aBuilder.Shell().TShape();
174       myIsModified = Standard_False;
175     } catch (Standard_Failure) {
176       myTShape.Nullify();
177     }
178   }
179   return myTShape;
180 }
181
182 //=======================================================================
183 //function : VrmlData_Cone::Clone
184 //purpose  : 
185 //=======================================================================
186
187 Handle(VrmlData_Node) VrmlData_Cone::Clone
188                                 (const Handle(VrmlData_Node)& theOther) const
189 {
190   Handle(VrmlData_Cone) aResult =
191     Handle(VrmlData_Cone)::DownCast (VrmlData_Node::Clone(theOther));
192   if (aResult.IsNull())
193     aResult = new VrmlData_Cone (theOther.IsNull() ? Scene(): theOther->Scene(),
194                                 Name());
195
196   aResult->SetBottomRadius (myBottomRadius);
197   aResult->SetHeight (myHeight);
198   aResult->SetFaces (myHasBottom, myHasSide);
199   return aResult;
200 }
201
202 //=======================================================================
203 //function : VrmlData_Cone::Read
204 //purpose  : 
205 //=======================================================================
206
207 VrmlData_ErrorStatus VrmlData_Cone::Read (VrmlData_InBuffer& theBuffer)
208 {
209   VrmlData_ErrorStatus aStatus;
210   Standard_Boolean hasSide(Standard_True), hasBottom(Standard_True);
211
212   while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
213   {
214     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "bottomRadius"))
215       aStatus = Scene().ReadReal (theBuffer, myBottomRadius,
216                                   Standard_True, Standard_True);
217     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "height"))
218       aStatus = Scene().ReadReal (theBuffer, myHeight,
219                                   Standard_True, Standard_True);
220     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "side")) {
221       if (OK(aStatus, ReadBoolean (theBuffer, hasSide)))
222         myHasSide = hasSide;
223     } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "bottom")) {
224       if (OK(aStatus, ReadBoolean (theBuffer, hasBottom)))
225         myHasBottom = hasBottom;
226     } else
227       break;
228
229     if (!OK(aStatus))
230       break;
231   }
232   // Read the terminating (closing) brace
233   if (OK(aStatus))
234     aStatus = readBrace (theBuffer);
235   return aStatus;
236 }
237
238 //=======================================================================
239 //function : VrmlData_Cone::Write
240 //purpose  : 
241 //=======================================================================
242
243 VrmlData_ErrorStatus VrmlData_Cone::Write (const char * thePrefix) const
244 {
245   static char header[] = "Cone {";
246   VrmlData_ErrorStatus aStatus;
247   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
248   {
249     char buf[128];
250     if ((myBottomRadius - 1.)*(myBottomRadius - 1.) > Precision::Confusion()) {
251       sprintf (buf, "bottomRadius %.12g", myBottomRadius);
252       aStatus = Scene().WriteLine (buf);
253     }
254     if (OK(aStatus) &&
255         (myHeight - 2.)*(myHeight - 2.) > Precision::Confusion()) {
256       sprintf (buf, "height       %.12g", myHeight);
257       aStatus = Scene().WriteLine (buf);
258     }
259     if (OK(aStatus) && myHasBottom == Standard_False)
260       aStatus = Scene().WriteLine ("bottom   FALSE");
261     if (OK(aStatus) && myHasSide == Standard_False)
262       aStatus = Scene().WriteLine ("side     FALSE");
263
264     aStatus = WriteClosing();
265   }
266   return aStatus;
267 }
268
269 //=======================================================================
270 //function : VrmlData_Cone::IsDefault
271 //purpose  : 
272 //=======================================================================
273
274 // Standard_Boolean VrmlData_Cone::IsDefault () const
275 // {
276 //   return
277 //     (myHasBottom && myHasSide &&
278 //      ((myBottomRadius - 1.)*(myBottomRadius-1.) < Precision::Confusion()) &&
279 //      ((myHeight - 2.)*(myHeight - 2.) < Precision::Confusion()));
280 // }
281
282 //=======================================================================
283 //function : VrmlData_Cylinder::TShape
284 //purpose  : 
285 //=======================================================================
286
287 const Handle(TopoDS_TShape)& VrmlData_Cylinder::TShape ()
288 {
289   if (myIsModified && (myHasBottom || myHasSide || myHasTop)) {
290     try {
291       gp_Ax2 aLocalAxis (gp_Pnt (0., -0.5 * myHeight, 0.),
292                          gp_Dir (0., 1., 0.));
293       BRepPrim_Cylinder aBuilder (aLocalAxis, myRadius, myHeight);
294       BRepPrim_Builder aShapeBuilder;
295       TopoDS_Shell aShell;
296       aShapeBuilder.MakeShell(aShell);
297       if (myHasSide)
298         aShapeBuilder.AddShellFace (aShell, aBuilder.LateralFace());
299       if (myHasTop)
300         aShapeBuilder.AddShellFace (aShell, aBuilder.TopFace());
301       if (myHasBottom)
302         aShapeBuilder.AddShellFace (aShell, aBuilder.BottomFace());
303       myTShape = aShell.TShape();
304       myIsModified = Standard_False;
305     } catch (Standard_Failure) {
306       myTShape.Nullify();
307     }
308   }
309   return myTShape;
310 }
311
312 //=======================================================================
313 //function : VrmlData_Cylinder::Clone
314 //purpose  : 
315 //=======================================================================
316
317 Handle(VrmlData_Node) VrmlData_Cylinder::Clone
318                                 (const Handle(VrmlData_Node)& theOther) const
319 {
320   Handle(VrmlData_Cylinder) aResult =
321     Handle(VrmlData_Cylinder)::DownCast (VrmlData_Node::Clone(theOther));
322   if (aResult.IsNull())
323     aResult = new VrmlData_Cylinder(theOther.IsNull()?Scene():theOther->Scene(),
324                                     Name());
325   aResult->SetRadius (myRadius);
326   aResult->SetHeight (myHeight);
327   aResult->SetFaces  (myHasBottom, myHasSide, myHasTop);
328   return aResult;
329 }
330
331 //=======================================================================
332 //function : VrmlData_Cylinder::Read
333 //purpose  : 
334 //=======================================================================
335
336 VrmlData_ErrorStatus VrmlData_Cylinder::Read (VrmlData_InBuffer& theBuffer)
337 {
338   VrmlData_ErrorStatus aStatus;
339   Standard_Boolean hasSide(Standard_True), hasBottom(Standard_True);
340   Standard_Boolean hasTop (Standard_True);
341
342   while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
343   {
344     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "radius"))
345       aStatus = Scene().ReadReal (theBuffer, myRadius,
346                                   Standard_True, Standard_True);
347     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "height"))
348       aStatus = Scene().ReadReal (theBuffer, myHeight,
349                                   Standard_True, Standard_True);
350     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "top")) {
351       if (OK(aStatus, ReadBoolean (theBuffer, hasTop)))
352         myHasTop = hasTop;
353     } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "side")) {
354       if (OK(aStatus, ReadBoolean (theBuffer, hasSide)))
355         myHasSide = hasSide;
356     } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "bottom")) {
357       if (OK(aStatus, ReadBoolean (theBuffer, hasBottom)))
358         myHasBottom = hasBottom;
359     } else
360       break;
361
362     if (!OK(aStatus))
363       break;
364   }
365
366   // Read the terminating (closing) brace
367   if (OK(aStatus))
368     aStatus = readBrace (theBuffer);
369   return aStatus;
370 }
371
372 //=======================================================================
373 //function : VrmlData_Cylinder::Write
374 //purpose  : 
375 //=======================================================================
376
377 VrmlData_ErrorStatus VrmlData_Cylinder::Write (const char * thePrefix) const
378 {
379   static char header[] = "Cylinder {";
380   VrmlData_ErrorStatus aStatus;
381   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
382   {
383     char buf[128];
384     if ((myRadius - 1.)*(myRadius - 1.) > Precision::Confusion()) {
385       sprintf (buf, "radius   %.12g", myRadius);
386       aStatus = Scene().WriteLine (buf);
387     }
388     if (OK(aStatus) &&
389         (myHeight - 2.)*(myHeight - 2.) > Precision::Confusion()) {
390       sprintf (buf, "height   %.12g", myHeight);
391       aStatus = Scene().WriteLine (buf);
392     }
393     if (OK(aStatus) && myHasBottom == Standard_False)
394       aStatus = Scene().WriteLine ("bottom   FALSE");
395     if (OK(aStatus) && myHasSide == Standard_False)
396       aStatus = Scene().WriteLine ("side     FALSE");
397     if (OK(aStatus) && myHasTop == Standard_False)
398       aStatus = Scene().WriteLine ("top      FALSE");
399
400     aStatus = WriteClosing();
401   }
402   return aStatus;
403 }
404
405 //=======================================================================
406 //function : VrmlData_Cylinder::IsDefault
407 //purpose  : 
408 //=======================================================================
409
410 // Standard_Boolean VrmlData_Cylinder::IsDefault () const
411 // {
412 //   return
413 //     (myHasBottom && myHasSide && myHasTop &&
414 //      ((myRadius - 1.)*(myRadius - 1.) < Precision::Confusion()) &&
415 //      ((myHeight - 2.)*(myHeight - 2.) < Precision::Confusion()));
416 // }
417
418 //=======================================================================
419 //function : VrmlData_Sphere::TShape
420 //purpose  : 
421 //=======================================================================
422
423 const Handle(TopoDS_TShape)& VrmlData_Sphere::TShape ()
424 {
425   if (myIsModified) {
426     try {
427       myTShape = BRepPrim_Sphere(myRadius).Shell().TShape();
428       myIsModified = Standard_False;
429     } catch (Standard_Failure) {
430       myTShape.Nullify();
431     }
432   }
433   return myTShape;
434 }
435
436 //=======================================================================
437 //function : VrmlData_Sphere::Clone
438 //purpose  : 
439 //=======================================================================
440
441 Handle(VrmlData_Node) VrmlData_Sphere::Clone
442                                 (const Handle(VrmlData_Node)& theOther) const
443 {
444   Handle(VrmlData_Sphere) aResult =
445     Handle(VrmlData_Sphere)::DownCast (VrmlData_Node::Clone(theOther));
446   if (aResult.IsNull())
447     aResult = new VrmlData_Sphere(theOther.IsNull()? Scene() :theOther->Scene(),
448                                   Name());
449   aResult->SetRadius (myRadius);
450   return aResult;
451 }
452
453 //=======================================================================
454 //function : VrmlData_Sphere::Read
455 //purpose  : 
456 //=======================================================================
457
458 VrmlData_ErrorStatus VrmlData_Sphere::Read (VrmlData_InBuffer& theBuffer)
459 {
460   VrmlData_ErrorStatus aStatus;
461   while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
462     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "radius"))
463       aStatus = Scene().ReadReal (theBuffer, myRadius,
464                                   Standard_True, Standard_True);
465     else
466       break;
467
468   // Read the terminating (closing) brace
469   if (OK(aStatus))
470     aStatus = readBrace (theBuffer);
471   return aStatus;
472 }
473
474 //=======================================================================
475 //function : VrmlData_Sphere::Write
476 //purpose  : 
477 //=======================================================================
478
479 VrmlData_ErrorStatus VrmlData_Sphere::Write (const char * thePrefix) const
480 {
481   static char header[] = "Sphere {";
482   VrmlData_ErrorStatus aStatus;
483   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
484   {
485     char buf[128];
486     sprintf (buf, "radius   %.12g", myRadius);
487     Scene().WriteLine (buf);
488     aStatus = WriteClosing();
489   }
490   return aStatus;
491 }
492
493 //=======================================================================
494 //function : VrmlData_Sphere::IsDefault
495 //purpose  : 
496 //=======================================================================
497
498 // Standard_Boolean VrmlData_Sphere::IsDefault () const
499 // {
500 //   return ((myRadius - 1.)*(myRadius - 1.) < Precision::Confusion())
501 // }
502
503 //=======================================================================
504 //function : VrmlData_TextureCoordinate::AllocateValues
505 //purpose  : 
506 //=======================================================================
507
508 Standard_Boolean VrmlData_TextureCoordinate::AllocateValues
509                                 (const Standard_Size theLength)
510 {
511   myPoints = reinterpret_cast <const gp_XY *>
512     (Scene().Allocator()->Allocate (theLength*sizeof(gp_XY)));
513   myLength = theLength;
514   return (myPoints != 0L);
515 }
516
517 //=======================================================================
518 //function : VrmlData_TextureCoordinate::Clone
519 //purpose  : 
520 //=======================================================================
521
522 Handle(VrmlData_Node) VrmlData_TextureCoordinate::Clone
523                                 (const Handle(VrmlData_Node)& theOther) const
524 {
525   Handle(VrmlData_TextureCoordinate) aResult =
526     Handle(VrmlData_TextureCoordinate)::DownCast
527     (VrmlData_Node::Clone(theOther));
528   if (aResult.IsNull())
529     aResult = new VrmlData_TextureCoordinate
530       (theOther.IsNull() ? Scene() : theOther->Scene(), Name());
531   if (&aResult->Scene() == &Scene())
532     aResult->SetPoints (myLength, myPoints);
533   else {
534     aResult->AllocateValues (myLength);
535     for (Standard_Size i = 0; i < myLength; i++)
536       const_cast <gp_XY&> (aResult->myPoints[i]) = myPoints[i];
537   }
538   return aResult;
539 }
540
541 //=======================================================================
542 //function : VrmlData_TextureCoordinate::Read
543 //purpose  : 
544 //=======================================================================
545
546 VrmlData_ErrorStatus VrmlData_TextureCoordinate::Read
547                                         (VrmlData_InBuffer& theBuffer)
548 {
549   VrmlData_ErrorStatus aStatus;
550   NCollection_Vector<gp_XY> vecValues;
551   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
552     // Match the name with the current word in the stream
553     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "point"))
554       // Read the body of the data node (comma-separated list of duplets)
555       if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
556         if (theBuffer.LinePtr[0] != '[')  // opening bracket
557           aStatus = VrmlData_VrmlFormatError;
558         else {
559           theBuffer.LinePtr++;
560           while (~0) {
561             gp_XY anXY;
562             if (!OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
563               break;
564             // closing bracket, in case that it follows a comma
565             if (theBuffer.LinePtr[0] == ']') {
566               theBuffer.LinePtr++;
567               break;
568             }
569             if (!OK(aStatus, Scene().ReadXY(theBuffer, anXY,
570                                             Standard_False, Standard_False)))
571               break;
572             vecValues.Append(anXY);
573             if (!OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
574               break;
575             if (theBuffer.LinePtr[0] == ',') {
576               theBuffer.LinePtr++;
577               continue;
578             } else if (theBuffer.LinePtr[0] == ']') // closing bracket
579               theBuffer.LinePtr++;
580             else
581               aStatus = VrmlData_VrmlFormatError;
582             break;
583           }
584         }
585     if (OK(aStatus) && OK(aStatus, readBrace (theBuffer))) {
586       myLength = vecValues.Length();
587       if (myLength > 0) {
588         gp_XY * aPoints = reinterpret_cast <gp_XY *>
589           (Scene().Allocator()->Allocate (myLength * sizeof(gp_XY)));
590         myPoints = aPoints;
591         for (Standard_Integer i = 0; i < Standard_Integer(myLength); i++)
592           aPoints[i] = vecValues(i);
593       }
594     }
595   }
596   return aStatus;
597 }
598
599 //=======================================================================
600 //function : VrmlData_ArrayVec3d::Clone
601 //purpose  : 
602 //=======================================================================
603
604 // Handle(VrmlData_Node) VrmlData_ArrayVec3d::Clone
605 //                                 (const Handle(VrmlData_Node)& theOther) const
606 // {
607 //   VrmlData_Node::Clone (theOther);
608 //   const Handle(VrmlData_ArrayVec3d) anArrayNode =
609 //     Handle(VrmlData_ArrayVec3d)::DownCast (theOther);
610 //   if (anArrayNode.IsNull() == Standard_False)
611 //     anArrayNode->SetValues (myLength, myArray);
612 //   return theOther;
613 // }
614
615 //=======================================================================
616 //function : VrmlData_ArrayVec3d::ReadArray
617 //purpose  : 
618 //=======================================================================
619
620 VrmlData_ErrorStatus VrmlData_ArrayVec3d::ReadArray
621                                         (VrmlData_InBuffer&     theBuffer,
622                                          const char *           theName,
623                                          const Standard_Boolean isScale)
624 {
625   VrmlData_ErrorStatus aStatus;
626   NCollection_Vector<gp_XYZ> vecValues;
627   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
628     // Match the name with the current word in the stream
629     if (theName) {
630       const Standard_Integer aNameLen = strlen(theName);
631       if (strncmp (theBuffer.LinePtr, theName, aNameLen))
632         aStatus = VrmlData_VrmlFormatError;
633       else
634         theBuffer.LinePtr += aNameLen;
635     } else {
636       // Skip the word in the input
637       while (theBuffer.LinePtr[0] != ' ' &&
638              theBuffer.LinePtr[0] != ',' &&
639              theBuffer.LinePtr[0] != '\t' &&
640              theBuffer.LinePtr[0] != '\n' &&
641              theBuffer.LinePtr[0] != '\r' &&
642              theBuffer.LinePtr[0] != '\0')
643         theBuffer.LinePtr++;
644     }
645     // Read the body of the data node (list of triplets)
646     if (OK(aStatus) && OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
647       if (theBuffer.LinePtr[0] != '[')  // opening bracket
648         aStatus = VrmlData_VrmlFormatError;
649       else {
650         theBuffer.LinePtr++;
651         while (~0) {
652           gp_XYZ anXYZ;
653           if (!OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
654             break;
655           // closing bracket, in case that it follows a comma
656           if (theBuffer.LinePtr[0] == ']') {
657             theBuffer.LinePtr++;
658             break;
659           }
660           // Read three numbers (XYZ value)
661           if (!OK(aStatus, Scene().ReadXYZ(theBuffer, anXYZ,
662                                            isScale, Standard_False)))
663             break;
664           vecValues.Append(anXYZ);
665           if (!OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
666             break;
667           if (theBuffer.LinePtr[0] == ']') {// closing bracket
668             theBuffer.LinePtr++;
669             break;
670           }
671         }
672       }
673     if (OK(aStatus) && OK(aStatus, readBrace (theBuffer))) {
674       myLength = vecValues.Length();
675       if (myLength > 0) {
676         gp_XYZ * anArray = reinterpret_cast <gp_XYZ *>
677           (Scene().Allocator()->Allocate (myLength * sizeof(gp_XYZ)));
678         myArray = anArray;
679         for (Standard_Integer i = 0; i < Standard_Integer(myLength); i++)
680           anArray[i] = vecValues(i);
681       }
682     }
683   }
684   return aStatus;
685 }
686
687 //=======================================================================
688 //function : VrmlData_ArrayVec3d::WriteArray
689 //purpose  : 
690 //=======================================================================
691
692 VrmlData_ErrorStatus VrmlData_ArrayVec3d::WriteArray
693                                         (const char *           theName,
694                                          const Standard_Boolean isScale) const
695 {
696   VrmlData_ErrorStatus aStatus (VrmlData_StatusOK);
697   if (myLength > 0) {
698     aStatus = Scene().WriteLine (theName, "[", 2*GlobalIndent());
699     if (OK(aStatus)) {
700       for (Standard_Size i = 0; i < myLength-1; i++)
701         if (!OK (aStatus, Scene().WriteXYZ (myArray[i], isScale, ",")))
702           break;
703       if (OK(aStatus))
704         aStatus = Scene().WriteXYZ (myArray[myLength-1], isScale);
705     }
706     if (aStatus == VrmlData_StatusOK)
707       aStatus = Scene().WriteLine ("]", 0L, -2*GlobalIndent());
708   }
709   return aStatus;
710 }
711
712 //=======================================================================
713 //function : VrmlData_ArrayVec3d::IsDefault
714 //purpose  : 
715 //=======================================================================
716
717 Standard_Boolean VrmlData_ArrayVec3d::IsDefault () const
718 {
719   return myLength == 0;
720 }
721
722 //=======================================================================
723 //function : VrmlData_Coodinate::Clone
724 //purpose  : 
725 //=======================================================================
726
727 Handle(VrmlData_Node) VrmlData_Coordinate::Clone
728                                 (const Handle(VrmlData_Node)& theOther) const
729 {
730   Handle(VrmlData_Coordinate) aResult =
731     Handle(VrmlData_Coordinate)::DownCast (VrmlData_Node::Clone(theOther));
732   if (aResult.IsNull())
733     aResult = new VrmlData_Coordinate
734       (theOther.IsNull() ? Scene() : theOther->Scene(), Name());
735   if (&aResult->Scene() == &Scene())
736     aResult->SetValues (Length(), Values());
737   else {
738     aResult->AllocateValues (Length());
739     for (Standard_Size i = 0; i < Length(); i++)
740       const_cast <gp_XYZ&> (aResult->Values()[i]) = Values()[i];
741   }
742   return aResult;
743 }
744
745 //=======================================================================
746 //function : VrmlData_Coordinate::Read
747 //purpose  : 
748 //=======================================================================
749
750 VrmlData_ErrorStatus VrmlData_Coordinate::Read (VrmlData_InBuffer& theBuffer)
751 {
752   return VrmlData_ArrayVec3d::ReadArray (theBuffer, "point", Standard_True);
753 }
754
755 //=======================================================================
756 //function : VrmlData_Coordinate::Write
757 //purpose  : 
758 //=======================================================================
759
760 VrmlData_ErrorStatus VrmlData_Coordinate::Write (const char * thePrefix) const
761 {
762   static char header[] = "Coordinate {";
763   VrmlData_ErrorStatus aStatus;
764   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
765   {
766     WriteArray ("point", Standard_True);
767     aStatus = WriteClosing();
768   }
769   return aStatus;
770 }
771
772 //=======================================================================
773 //function : VrmlData_Color::Clone
774 //purpose  : 
775 //=======================================================================
776
777 Handle(VrmlData_Node) VrmlData_Color::Clone
778                                 (const Handle(VrmlData_Node)& theOther) const
779 {
780   Handle(VrmlData_Color) aResult =
781     Handle(VrmlData_Color)::DownCast (VrmlData_Node::Clone(theOther));
782   if (aResult.IsNull())
783     aResult = new VrmlData_Color(theOther.IsNull()? Scene() : theOther->Scene(),
784                                  Name());
785   if (&aResult->Scene() == &Scene())
786     aResult->SetValues (Length(), Values());
787   else {
788     aResult->AllocateValues (Length());
789     for (Standard_Size i = 0; i < Length(); i++)
790       const_cast <gp_XYZ&> (aResult->Values()[i]) = Values()[i];
791   }
792   return aResult;
793 }
794
795 //=======================================================================
796 //function : VrmlData_Color::Read
797 //purpose  : 
798 //=======================================================================
799
800 VrmlData_ErrorStatus VrmlData_Color::Read (VrmlData_InBuffer& theBuffer)
801 {
802   return ReadArray (theBuffer, "color", Standard_False);
803 }
804
805 //=======================================================================
806 //function : VrmlData_Color::Write
807 //purpose  : 
808 //=======================================================================
809
810 VrmlData_ErrorStatus VrmlData_Color::Write (const char * thePrefix) const
811 {
812   static char header[] = "Color {";
813   VrmlData_ErrorStatus aStatus;
814   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
815   {
816     WriteArray ("color", Standard_False);
817     aStatus = WriteClosing();
818   }
819   return aStatus;
820 }
821
822 //=======================================================================
823 //function : VrmlData_Normal::Clone
824 //purpose  : 
825 //=======================================================================
826
827 Handle(VrmlData_Node) VrmlData_Normal::Clone
828                                 (const Handle(VrmlData_Node)& theOther) const
829 {
830   Handle(VrmlData_Normal) aResult =
831     Handle(VrmlData_Normal)::DownCast (VrmlData_Node::Clone(theOther));
832   if (aResult.IsNull())
833     aResult= new VrmlData_Normal(theOther.IsNull()? Scene() : theOther->Scene(),
834                                  Name());
835   if (&aResult->Scene() == &Scene())
836     aResult->SetValues (Length(), Values());
837   else {
838     aResult->AllocateValues (Length());
839     for (Standard_Size i = 0; i < Length(); i++)
840       const_cast <gp_XYZ&> (aResult->Values()[i]) = Values()[i];
841   }
842   return aResult;
843 }
844
845 //=======================================================================
846 //function : VrmlData_Normal::Read
847 //purpose  : 
848 //=======================================================================
849
850 VrmlData_ErrorStatus VrmlData_Normal::Read (VrmlData_InBuffer& theBuffer)
851 {
852   return VrmlData_ArrayVec3d::ReadArray (theBuffer, "vector", Standard_False);
853 }
854
855 //=======================================================================
856 //function : VrmlData_Normal::Write
857 //purpose  : 
858 //=======================================================================
859
860 VrmlData_ErrorStatus VrmlData_Normal::Write (const char * thePrefix) const
861 {
862   static char header[] = "Normal {";
863   VrmlData_ErrorStatus aStatus;
864   if (OK (aStatus, Scene().WriteLine (thePrefix, header, GlobalIndent())))
865   {
866     WriteArray ("vector", Standard_False);
867     aStatus = WriteClosing();
868   }
869   return aStatus;
870 }