summaryrefslogtreecommitdiff
path: root/inc/VrmlData_Scene.hxx
blob: 298ff2a103264e3dab526b8b038c7b9c54a3036f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
// File:      VrmlData_Scene.hxx
// Created:   08.10.06 18:35:39
// Author:    Alexander GRIGORIEV
// Copyright: Open Cascade 2006


#ifndef VrmlData_Scene_HeaderFile
#define VrmlData_Scene_HeaderFile

#include <VrmlData_ListOfNode.hxx>
#include <VrmlData_MapOfNode.hxx>
#include <VrmlData_ErrorStatus.hxx>
#include <VrmlData_Geometry.hxx>
#include <VrmlData_WorldInfo.hxx>
#include <TopoDS_Shape.hxx>
#include <Standard_OStream.hxx>
#include <Standard_IStream.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Standard_Mutex.hxx>

struct VrmlData_InBuffer;
class Handle_VrmlData_WorldInfo;
class VrmlData_DataMapOfShapeAppearance;

/**
 * Block of comments describing class VrmlData_Scene
 */

class VrmlData_Scene 
{
 public:
  /**
   * Iterator type to get all contained Nodes one-by-one.
   */
  typedef VrmlData_ListOfNode::Iterator Iterator;

  // ---------- PUBLIC METHODS ----------

  /**
   * Constructor.
   */
  Standard_EXPORT VrmlData_Scene (const Handle(NCollection_IncAllocator)& = 0L);

  /**
   * Query the status of the previous operation.
   * Normally it should be equal to VrmlData_StatusOK (no error).
   */
  inline VrmlData_ErrorStatus   Status      () const
  { return myStatus; }

  /**
   * Add the given directory path to the list of VRML file search directories.
   * This method forms the list of directories ordered according to the
   * sequence of this method calls. When an Inline node is found, the URLs
   * in that node are matched with these directories.
   * The last (implicit) search directory is the current process directory
   * ("."). It takes effect if the list is empty or if there is no match with
   * exisiting directories.
   */
  Standard_EXPORT void          SetVrmlDir  (const TCollection_ExtendedString&);

  /**
   * Set the scale factor that would be further used in methods
   * ReadReal, ReadXYZ and ReadXY. All coordinates, distances and sized are
   * multiplied by this factor during reading the data.
   */
  inline void                   SetLinearScale (const Standard_Real theScale)
  { myLinearScale = theScale; }

  /**
   * Returns the directory iterator, to check the presence of requested VRML
   * file in each iterated directory.
   */
  inline NCollection_List<TCollection_ExtendedString>::Iterator
                                VrmlDirIterator () const
  { return NCollection_List<TCollection_ExtendedString>::Iterator(myVrmlDir); }

  /**
   * Iterator of Nodes
   */
  inline Iterator               GetIterator () const
  { return Iterator (myLstNodes); }

  /**
   * Get the iterator of named nodes.
   */
  inline VrmlData_MapOfNode::Iterator
                                NamedNodesIterator() const
  { return myNamedNodes; }

  /**
   * Allocator used by all nodes contained in the Scene.
   */
  inline const Handle(NCollection_IncAllocator)&
                                Allocator   () const
  { return myAllocator; }

  /**
   * Add a Node. If theN belongs to another Scene, it is cloned.
   * <p>VrmlData_WorldInfo cannot be added, in this case the method
   * returns a NULL handle.
   */
  Standard_EXPORT const Handle(VrmlData_Node)&
                                AddNode     (const Handle(VrmlData_Node)& theN,
                                             const Standard_Boolean isTopLevel
                                             = Standard_True);

  /**
   * Find a node by its name.
   * @param theName
   *   Name of the node to find.
   * @param theType
   *   Type to match. If this value is NULL, the first found node with the
   *   given name is returned. If theType is given, only the node that has
   *   that type is returned.
   */
  Standard_EXPORT Handle(VrmlData_Node)
                                FindNode    (const char * theName,
                                             const Handle(Standard_Type)&
                                                           theType = 0L) const;

  /**
   * Find a node by its name.
   * @param theName
   *   Name of the node to search for.
   * @param theLocation
   *   Location of the found node with respect to the whole VRML shape.
   */
  Standard_EXPORT Handle(VrmlData_Node)
                                FindNode(const char * theName,
                                         gp_Trsf&     theLocation) const;

