0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / VrmlData / VrmlData_Scene.hxx
1 // Created on: 2006-10-08
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 #ifndef VrmlData_Scene_HeaderFile
17 #define VrmlData_Scene_HeaderFile
18
19 #include <VrmlData_ListOfNode.hxx>
20 #include <VrmlData_MapOfNode.hxx>
21 #include <VrmlData_ErrorStatus.hxx>
22 #include <VrmlData_Geometry.hxx>
23 #include <VrmlData_WorldInfo.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <Standard_OStream.hxx>
26 #include <Standard_IStream.hxx>
27 #include <TCollection_ExtendedString.hxx>
28 #include <NCollection_IncAllocator.hxx>
29 #include <Standard_Mutex.hxx>
30 #include <VrmlData_DataMapOfShapeAppearance.hxx>
31
32 // resolve name collisions with X11 headers
33 #ifdef Status
34   #undef Status
35 #endif
36
37 struct VrmlData_InBuffer;
38
39 /**
40  * Block of comments describing class VrmlData_Scene
41  */
42
43 class VrmlData_Scene 
44 {
45  public:
46   /**
47    * Iterator type to get all contained Nodes one-by-one.
48    */
49   typedef VrmlData_ListOfNode::Iterator Iterator;
50
51   // ---------- PUBLIC METHODS ----------
52
53   /**
54    * Constructor.
55    */
56   Standard_EXPORT VrmlData_Scene (const Handle(NCollection_IncAllocator)& = 0L);
57
58   /**
59    * Query the status of the previous operation.
60    * Normally it should be equal to VrmlData_StatusOK (no error).
61    */
62   inline VrmlData_ErrorStatus   Status      () const
63   { return myStatus; }
64
65   /**
66    * Add the given directory path to the list of VRML file search directories.
67    * This method forms the list of directories ordered according to the
68    * sequence of this method calls. When an Inline node is found, the URLs
69    * in that node are matched with these directories.
70    * The last (implicit) search directory is the current process directory
71    * ("."). It takes effect if the list is empty or if there is no match with
72    * exisiting directories.
73    */
74   Standard_EXPORT void          SetVrmlDir  (const TCollection_ExtendedString&);
75
76   /**
77    * Set the scale factor that would be further used in methods
78    * ReadReal, ReadXYZ and ReadXY. All coordinates, distances and sized are
79    * multiplied by this factor during reading the data.
80    */
81   inline void                   SetLinearScale (const Standard_Real theScale)
82   { myLinearScale = theScale; }
83
84   /**
85    * Returns the directory iterator, to check the presence of requested VRML
86    * file in each iterated directory.
87    */
88   inline NCollection_List<TCollection_ExtendedString>::Iterator
89                                 VrmlDirIterator () const
90   { return NCollection_List<TCollection_ExtendedString>::Iterator(myVrmlDir); }
91
92   /**
93    * Iterator of Nodes
94    */
95   inline Iterator               GetIterator () const
96   { return Iterator (myLstNodes); }
97
98   /**
99    * Get the iterator of named nodes.
100    */
101   inline VrmlData_MapOfNode::Iterator
102                                 NamedNodesIterator() const
103   { return myNamedNodes; }
104
105   /**
106    * Allocator used by all nodes contained in the Scene.
107    */
108   inline const Handle(NCollection_IncAllocator)&
109                                 Allocator   () const
110   { return myAllocator; }
111
112   /**
113    * Add a Node. If theN belongs to another Scene, it is cloned.
114    * <p>VrmlData_WorldInfo cannot be added, in this case the method
115    * returns a NULL handle.
116    */
117   Standard_EXPORT const Handle(VrmlData_Node)&
118                                 AddNode     (const Handle(VrmlData_Node)& theN,
119                                              const Standard_Boolean isTopLevel
120                                              = Standard_True);
121
122   /**
123    * Find a node by its name.
124    * @param theName
125    *   Name of the node to find.
126    * @param theType
127    *   Type to match. If this value is NULL, the first found node with the
128    *   given name is returned. If theType is given, only the node that has
129    *   that type is returned.
130    */
131   Standard_EXPORT Handle(VrmlData_Node)
132                                 FindNode    (const char * theName,
133                                              const Handle(Standard_Type)&
134                                                            theType = 0L) const;
135
136   /**
137    * Find a node by its name.
138    * @param theName
139    *   Name of the node to search for.
140    * @param theLocation
141    *   Location of the found node with respect to the whole VRML shape.
142    */
143   Standard_EXPORT Handle(VrmlData_Node)
144                                 FindNode(const char * theName,
145                                          gp_Trsf&     theLocation) const;
146
147   /**
148    * Export to text stream (file or else).
149    * This method is protected by Mutex, it is not allowed to read/write
150    * two VRML streams concurrently.
151    * The stream should give as the first line the VRML header:
152    * <code>
153    *   #VRML V2.0 <encoding type> [optional comment] <line terminator>
154    * </code>
155    *  
156    */
157   friend Standard_EXPORT Standard_OStream&
158                                 operator << (Standard_OStream&      theOutput,
159                                              const VrmlData_Scene&  theScene);
160
161   /**
162    * Import from text stream (file or else).
163    * This method is protected by Mutex, it is not allowed to read/write
164    * two VRML streams concurrently.
165    */
166   Standard_EXPORT VrmlData_Scene& operator<<(Standard_IStream& theInput);
167
168   /**
169    * Convert the scene to a Shape.
170    */
171   Standard_EXPORT               operator TopoDS_Shape () const;
172
173   /**
174    * Convert the scene to a Shape, with the information on materials defined
175    * for each sub-shape. This method should be used instead of TopoDS_Shape
176    * explicit conversion operator when you need to retrieve the material
177    * aspect for each face or edge in the returned topological object.
178    * @param M
179    *   Data Map that binds an Appearance instance to each created TFace or
180    *   TEdge if the Appearance node is defined in VRML scene for that geometry.
181    * @return
182    *   TopoDS_Shape (Compound) holding all the scene, similar to the result of
183    *   explicit TopoDS_Shape conversion operator.
184    */
185   Standard_EXPORT TopoDS_Shape  GetShape (VrmlData_DataMapOfShapeAppearance& M);
186
187   /**
188    * Query the WorldInfo member.
189    */
190   Standard_EXPORT const Handle(VrmlData_WorldInfo)&
191                                 WorldInfo() const;
192
193   /**
194    * Read a VRML line. Empty lines and comments are skipped.
195    * The processing starts here from theBuffer.LinePtr; if there is at least
196    * one non-empty character (neither space nor comment), this line is used
197    * without reading the next one.
198    * @param theLine
199    *   Buffer receiving the input line
200    * @param theInput
201    *   Input stream
202    * @param theLen
203    *   Length of the input buffer (maximal line length)
204    */
205   Standard_EXPORT static VrmlData_ErrorStatus
206                                 ReadLine    (VrmlData_InBuffer& theBuffer);
207
208   /**
209    * Read a singel word from the input stream, delimited by whitespace.
210    */
211   Standard_EXPORT static VrmlData_ErrorStatus
212                                 ReadWord    (VrmlData_InBuffer&       theBuffer,
213                                              TCollection_AsciiString& theStr);
214
215   /**
216    * Diagnostic dump of the contents
217    */
218   Standard_EXPORT void          Dump        (Standard_OStream& theStream) const;
219
220   /**
221    * Read one real value.
222    */
223   Standard_EXPORT VrmlData_ErrorStatus
224                                 ReadReal    (VrmlData_InBuffer& theBuffer,
225                                              Standard_Real&     theResult,
226                                              Standard_Boolean   isApplyScale,
227                                              Standard_Boolean   isOnlyPositive)
228                                                                         const;
229
230   /**
231    * Read one triplet of real values.
232    */
233   Standard_EXPORT VrmlData_ErrorStatus
234                                 ReadXYZ     (VrmlData_InBuffer& theBuffer,
235                                              gp_XYZ&            theXYZ,
236                                              Standard_Boolean   isApplyScale,
237                                              Standard_Boolean   isOnlyPositive)
238                                                                         const;
239
240   /**
241    * Read one doublet of real values.
242    */
243   Standard_EXPORT VrmlData_ErrorStatus
244                                 ReadXY      (VrmlData_InBuffer& theBuffer,
245                                              gp_XY&             theXYZ,
246                                              Standard_Boolean   isApplyScale,
247                                              Standard_Boolean   isOnlyPositive)
248                                                                         const;
249   /**
250    * Read an array of integer indices, for IndexedfaceSet and IndexedLineSet.
251    */ 
252   Standard_EXPORT VrmlData_ErrorStatus
253                                 ReadArrIndex(VrmlData_InBuffer& theBuffer,
254                                              const Standard_Integer **& theArr,
255                                              Standard_Size&             theNBl)
256                                                                         const;
257
258   /**
259    * Query the line where the error occurred (if the status is not OK)
260    */
261   inline Standard_Integer       GetLineError() const { return myLineError; }
262
263   /**
264    * Store the indentation for VRML output.
265    * @param nSpc
266    *   number of spaces to insert at every indentation level
267    */
268   inline void                   SetIndent   (const Standard_Integer nSpc)
269   { myIndent = nSpc; }
270
271   /**
272    * Write a triplet of real values on a separate line.
273    * @param theXYZ
274    *   The value to be output.
275    * @param isScale
276    *   If True, then each component is divided by myLinearScale.
277    * @param thePostfix
278    *   Optional string that is added before the end of the line.
279    */
280   Standard_EXPORT VrmlData_ErrorStatus
281                                 WriteXYZ    (const  gp_XYZ&         theXYZ,
282                                              const Standard_Boolean isScale,
283                                              const char           * thePostfix
284                                                                     = 0L) const;
285   /**
286    * Write an array of integer indices, for IndexedFaceSet and IndexedLineSet.
287    */
288   Standard_EXPORT VrmlData_ErrorStatus
289                                 WriteArrIndex(const char *          thePrefix,
290                                               const Standard_Integer ** theArr,
291                                               const Standard_Size       theNbBl)
292                                                                         const;
293
294
295   /**
296    * Write a string to the output stream respecting the indentation. The string
297    * can be defined as two substrings that will be separated by a space.
298    * Each of the substrings can be NULL, then it is ignored. If both
299    * are NULL, then a single newline is output (without indent).
300    * @param theLine0
301    *   The first part of string to output
302    * @param theLine1
303    *   The second part of string to output
304    * @param theIndent
305    *   - 0 value ignored.
306    *   - negative decreases the current indent and then outputs.
307    *   - positive outputs and then increases the current indent. 
308    * @return
309    *   Error status of the stream, or a special error if myOutput == NULL.
310    */
311   Standard_EXPORT VrmlData_ErrorStatus
312                                 WriteLine   (const char           * theLine0,
313                                              const char           * theLine1=0L,
314                                              const Standard_Integer theIndent
315                                                                      = 0) const;
316
317   /**
318    * Write the given node to output stream 'myOutput'.
319    */
320   Standard_EXPORT VrmlData_ErrorStatus
321                                 WriteNode   (const char * thePrefix,
322                                              const Handle(VrmlData_Node)&) const;
323
324   /**
325    * Query if the current write operation is dummy, i.e., for the purpose of
326    * collecting information before the real write is commenced.
327    */
328   inline Standard_Boolean       IsDummyWrite() const
329   { return myOutput == 0L; }
330
331  private:
332   // ---------- PRIVATE METHODS (PROHIBITED) ----------
333   VrmlData_Scene (const VrmlData_Scene&);
334   VrmlData_Scene& operator = (const VrmlData_Scene&);
335
336  protected:
337   /**
338    * Read whatever line from the input checking the istream flags.
339    */ 
340   Standard_EXPORT static VrmlData_ErrorStatus
341                                 readLine    (VrmlData_InBuffer&     theBuffer);
342
343   /**
344    * Read and verify the VRML header (the 1st line of the file)
345    */ 
346   Standard_EXPORT static VrmlData_ErrorStatus
347                                 readHeader  (VrmlData_InBuffer&     theBuffer);
348
349   /**
350    * Create the node.
351    * @param theBuffer
352    *   Input buffer from where the node is created
353    * @param theNode
354    *   Output parameter, contains the created node on exit
355    * @param Type
356    *   Node type to be checked. If it is NULL no type checking is done.
357    *   Otherwise the created node is matched and an error is returned if
358    *   no match detected.
359    */
360   Standard_EXPORT VrmlData_ErrorStatus 
361                                 createNode  (VrmlData_InBuffer&     theBuffer,
362                                              Handle(VrmlData_Node)& theNode,
363                                              const Handle(Standard_Type)& Type);
364
365   /**
366    * Create a single Shape object from all geometric nodes in the list.
367    */
368   Standard_EXPORT static void   createShape (TopoDS_Shape&          outShape,
369                                              const VrmlData_ListOfNode&,
370                                              VrmlData_DataMapOfShapeAppearance*);
371
372
373  private:
374   // ---------- PRIVATE FIELDS ----------
375   Standard_Real                                 myLinearScale;
376   VrmlData_ListOfNode                           myLstNodes; ///! top-level nodes
377   VrmlData_ListOfNode                           myAllNodes; ///! all nodes
378   VrmlData_ErrorStatus                          myStatus;
379   Handle(NCollection_IncAllocator)               myAllocator;
380   Handle(VrmlData_WorldInfo)                     myWorldInfo;
381   VrmlData_MapOfNode                            myNamedNodes;
382
383   // read from stream
384   NCollection_List<TCollection_ExtendedString>  myVrmlDir;
385   Standard_Mutex                                myMutex;
386   Standard_Integer                              myLineError;///! #0 if error
387
388   // write to stream
389   Standard_OStream                              * myOutput;
390   Standard_Integer                              myIndent;
391   Standard_Integer                              myCurrentIndent;
392   /**
393    * This map is used to avoid multiple storage of the same named node: each
394    * named node is added here when it is written the first time.
395    */
396   VrmlData_MapOfNode                            myNamedNodesOut;
397   /**
398    * This map allows to resolve multiple reference to any unnamed node. It
399    * is used during the dummy write (myOutput == 0L). When a node is processed
400    * the first time it is added to this map, the second time it is automatically
401    * assigned a name.
402    */
403   NCollection_Map<Standard_Address>             myUnnamedNodesOut;
404   Standard_Integer                              myAutoNameCounter;
405   friend class VrmlData_Group;
406   friend class VrmlData_Node;
407 };
408
409 #endif