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