  /**
   * Export to text stream (file or else).
   * This method is protected by Mutex, it is not allowed to read/write
   * two VRML streams concurrently.
   * The stream should give as the first line the VRML header:
   * <code>
   *   #VRML V2.0 <encoding type> [optional comment] <line terminator>
   * </code>
   *  
   */
  friend Standard_EXPORT Standard_OStream&
                                operator << (Standard_OStream&      theOutput,
                                             const VrmlData_Scene&  theScene);

  /**
   * Import from text stream (file or else).
   * This method is protected by Mutex, it is not allowed to read/write
   * two VRML streams concurrently.
   */
  Standard_EXPORT VrmlData_Scene& operator<<(Standard_IStream& theInput);

  /**
   * Convert the scene to a Shape.
   */
  Standard_EXPORT               operator TopoDS_Shape () const;

  /**
   * Convert the scene to a Shape, with the information on materials defined
   * for each sub-shape. This method should be used instead of TopoDS_Shape
   * explicit conversion operator when you need to retrieve the material
   * aspect for each face or edge in the returned topological object.
   * @param M
   *   Data Map that binds an Appearance instance to each created TFace or
   *   TEdge if the Appearance node is defined in VRML scene for that geometry.
   * @return
   *   TopoDS_Shape (Compound) holding all the scene, similar to the result of
   *   explicit TopoDS_Shape conversion operator.
   */
  Standard_EXPORT TopoDS_Shape  GetShape (VrmlData_DataMapOfShapeAppearance& M);

  /**
   * Query the WorldInfo member.
   */
  Standard_EXPORT const Handle_VrmlData_WorldInfo&
                                WorldInfo() const;

  /**
   * Read a VRML line. Empty lines and comments are skipped.
   * The processing starts here from theBuffer.LinePtr; if there is at least
   * one non-empty character (neither space nor comment), this line is used
   * without reading the next one.
   * @param theLine
   *   Buffer receiving the input line
   * @param theInput
   *   Input stream
   * @param theLen
   *   Length of the input buffer (maximal line length)
   */
  Standard_EXPORT static VrmlData_ErrorStatus
                                ReadLine    (VrmlData_InBuffer& theBuffer);

  /**
   * Read a singel word from the input stream, delimited by whitespace.
   */
  Standard_EXPORT static VrmlData_ErrorStatus
                                ReadWord    (VrmlData_InBuffer&       theBuffer,
                                             TCollection_AsciiString& theStr);

  /**
   * Diagnostic dump of the contents
   */
  Standard_EXPORT void          Dump        (Standard_OStream& theStream) const;

  /**
   * Read one real value.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                ReadReal    (VrmlData_InBuffer& theBuffer,
                                             Standard_Real&     theResult,
                                             Standard_Boolean   isApplyScale,
                                             Standard_Boolean   isOnlyPositive)
                                                                        const;

  /**
   * Read one triplet of real values.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                ReadXYZ     (VrmlData_InBuffer& theBuffer,
                                             gp_XYZ&            theXYZ,
                                             Standard_Boolean   isApplyScale,
                                             Standard_Boolean   isOnlyPositive)
                                                                        const;

  /**
   * Read one doublet of real values.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                ReadXY      (VrmlData_InBuffer& theBuffer,
                                             gp_XY&             theXYZ,
                                             Standard_Boolean   isApplyScale,
                                             Standard_Boolean   isOnlyPositive)
                                                                        const;
  /**
   * Read an array of integer indices, for IndexedfaceSet and IndexedLineSet.
   */ 
  Standard_EXPORT VrmlData_ErrorStatus
                                ReadArrIndex(VrmlData_InBuffer& theBuffer,
                                             const Standard_Integer **& theArr,
                                             Standard_Size&             theNBl)
                                                                        const;

  /**
   * Query the line where the error occurred (if the status is not OK)
   */
  inline Standard_Integer       GetLineError() const { return myLineError; }

  /**
   * Store the indentation for VRML output.
   * @param nSpc
   *   number of spaces to insert at every indentation level
   */
  inline void                   SetIndent   (const Standard_Integer nSpc)
  { myIndent = nSpc; }

