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