1 // Created on: 2006-05-25
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2006-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15 
16 #include <Precision.hxx>
17 #include <VrmlData_Appearance.hxx>
18 #include <VrmlData_ImageTexture.hxx>
19 #include <VrmlData_Material.hxx>
20 #include <VrmlData_ShapeNode.hxx>
21 #include <VrmlData_UnknownNode.hxx>
22 #include <VrmlData_Scene.hxx>
23 #include <VrmlData_InBuffer.hxx>
24 #include <gp_XY.hxx>
25 #include <gp_XYZ.hxx>
26 #include <VrmlData_Geometry.hxx>
27 #include <VrmlData_TextureTransform.hxx>
28 #include <VrmlData_Texture.hxx>
29 
30 IMPLEMENT_STANDARD_RTTIEXT(VrmlData_Node,Standard_Transient)
31 
32 #ifdef _MSC_VER
33 #define _CRT_SECURE_NO_DEPRECATE
34 #pragma warning (disable:4996)
35 #endif
36 
37 static VrmlData_Scene MyDefaultScene;
38 
39 //=======================================================================
40 //function : IsEqual
41 //purpose  : Global method
42 //=======================================================================
43 
IsEqual(const Handle (VrmlData_Node)& theOne,const Handle (VrmlData_Node)& theTwo)44 Standard_Boolean IsEqual (const Handle(VrmlData_Node)& theOne,
45                           const Handle(VrmlData_Node)& theTwo)
46 {
47   Standard_Boolean aResult (Standard_False);
48   if (theOne->Name() != 0L && theTwo->Name() != 0L)
49     aResult = (strcmp (theOne->Name(), theTwo->Name()) == 0);
50   return aResult;
51 }
52 
53 //=======================================================================
54 // function : HashCode
55 // purpose  : Global method
56 //=======================================================================
HashCode(const Handle (VrmlData_Node)& theNode,const Standard_Integer theUpperBound)57 Standard_Integer HashCode (const Handle (VrmlData_Node) & theNode, const Standard_Integer theUpperBound)
58 {
59   return (theNode->Name () == NULL ? 1 : HashCode (theNode->Name (), theUpperBound));
60 }
61 
62 //=======================================================================
63 //function : VrmlData_Node
64 //purpose  :
65 //=======================================================================
66 
VrmlData_Node()67 VrmlData_Node::VrmlData_Node ()
68   : myScene (&MyDefaultScene),
69     myName  (0L) {}
70 
71 //=======================================================================
72 //function : VrmlData_Node
73 //purpose  : Constructor
74 //=======================================================================
75 
VrmlData_Node(const VrmlData_Scene & theScene,const char * theName)76 VrmlData_Node::VrmlData_Node (const VrmlData_Scene& theScene,
77                               const char            * theName)
78   : myScene   (&theScene)
79 {
80   if (theName == 0L)
81     theName = "";
82   setName (theName);
83 }
84 
85 //=======================================================================
86 //function : Clone
87 //purpose  : Create a copy of this node.
88 //=======================================================================
89 
Handle(VrmlData_Node)90 Handle(VrmlData_Node) VrmlData_Node::Clone
91                                 (const Handle(VrmlData_Node)& theOther) const
92 {
93   if (theOther.IsNull() == Standard_False) {
94     if (theOther->IsKind (DynamicType()) == Standard_False)
95       return NULL;
96     if (&theOther->Scene() == myScene)
97       theOther->myName = myName;
98     else
99       theOther->setName (myName);
100   }
101   return theOther;
102 }
103 
104 //=======================================================================
105 //function : setName
106 //purpose  :
107 //=======================================================================
108 
setName(const char * theName,const char * theSuffix)109 void VrmlData_Node::setName (const char * theName, const char * theSuffix)
110 {
111   size_t len[2] = {
112     strlen(theName) + 1,
113     0
114   };
115   if (theSuffix)
116     len[1] = strlen (theSuffix);
117   char * aName = (char *)Scene().Allocator()->Allocate(len[0]+len[1]);
118   myName = aName;
119   memcpy (aName, theName, len[0]);
120   if (len[1])
121     memcpy (&aName[len[0] - 1], theSuffix, len[1]+1);
122 }
123 
124 //=======================================================================
125 //function : IsDefault
126 //purpose  :
127 //=======================================================================
128 
IsDefault() const129 Standard_Boolean VrmlData_Node::IsDefault () const
130 {
131   return Standard_False;
132 }
133 
134 
135 //=======================================================================
136 //function : Write
137 //purpose  :
138 //=======================================================================
139 
Write(const char *) const140 VrmlData_ErrorStatus VrmlData_Node::Write (const char *) const
141 {
142   return VrmlData_NotImplemented;
143 }
144 
145 //=======================================================================
146 //function : WriteClosing
147 //purpose  :
148 //=======================================================================
149 
WriteClosing() const150 VrmlData_ErrorStatus VrmlData_Node::WriteClosing () const
151 {
152   VrmlData_ErrorStatus aResult = Scene().Status();
153   if (aResult == VrmlData_StatusOK || aResult == VrmlData_NotImplemented)
154     aResult = Scene().WriteLine ("}", 0L, -GlobalIndent());
155   return aResult;
156 }
157 
158 //=======================================================================
159 //function : readBrace
160 //purpose  :
161 //=======================================================================
162 
readBrace(VrmlData_InBuffer & theBuffer)163 VrmlData_ErrorStatus VrmlData_Node::readBrace (VrmlData_InBuffer& theBuffer)
164 {
165   VrmlData_ErrorStatus aStatus;
166   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
167     if (theBuffer.LinePtr[0] == '}')
168       theBuffer.LinePtr++;
169     else
170       aStatus = VrmlData_VrmlFormatError;
171   }
172   return aStatus;
173 }
174 
175 //=======================================================================
176 //function : ReadBoolean
177 //purpose  :
178 //=======================================================================
179 
ReadBoolean(VrmlData_InBuffer & theBuffer,Standard_Boolean & theResult)180 VrmlData_ErrorStatus VrmlData_Node::ReadBoolean (VrmlData_InBuffer& theBuffer,
181                                                  Standard_Boolean&  theResult)
182 {
183   VrmlData_ErrorStatus aStatus;
184   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
185     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "TRUE"))
186       theResult = Standard_True;
187     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "FALSE"))
188       theResult = Standard_False;
189     else
190       aStatus = VrmlData_BooleanInputError;
191   }
192   return aStatus;
193 }
194 
195 //=======================================================================
196 //function : ReadInteger
197 //purpose  :
198 //=======================================================================
199 
ReadInteger(VrmlData_InBuffer & theBuffer,long & theResult)200 VrmlData_ErrorStatus VrmlData_Node::ReadInteger (VrmlData_InBuffer& theBuffer,
201                                                  long&              theResult)
202 {
203   VrmlData_ErrorStatus aStatus;
204   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
205     char * endptr;
206     long aResult;
207     aResult = strtol (theBuffer.LinePtr, &endptr, 10);
208     if (endptr == theBuffer.LinePtr)
209       aStatus = VrmlData_NumericInputError;
210     else {
211       theResult = aResult;
212       theBuffer.LinePtr = endptr;
213     }
214   }
215   return aStatus;
216 }
217 
218 //=======================================================================
219 //function : ReadString
220 //purpose  :
221 //=======================================================================
222 
ReadString(VrmlData_InBuffer & theBuffer,TCollection_AsciiString & theResult)223 VrmlData_ErrorStatus VrmlData_Node::ReadString
224                                 (VrmlData_InBuffer& theBuffer,
225                                  TCollection_AsciiString&  theResult)
226 {
227   VrmlData_ErrorStatus aStatus;
228   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
229     if (theBuffer.LinePtr[0] != '\"')
230       aStatus = VrmlData_StringInputError;
231     else {
232       char * ptr = &theBuffer.LinePtr[1];
233       while (*ptr != '\0' && *ptr != '\"')
234         ptr++;
235       if (*ptr == '\0')
236         aStatus = VrmlData_StringInputError;
237       else {
238         *ptr = '\0';
239         theResult = (Standard_CString) &theBuffer.LinePtr[1];
240         theBuffer.LinePtr = ptr+1;
241       }
242     }
243   }
244   return aStatus;
245 }
246 
247 //=======================================================================
248 //function : ReadMultiString
249 //purpose  :
250 //=======================================================================
251 
ReadMultiString(VrmlData_InBuffer & theBuffer,NCollection_List<TCollection_AsciiString> & theResult)252 VrmlData_ErrorStatus VrmlData_Node::ReadMultiString
253                         (VrmlData_InBuffer&                         theBuffer,
254                          NCollection_List<TCollection_AsciiString>& theResult)
255 {
256   VrmlData_ErrorStatus aStatus;
257   Standard_Boolean isBracketed (Standard_False);
258   // Read the list of URL
259   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
260     if (theBuffer.LinePtr[0] == '[') {
261       theBuffer.LinePtr++;
262       isBracketed = Standard_True;
263     }
264     while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
265       if (isBracketed && theBuffer.LinePtr[0] == ']') { // closing bracket
266         theBuffer.LinePtr++;
267         break;
268       }
269       TCollection_AsciiString aString;
270       if (!OK(aStatus, ReadString(theBuffer, aString)))
271         break;
272       theResult.Append(aString);
273       if (isBracketed == Standard_False ||
274           !OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
275         break;
276       if (theBuffer.LinePtr[0] == ',') {
277         theBuffer.LinePtr++;
278         continue;
279       } else if (theBuffer.LinePtr[0] == ']') // closing bracket
280         theBuffer.LinePtr++;
281       else
282         aStatus = VrmlData_VrmlFormatError;
283       break;
284     }
285   }
286   return aStatus;
287 }
288 
289 //=======================================================================
290 //function : ReadNode
291 //purpose  :
292 //=======================================================================
293 
ReadNode(VrmlData_InBuffer & theBuffer,Handle (VrmlData_Node)& theNode,const Handle (Standard_Type)& theType)294 VrmlData_ErrorStatus VrmlData_Node::ReadNode
295                                 (VrmlData_InBuffer&             theBuffer,
296                                  Handle(VrmlData_Node)&         theNode,
297                                  const Handle(Standard_Type)&   theType)
298 {
299   Handle(VrmlData_Node) aNode;
300   VrmlData_ErrorStatus  aStatus;
301   // First line of a new node should identify this node type
302   if (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
303     if (VRMLDATA_LCOMPARE(theBuffer.LinePtr, "USE")) {
304       TCollection_AsciiString aName;
305       aStatus = VrmlData_Scene::ReadWord (theBuffer, aName);
306       if (aStatus == VrmlData_StatusOK) {
307         aNode = myScene->FindNode (aName.ToCString(), theType);
308         if (aNode.IsNull())
309           aStatus = VrmlData_NodeNameUnknown;
310 //         else
311 //           aNode = aNode->Clone(0L);
312       }
313     }
314 
315     // We create a relevant node using the line with the type ID
316     else if (OK(aStatus,
317                 const_cast<VrmlData_Scene *>(myScene)->createNode (theBuffer,
318                                                                    aNode,
319                                                                    theType)))
320       if (aNode.IsNull() == Standard_False)
321         // The node data are read here, including the final closing brace
322         aStatus = aNode->Read(theBuffer);
323 
324     if (aStatus == VrmlData_StatusOK)
325       theNode = aNode;
326   }
327   return aStatus;
328 }
329 
330 //=======================================================================
331 //function : VrmlData_ShapeNode::Clone
332 //purpose  :
333 //=======================================================================
334 
Handle(VrmlData_Node)335 Handle(VrmlData_Node) VrmlData_ShapeNode::Clone
336                                 (const Handle(VrmlData_Node)& theOther) const
337 {
338   Handle(VrmlData_ShapeNode) aResult =
339     Handle(VrmlData_ShapeNode)::DownCast (VrmlData_Node::Clone(theOther));
340   if (aResult.IsNull())
341     aResult= new VrmlData_ShapeNode(theOther.IsNull()?Scene():theOther->Scene(),
342                                     Name());
343   if (&aResult->Scene() == &Scene()) {
344     aResult->SetAppearance (myAppearance);
345     aResult->SetGeometry   (myGeometry);
346   } else {
347     // Create a dummy node to pass the different Scene instance to methods Clone
348     const Handle(VrmlData_UnknownNode) aDummyNode =
349       new VrmlData_UnknownNode (aResult->Scene());
350     if (myAppearance.IsNull() == Standard_False)
351       aResult->SetAppearance(Handle(VrmlData_Appearance)::DownCast
352                              (myAppearance->Clone (aDummyNode)));
353     if (myGeometry.IsNull() == Standard_False)
354       aResult->SetGeometry (Handle(VrmlData_Geometry)::DownCast
355                             (myGeometry->Clone (aDummyNode)));
356   }
357   return aResult;
358 }
359 
360 //=======================================================================
361 //function : VrmlData_ShapeNode::Read
362 //purpose  :
363 //=======================================================================
364 
Read(VrmlData_InBuffer & theBuffer)365 VrmlData_ErrorStatus VrmlData_ShapeNode::Read (VrmlData_InBuffer& theBuffer)
366 {
367   VrmlData_ErrorStatus aStatus;
368   while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
369     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "appearance"))
370     {
371       Handle(VrmlData_Node) aNode;
372       aStatus = ReadNode (theBuffer, aNode,
373                           STANDARD_TYPE(VrmlData_Appearance));
374       myAppearance = Handle(VrmlData_Appearance)::DownCast (aNode);
375     }
376     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "geometry"))
377     {
378       Handle(VrmlData_Node) aNode;
379       aStatus = ReadNode (theBuffer, aNode);
380       myGeometry = Handle(VrmlData_Geometry)::DownCast (aNode);
381 // here we do not check for the Geometry type because unknown node types can
382 // occur (IndexedLineSet, etc.)
383 //                          STANDARD_TYPE(VrmlData_Geometry));
384     }
385     else
386       break;
387 
388     if (!OK(aStatus))
389       break;
390   }
391 
392   // Read the terminating (closing) brace
393   if (OK(aStatus))
394     aStatus = readBrace (theBuffer);
395   return aStatus;
396 }
397 
398 //=======================================================================
399 //function : VrmlData_ShapeNode::Write
400 //purpose  :
401 //=======================================================================
402 
Write(const char * thePrefix) const403 VrmlData_ErrorStatus VrmlData_ShapeNode::Write (const char * thePrefix) const
404 {
405   VrmlData_ErrorStatus aStatus (VrmlData_StatusOK);
406   const VrmlData_Scene& aScene = Scene();
407   static char header[] = "Shape {";
408   if (OK (aStatus, aScene.WriteLine (thePrefix, header, GlobalIndent())))
409   {
410     if (myAppearance.IsNull() == Standard_False)
411       aStatus = aScene.WriteNode ("appearance", myAppearance);
412     if (myGeometry.IsNull() == Standard_False && OK(aStatus))
413       aStatus = aScene.WriteNode ("geometry", myGeometry);
414 
415     aStatus = WriteClosing();
416   }
417   return aStatus;
418 }
419 
420 //=======================================================================
421 //function : VrmlData_ShapeNode::IsDefault
422 //purpose  :
423 //=======================================================================
424 
IsDefault() const425 Standard_Boolean VrmlData_ShapeNode::IsDefault () const
426 {
427   Standard_Boolean aResult (Standard_True);
428   if (myGeometry.IsNull() == Standard_False)
429     aResult = myGeometry->IsDefault();
430   return aResult;
431 }
432 
433 //=======================================================================
434 //function : VrmlData_UnknownNode::Read
435 //purpose  :
436 //=======================================================================
437 
Read(VrmlData_InBuffer & theBuffer)438 VrmlData_ErrorStatus VrmlData_UnknownNode::Read (VrmlData_InBuffer& theBuffer)
439 {
440   VrmlData_ErrorStatus aStatus = VrmlData_StatusOK;
441   Standard_Integer aLevelCounter (0);
442   // This loop searches for any opening brace.
443   // Such brace increments the level counter. A closing brace decrements
444   // the counter. The loop terminates when the counter becomes negative.
445   while (aLevelCounter >= 0 &&
446          OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
447   {
448     int aChar;
449     while ((aChar = theBuffer.LinePtr[0]) != '\0') {
450       theBuffer.LinePtr++;
451       if        (aChar == '{') {
452         aLevelCounter++;
453         break;
454       } else if (aChar == '}') {
455         aLevelCounter--;
456         break;
457       }
458     }
459   }
460   return aStatus;
461 }
462 
463 //=======================================================================
464 //function : VrmlData_UnknownNode::IsDefault
465 //purpose  :
466 //=======================================================================
467 
IsDefault() const468 Standard_Boolean VrmlData_UnknownNode::IsDefault () const
469 {
470   return Standard_True;
471 }
472 
473 //=======================================================================
474 //function : VrmlData_Appearance::Clone
475 //purpose  :
476 //=======================================================================
477 
Handle(VrmlData_Node)478 Handle(VrmlData_Node) VrmlData_Appearance::Clone
479                                 (const Handle(VrmlData_Node)& theOther) const
480 {
481   Handle(VrmlData_Appearance) aResult =
482     Handle(VrmlData_Appearance)::DownCast (VrmlData_Node::Clone(theOther));
483   if (aResult.IsNull())
484     aResult = new VrmlData_Appearance
485       (theOther.IsNull() ? Scene() : theOther->Scene(), Name());
486   if (&aResult->Scene() == &Scene()) {
487     aResult->SetMaterial          (myMaterial);
488     aResult->SetTexture           (myTexture);
489     aResult->SetTextureTransform  (myTTransform);
490   } else {
491     // Create a dummy node to pass the different Scene instance to methods Clone
492     const Handle(VrmlData_UnknownNode) aDummyNode =
493       new VrmlData_UnknownNode (aResult->Scene());
494     if (myMaterial.IsNull()   == Standard_False)
495       aResult->SetMaterial (Handle(VrmlData_Material)::DownCast
496                             (myMaterial->Clone (aDummyNode)));
497     if (myTexture.IsNull()    == Standard_False)
498       aResult->SetTexture(Handle(VrmlData_Texture)::DownCast
499                           (myTexture->Clone (aDummyNode)));
500     if (myTTransform.IsNull() == Standard_False)
501       aResult->SetTextureTransform(Handle(VrmlData_TextureTransform)::DownCast
502                                    (myTTransform->Clone (aDummyNode)));
503   }
504   return aResult;
505 }
506 
507 //=======================================================================
508 //function : VrmlData_Appearance::Read
509 //purpose  :
510 //=======================================================================
511 
Read(VrmlData_InBuffer & theBuffer)512 VrmlData_ErrorStatus VrmlData_Appearance::Read (VrmlData_InBuffer& theBuffer)
513 {
514   VrmlData_ErrorStatus aStatus;
515   while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
516     if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "material"))
517     {
518       Handle(VrmlData_Node) aNode;
519       aStatus = ReadNode (theBuffer, aNode,
520                           STANDARD_TYPE(VrmlData_Material));
521       myMaterial = Handle(VrmlData_Material)::DownCast (aNode);
522     }
523     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "textureTransform"))
524     {
525       Handle(VrmlData_Node) aNode;
526       aStatus = ReadNode (theBuffer, aNode
527                           /*,STANDARD_TYPE(VrmlData_TextureTransform)*/);
528       myTTransform = Handle(VrmlData_TextureTransform)::DownCast (aNode);
529     }
530     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "texture"))
531     {
532       Handle(VrmlData_Node) aNode;
533       aStatus = ReadNode (theBuffer, aNode,
534                           STANDARD_TYPE(VrmlData_Texture));
535       myTexture = Handle(VrmlData_Texture)::DownCast (aNode);
536     }
537     else
538       break;
539 
540     if (!OK(aStatus))
541       break;
542   }
543 
544   // Read the terminating (closing) brace
545   if (OK(aStatus))
546     aStatus = readBrace (theBuffer);
547   return aStatus;
548 }
549 
550 //=======================================================================
551 //function : VrmlData_Appearance::Write
552 //purpose  :
553 //=======================================================================
554 
Write(const char * thePrefix) const555 VrmlData_ErrorStatus VrmlData_Appearance::Write (const char * thePrefix) const
556 {
557   static char header[] = "Appearance {";
558   VrmlData_ErrorStatus aStatus;
559   const VrmlData_Scene& aScene = Scene();
560   if (OK (aStatus, aScene.WriteLine (thePrefix, header, GlobalIndent())))
561   {
562     if (myMaterial.IsNull() == Standard_False)
563       aStatus = aScene.WriteNode ("material", myMaterial);
564     if (myTexture.IsNull() == Standard_False && OK(aStatus))
565       aStatus = aScene.WriteNode ("texture", myTexture);
566     if (myTTransform.IsNull() == Standard_False && OK(aStatus))
567       aStatus = aScene.WriteNode ("textureTransform", myTTransform);
568 
569     aStatus = WriteClosing();
570   }
571   return aStatus;
572 }
573 
574 //=======================================================================
575 //function : IsDefault
576 //purpose  :
577 //=======================================================================
578 
IsDefault() const579 Standard_Boolean VrmlData_Appearance::IsDefault () const
580 {
581   Standard_Boolean aResult (Standard_True);
582   if (myMaterial.IsNull() == Standard_False)
583     aResult = myMaterial->IsDefault();
584   if (aResult && myTexture.IsNull() == Standard_False)
585     aResult = myTexture->IsDefault();
586   if (aResult && myTTransform.IsNull() == Standard_False)
587     aResult = myTTransform->IsDefault();
588   return aResult;
589 }
590 
591 //=======================================================================
592 //function : VrmlData_ImageTexture
593 //purpose  : Constructor
594 //=======================================================================
595 
VrmlData_ImageTexture(const VrmlData_Scene & theScene,const char * theName,const char * theURL,const Standard_Boolean theRepS,const Standard_Boolean theRepT)596 VrmlData_ImageTexture::VrmlData_ImageTexture (const VrmlData_Scene&  theScene,
597                                               const char             * theName,
598                                               const char             * theURL,
599                                               const Standard_Boolean theRepS,
600                                               const Standard_Boolean theRepT)
601   : VrmlData_Texture (theScene, theName, theRepS, theRepT),
602     myURL            (theScene.Allocator())
603 {
604   myURL.Append (theURL ? (Standard_CString)theURL : "");
605 }
606 
607 //=======================================================================
608 //function : VrmlData_ImageTexture::Clone
609 //purpose  :
610 //=======================================================================
611 
Handle(VrmlData_Node)612 Handle(VrmlData_Node) VrmlData_ImageTexture::Clone
613                                 (const Handle(VrmlData_Node)& theOther) const
614 {
615   Handle(VrmlData_ImageTexture) aResult =
616     Handle(VrmlData_ImageTexture)::DownCast (VrmlData_Node::Clone(theOther));
617   if (aResult.IsNull())
618     aResult =
619       new VrmlData_ImageTexture(theOther.IsNull() ? Scene() : theOther->Scene(),
620                                 Name());
621   aResult->myURL = myURL;
622   return aResult;
623 }
624 
625 //=======================================================================
626 //function : VrmlData_ImageTexture::Read
627 //purpose  :
628 //=======================================================================
629 
Read(VrmlData_InBuffer & theBuffer)630 VrmlData_ErrorStatus VrmlData_ImageTexture::Read (VrmlData_InBuffer& theBuffer)
631 {
632   VrmlData_ErrorStatus aStatus;
633   Standard_Boolean aRepeatS (Standard_True), aRepeatT (Standard_True);
634   myURL.Clear();
635   while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
636     if      (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "url"))
637       aStatus = ReadMultiString (theBuffer, myURL);
638     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "repeatS"))
639       aStatus = ReadBoolean (theBuffer, aRepeatS);
640     else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "repeatT"))
641       aStatus = ReadBoolean (theBuffer, aRepeatT);
642     else
643       break;
644 
645     if (!OK(aStatus))
646       break;
647   }
648   if (OK(aStatus) && OK(aStatus, readBrace (theBuffer))) {
649     SetRepeatS (aRepeatS);
650     SetRepeatT (aRepeatT);
651   }
652   return aStatus;
653 }
654 
655 //=======================================================================
656 //function : Write
657 //purpose  :
658 //=======================================================================
659 
Write(const char * thePrefix) const660 VrmlData_ErrorStatus VrmlData_ImageTexture::Write(const char *thePrefix)  const
661 {
662   VrmlData_ErrorStatus aStatus = VrmlData_StatusOK;
663   const VrmlData_Scene& aScene = Scene();
664   static char header[] = "ImageTexture {";
665   if (aScene.IsDummyWrite() == Standard_False &&
666       OK(aStatus, aScene.WriteLine(thePrefix, header, GlobalIndent())))
667   {
668     TCollection_AsciiString url = "\"";
669     url += URL().First();
670     url += "\"";
671 
672     try {
673       aStatus = aScene.WriteLine("url ", url.ToCString());
674     }
675     catch (...)
676     {
677 
678     }
679     aStatus = WriteClosing();
680   }
681   return aStatus;
682 }
683