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> |
30 | |
31 | struct VrmlData_InBuffer; |
7fd59977 |
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 | */ |
857ffd5e |
185 | Standard_EXPORT const Handle(VrmlData_WorldInfo)& |
7fd59977 |
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, |
857ffd5e |
317 | const Handle(VrmlData_Node)&) const; |
7fd59977 |
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; |
857ffd5e |
374 | Handle(NCollection_IncAllocator) myAllocator; |
375 | Handle(VrmlData_WorldInfo) myWorldInfo; |
7fd59977 |
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 |