0030402: Data Exchange - exported VRML file has broken location information
[occt.git] / src / VrmlData / VrmlData_Scene.hxx
CommitLineData
b311480e 1// Created on: 2006-10-08
2// Created by: Alexander GRIGORIEV
973c2be1 3// Copyright (c) 2006-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 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>
ddf2fe8e 28#include <NCollection_IncAllocator.hxx>
7fd59977 29#include <Standard_Mutex.hxx>
9533a866 30#include <VrmlData_DataMapOfShapeAppearance.hxx>
7fd59977 31
9fd2d2c3 32// resolve name collisions with X11 headers
33#ifdef Status
34 #undef Status
35#endif
36
7fd59977 37struct VrmlData_InBuffer;
7fd59977 38
39/**
40 * Block of comments describing class VrmlData_Scene
41 */
42
43class 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 */
857ffd5e 190 Standard_EXPORT const Handle(VrmlData_WorldInfo)&
7fd59977 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,
857ffd5e 322 const Handle(VrmlData_Node)&) const;
7fd59977 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;
857ffd5e 379 Handle(NCollection_IncAllocator) myAllocator;
380 Handle(VrmlData_WorldInfo) myWorldInfo;
7fd59977 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