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 |
37 | struct VrmlData_InBuffer; |
7fd59977 |
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 | */ |
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 |