  /**
   * Write a triplet of real values on a separate line.
   * @param theXYZ
   *   The value to be output.
   * @param isScale
   *   If True, then each component is divided by myLinearScale.
   * @param thePostfix
   *   Optional string that is added before the end of the line.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                WriteXYZ    (const  gp_XYZ&         theXYZ,
                                             const Standard_Boolean isScale,
                                             const char           * thePostfix
                                                                    = 0L) const;
  /**
   * Write an array of integer indices, for IndexedFaceSet and IndexedLineSet.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                WriteArrIndex(const char *          thePrefix,
                                              const Standard_Integer ** theArr,
                                              const Standard_Size       theNbBl)
                                                                        const;


  /**
   * Write a string to the output stream respecting the indentation. The string
   * can be defined as two substrings that will be separated by a space.
   * Each of the substrings can be NULL, then it is ignored. If both
   * are NULL, then a single newline is output (without indent).
   * @param theLine0
   *   The first part of string to output
   * @param theLine1
   *   The second part of string to output
   * @param theIndent
   *   - 0 value ignored.
   *   - negative decreases the current indent and then outputs.
   *   - positive outputs and then increases the current indent. 
   * @return
   *   Error status of the stream, or a special error if myOutput == NULL.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                WriteLine   (const char           * theLine0,
                                             const char           * theLine1=0L,
                                             const Standard_Integer theIndent
                                                                     = 0) const;

  /**
   * Write the given node to output stream 'myOutput'.
   */
  Standard_EXPORT VrmlData_ErrorStatus
                                WriteNode   (const char * thePrefix,
                                             const Handle_VrmlData_Node&) const;

  /**
   * Query if the current write operation is dummy, i.e., for the purpose of
   * collecting information before the real write is commenced.
   */
  inline Standard_Boolean       IsDummyWrite() const
  { return myOutput == 0L; }

 private:
  // ---------- PRIVATE METHODS (PROHIBITED) ----------
  VrmlData_Scene (const VrmlData_Scene&);
  VrmlData_Scene& operator = (const VrmlData_Scene&);

 protected:
  /**
   * Read whatever line from the input checking the istream flags.
   */ 
  Standard_EXPORT static VrmlData_ErrorStatus
                                readLine    (VrmlData_InBuffer&     theBuffer);

  /**
   * Read and verify the VRML header (the 1st line of the file)
   */ 
  Standard_EXPORT static VrmlData_ErrorStatus
                                readHeader  (VrmlData_InBuffer&     theBuffer);

  /**
   * Create the node.
   * @param theBuffer
   *   Input buffer from where the node is created
   * @param theNode
   *   Output parameter, contains the created node on exit
   * @param Type
   *   Node type to be checked. If it is NULL no type checking is done.
   *   Otherwise the created node is matched and an error is returned if
   *   no match detected.
   */
  Standard_EXPORT VrmlData_ErrorStatus 
                                createNode  (VrmlData_InBuffer&     theBuffer,
                                             Handle(VrmlData_Node)& theNode,
                                             const Handle(Standard_Type)& Type);

  /**
   * Create a single Shape object from all geometric nodes in the list.
   */
  Standard_EXPORT static void   createShape (TopoDS_Shape&          outShape,
                                             const VrmlData_ListOfNode&,
                                             VrmlData_DataMapOfShapeAppearance*);


 private:
  // ---------- PRIVATE FIELDS ----------
  Standard_Real                                 myLinearScale;
  VrmlData_ListOfNode                           myLstNodes; ///! top-level nodes
  VrmlData_ListOfNode                           myAllNodes; ///! all nodes
  VrmlData_ErrorStatus                          myStatus;
  Handle_NCollection_IncAllocator               myAllocator;
  Handle_VrmlData_WorldInfo                     myWorldInfo;
  VrmlData_MapOfNode                            myNamedNodes;

  // read from stream
  NCollection_List<TCollection_ExtendedString>  myVrmlDir;
  Standard_Mutex                                myMutex;
  Standard_Integer                              myLineError;///! #0 if error

  // write to stream
  Standard_OStream                              * myOutput;
  Standard_Integer                              myIndent;
  Standard_Integer                              myCurrentIndent;
  /**
   * This map is used to avoid multiple storage of the same named node: each
   * named node is added here when it is written the first time.
   */
  VrmlData_MapOfNode                            myNamedNodesOut;
  /**
   * This map allows to resolve multiple reference to any unnamed node. It
   * is used during the dummy write (myOutput == 0L). When a node is processed
   * the first time it is added to this map, the second time it is automatically
   * assigned a name.
   */
  NCollection_Map<Standard_Address>             myUnnamedNodesOut;
  Standard_Integer                              myAutoNameCounter;
  friend class VrmlData_Group;
  friend class VrmlData_Node;
};

#endif